想必大家在做 CTF 時都遇過那種題目:把使用者輸入直接丟進 printf
、fprintf
、syslog
或類似的 log 函式,結果一輸入特殊格式字串程式就開始把記憶體內容印出來,或甚至被寫到記憶體裡——這類題型就是 Format String 漏洞,在 Binary Exploitation / pwn 裡非常經典也很常見。
printf
類函式的 format 參數,而不是把使用者字串當作 format 的參數。printf(user_input);
與 printf("%s", user_input);
差很大:前者會把 user_input
當作格式化語法來解析(例如 %x
, %s
, %n
),後者只把它當單純字串印出。%p
/ %x
/ %s
快速把 stack / heap / GOT pointer 打出來,方便算出 libc base 或 binary base。%n
(或大小寫變體 %hhn
、%hn
)把「目前已輸出的字元數」寫入某 address,能被用來覆寫 GOT entry、function pointer,達到流程控制。%x
/ %p
:把 stack 上的資料(按位元/指標)以 hex 顯示 → 用來 leak stack 值。%s
:把 stack 上的值當 pointer,讀那個位址的字串(因此若 stack 上儲存的是 pointer,就能讀字符串或 data 段)。%n
:把到目前為止 printf
已經 output 的字元數寫入對應的參數所指定的位址(任意寫 的關鍵)。%hn
/ %hhn
:分別把字元數的低 2 bytes / 1 byte 寫入位址(方便做 byte-by-byte 寫入以避開字數限制)。%7$x
、%10$s
→ 指定從第幾個 stack 參數讀,能精準定位。先看這題的source code可以發現它會直接把我們的輸入放入printf做輸出,這樣將會有format string的漏洞
我們可以利用%p
來獲得他stack 上的資料
記憶體通常以8 bytes為單位儲存資料,我們先將多餘的東西刪掉後,然後swap endianness後,將他從Hex轉回文字就能得到flagㄌ~
以上就是今天的內容啦
想看更多,記得明天再來喔~