Hack The Box(HTB) - CTF Try Out : Don't Panic! Walkthrough
Hack The Box(HTB) - CTF Try Out : Don't Panic! Walkthrough
又是一題僅有檔案的 CTF
檔案下載後一樣僅有一個檔案
一樣是個 ELF 檔案,這一次 strings 沒有任何 HTB 字眼
執行看看,輸入 yes or no 都讓他恐慌
參考這一篇 : https://medium.com/@ranachouchen4/hackthebox-dont-panic-reverse-engineering-writeup-897bcc6cd809
編寫一個 python code 如下
import pexpect
import re
import string
import random
# Initial random flag (HTB format + 27 random letters)
flag = "HTB{111111111111111111111111111"
ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
# Regex to extract character from disassembled cmp line
cmp_re = re.compile(r"cmp\s+\$?0x([0-9a-fA-F]+).*%dil", re.IGNORECASE)
for i in range(31):
gdb = pexpect.spawn("gdb -q ./dontpanic", encoding="utf-8", timeout=3)
gdb.expect_exact("(gdb)")
gdb.sendline("b src::check_flag")
gdb.expect_exact("(gdb)")
gdb.sendline("run")
gdb.expect(r"Have you got a message for me\?")
gdb.sendline(flag) # Send current flag
gdb.expect_exact("Breakpoint 1") # Wait until we hit the breakpoint
gdb.expect_exact("(gdb)")
steps = 63 + i * 12
for j in range(steps):
gdb.sendline("si")
gdb.expect("(gdb)")
gdb.sendline("disas")
gdb.expect_exact("(gdb)")
output = gdb.before
output = ansi_escape.sub('', output)
match = cmp_re.search(output)
if match:
byte = int(match.group(1), 16)
flag_list = list(flag)
flag_list[i] = chr(byte)
flag = "".join(flag_list)
print(f"Found char at position {i}: {flag[i]}")
else:
print(f"Failed to extract char at position {i}")
gdb.close()
print("Recovered flag:", "".join(flag))
執行後如下獲取 flag : HTB{d0nt_p4n1c_c4tch_the_3rror}
原理說明 :
想像這程式像一台自動驗證輸入的機器,它會一個字一個字地比對你輸入的 flag 對不對。只要有一個字不對,它就會「驚慌失措」地說:
😱 You made me panic!
我們的目標是:
找出正確的 flag,每個位置該放什麼字元。
Rust 程式做了什麼?
這支 Rust 寫的 binary,在執行時會把你輸入的整段文字(像是 HTB{aaaaaaa})逐字送去 check_flag() 函數裡。
然後 check_flag() 裡會用組合語言的方式做類似這樣的事:
一旦有錯,就會 panic。
Python 做了什麼?
-
每次送一組錯的 flag(一開始用全是
1的HTB{111...) -
每次 在 GDB 裡停在
check_flag()的某一步驟,然後用disas拿到 disassembly 組合語言 -
用正規表達式
cmp.*%dil找出比較的是哪個字元 -
把它轉回字元,寫進對應的位置
-
重複 31 次,直到整段 flag 都被拼出來
每次就是這樣:
-
程式說:「你的第 6 個字應該是
p呀」 -
你說:「好,我改成
p」 -
下一輪再來看第 7 個是什麼
這樣來回問、改、問、改,很快就拿到整段正確 flag!
🧩 小總結:這叫「逐字元爆破(byte-by-byte bruteforce)」
-
藉由 GDB 停在
check_flag()的某一行 -
看到機器用
cmp檢查哪個字元 -
自動把它換成正確的
-
重複直到完成
留言
張貼留言