Hack The Box(HTB) - CTF Try Out : Dynamic Paths Walkthrough

 Hack The Box(HTB) - CTF Try Out : Dynamic Paths Walkthrough


靶機名稱 : Dynamic Paths

難度 : 簡單



瀏覽器開啟來看看,但無法輸入任意值



題目看來就是 [ 在一張只能往右或往下走的方格地圖,從左上走到右下,讓沿途數字總和最小 ]

改用 nc 測試,確認可以輸入值

從輸入結果來看要解題 100 次(因為一開始是 1/100)才能拿到 fl



再次開啟一題如下,解完是 33 輸入後真的進入了第二題 2/100



以上面這一題說明他的邏輯如下,第一題是

Test 1/100

4 4

7 6 4 4 6 8 3 3 8 7 7 7 2 7 2 4


44 表示每一行有 4 個數字,共有 4 列,所以可以改成顯示如下比較好理解

7   6   4   4 

6   8   3   3

8   7   7   7

2   7   2   4


然後我們要從左上走到右下,但加總的數字要最小

走法就是如下紅字 7 -> 6 -> 4 -> 3 -> 7 -> 2 -> 4

7   6   4   4 

6   8   3   3

8   7   7   7

2   7   2   4


所以這一題的答案就是 7 + 6 + 4 + 3 + 7 + 2 + 4 = 33

用一樣的邏輯解完 100 題就會拿到 flag 了~~~~~~~光用想的就好累

請 AI 依據該邏輯寫了一套 python 來執行就過了,程式碼如下

將內容存成 "dynamic_paths_socket_autosend.py"

=====================================================================

#!/usr/bin/env python3

# dynamic_paths_socket_autosend.py

import socket, re, sys


DIM_RE   = re.compile(r'^\s*(\d+)\s+(\d+)\s*$')

INT_RE   = re.compile(r'-?\d+')

FLAG_RE  = re.compile(rb'HTB\{[^}]+\}')

EXQ_RE   = re.compile(r'Example Question', re.I)

EXRESP_RE= re.compile(r'Example Response', re.I)


def min_path_sum(rows, cols, vals):

    dp = [0] * cols

    it = iter(vals)

    for r in range(rows):

        for c in range(cols):

            v = next(it)

            if r == 0 and c == 0:

                dp[c] = v

            elif r == 0:

                dp[c] = dp[c-1] + v

            elif c == 0:

                dp[c] = dp[c] + v

            else:

                dp[c] = min(dp[c], dp[c-1]) + v

    return dp[-1]


def solve(host, port, verbose=True):

    s = socket.create_connection((host, int(port)), timeout=30)

    s.settimeout(120)

    f = s.makefile('rwb', buffering=0)


    # 狀態:忽略 Example;答題就「湊滿後立刻送」

    in_example = False

    i = j = None

    need = 0

    buf  = []

    solved = 0


    while True:

        line = f.readline()

        if not line:

            break


        text = line.decode('utf-8', 'ignore').rstrip('\n')

        if verbose:

            print(text)


        # Flag?

        mflag = FLAG_RE.search(line)

        if mflag:

            print("\nFlag:", mflag.group(0).decode())

            break


        # Example 區段:看到 Example Question 進入、直到 Example Response 出現才離開

        if EXQ_RE.search(text):

            in_example = True

            continue

        if in_example:

            if EXRESP_RE.search(text):

                in_example = False

            continue  # Example 內所有內容都略過


        # 解析正式題目

        # 1) 尺寸行

        if i is None:

            m = DIM_RE.fullmatch(text.strip())

            if m:

                i, j = map(int, m.groups())

                need = i * j

                buf = []

            continue


        # 2) 收集數字(可跨多行)

        nums = list(map(int, INT_RE.findall(text)))

        if not nums:

            continue

        take = min(need - len(buf), len(nums))

        buf.extend(nums[:take])


        # 3) 湊滿即算、立刻送出

        if len(buf) == need:

            ans = min_path_sum(i, j, buf)

            if verbose:

                print(f"-> Send Answer #{solved+1}: {ans}")

            f.write((str(ans) + '\n').encode())

            f.flush()


            # 準備下一回合

            solved += 1

            i = j = None

            need = 0

            buf = []


    try:

        f.close()

    except:

        pass

    s.close()


if __name__ == "__main__":

    host = "94.237.57.211"

    port = 44158

    if len(sys.argv) == 3:

        host, port = sys.argv[1], int(sys.argv[2])

    solve(host, port, verbose=True)

=====================================================================


存檔後直接執行 python3 dynamic_paths_socket_autosend.py 94.237.57.211 44158

拿到 flag : HTB{b3h3M07H_5h0uld_H4v3_57ud13D_dYM4m1C_pr09r4mm1n9_70_C47ch_y0u_646e6b5c0d51f6bc19a0841c43479d36}



這題目後面真的誇張,第 100 題可以看到是 100/100 61 63
每一列有 61 個數字,總共有 63 列,這個不是人可以解出來的
難怪題目叫做 Coding,就是要靠一段 Code 去解題



這年代已經不用會寫 Code,只要會用 AI 即可

那一段 Python 也是透過跟 AI 互相問答,嘗試錯誤與輸出後得到的結果






留言

這個網誌中的熱門文章

Challenge 0 - Secura(2)

Challenge 0 - Secura(1)

Challenge 8 - Poseidon(1)