###### tags: `NCTU` `CS` `Course` `SecureProgramming` HW 0x02 Write Up == yysung ## [Lab 2-1] Add flag: flag{y0u_added_thr33_nums!} 使用反編譯程式後,可以發現該程式會讀取三個數字,並將其加總 將加總的數字當作參數呼叫 gen 函式得到一個字串 而且只有在加總為 1337 時,才會印出 flag{字串} 輸入 `0 0 1337` 後就可以得到 flag ## [Lab 2-2] Guess flag: flag{aaA_tOucH_0f_luccK_47ca4e} 使用反編譯程式後,可以發現該程式會先隨機產生一個數字 接下來讀入數字並與隨機數字比較,如果不同則回傳 Hi 或 Lo,只能猜測 22 次 猜測成功後就可以輸出 flag 將比較數字的機器碼 `0x400b93~0x400b94` 都 patch 成 `nop`,就不會比較數字,而且會直接跳到印 flag 的程式碼,就可以得到 flag ## [Lab 2-3] Forest flag: flag{you_could_see_the_forest_for_the_trees_ckyljfxyfmsw} 該程式會從 argv 讀入兩個字串,第二個字串是題目給定的字串。只要第一個字串是 flag 就會輸出 `You did it! Put the input in the flag{}.` 使用反編譯程式後,可以發現該程式會先用內建於程式裡的字串生出一個樹狀結構,並照著 argv 的第二個字串走訪樹 + D 代表的是將該節點的值和argv 的第一個字串比對並回到樹根 + L 代表的是往當前節點的左節點走 + R 代表的是往當前節點的右節點走 只要用一樣的方法生出一個樹狀結構,並用題目給定的字串走訪,在 D 時印出該節點的值,就可以得到 flag `lab2-3.cpp` 即為上述程式 ## [HW 0x02] simplebox flag: flag{wow0oW_Y0U_brEak_Th3_$IMP1e8oX} 該程式會從 argv 讀入題目給定的檔案的 filename ,接下來會讀入 36 個字元,隨便輸入後回傳 `Try hard!` 先用 `strings` 指令發現該程式有用 upx 加殼,所以先脱殼 使用 `strings` 後發現無法找到 `Try hard!` 字串 使用反編譯程式後,發現該程式是靜態編譯而且 symbol 有被拔掉,無法直接看出 main 函式的位置 尋找後發現 main 函式在 `0x401B1C` 的位置,接下來會將 filename fopen 並以 fread 讀入至 `0x4AFB60`,計算 `0x4AFB60` 字串的長度,並將該字串和長度作為 `0x401E9E` 函式的參數 題目給定的檔案內容最後有一個=,所以猜測是 base64 編碼過的字串,使用 `gdb` 執行後發現 `0x401E9E` 函式會將字串做 base64 解碼 被 base64 解碼的字串會被當作 `0x4016FD` 函式的參數,回傳值再被當作 `0x401978` 函式的參數 `0x4016FD` 函式是一個 switch case,有 8 個 cases,每個 cases 分別是把 1~8 以 2 bytes 大小放入 `0x4A7340` 並且每次跳 4 bytes,使用 gdb 看 `0x4A7340` 後會得到 ``` 0x4a7340: 0x0000000100000003 0x000b000700000006 0x4a7350: 0x0000000300000001 0x0000000300000001 0x4a7360: 0x0000000200000002 0x0003000800000004 0x4a7370: 0x0000000100000001 0x0000000200150007 ``` 只看 `0x4016FD` 操作的記憶體就是 ``` 3167131322481172 ``` 和題目給定的檔案 base64 解碼後的字串比較 ``` mBOFBmBmaabxBBFa ``` 可以看出以下對應 ``` B:1, a:2, m:3, b:4, O:6, F:7, x:8 ``` 剩下的 o 對應的是 5 `0x401978` 將上面做的轉換作為輸入,而且也是一個有 8 個 cases 的 switch case + 1 將 [rbp+var_8] 加 1 + 2 將 [rbp+var_8] 減 1 + 3 將 rbp+2*[rbp+var_8]+var_20010 指到的記憶體值加 1 + 4 將 rbp+2*[rbp+var_8]+var_20010 指到的記憶體值減 1 + 5 將 rbp+2*[rbp+var_8]+var_20010 指到的記憶體值當作參數呼叫 `0x40A200` + 6 將 `0x40BCD0` 函式的回傳值寫入 rbp+2*[rbp+var_8]+var_20010 指到的記憶體位址 + 7 比對 [rbp+var_8] 是否為 0,是則跳躍 + 8 比對 [rbp+var_8] 是否為 0,否則跳躍 `0x40A200` 為 write 一個字元, `0x40BCD0` 為 read 一個字元 以上的行為和 brainfuck 語言極為相似,所以將base64 解碼後的字串用以上規則轉換後用 brainfuck 直譯器執行,發現程式會先讀入一個字元,再建構出比較的字元,也就是 flag,再進行比較,全部字元 完全相同的會就會印 `You got the flag!` 所以就將建構比較字元的程式碼複製出來執行,就可以得到 flag `sol.b` 即為可以印出 flag 的 brainfuck 程式碼
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up