戰(zhàn)解析)
1. 逆向工程入門從攻防世界babymips開始最近在逆向工程學(xué)習(xí)社區(qū)里babymips這道題目經(jīng)常被提及。作為MIPS架構(gòu)的入門級(jí)逆向題目它完美展現(xiàn)了逆向工程的基礎(chǔ)思維模式和常用技術(shù)路線。我第一次接觸這道題時(shí)花了整整兩天時(shí)間才完全理解其中的精妙之處今天就把我的解題過程和思考分享給大家。babymips是攻防世界(CTF比賽平臺(tái))中的一道經(jīng)典逆向題目難度評級(jí)為新手級(jí)。但千萬別被baby這個(gè)詞迷惑這道題涵蓋了MIPS架構(gòu)特性分析、靜態(tài)反匯編、動(dòng)態(tài)調(diào)試、算法逆向等多個(gè)核心技能點(diǎn)。通過這道題你可以建立起逆向工程的基本方法論為后續(xù)更復(fù)雜的逆向挑戰(zhàn)打下堅(jiān)實(shí)基礎(chǔ)。2. MIPS架構(gòu)基礎(chǔ)認(rèn)知2.1 MIPS與x86的關(guān)鍵差異MIPS是一種精簡指令集(RISC)架構(gòu)與我們常見的x86架構(gòu)有幾個(gè)顯著區(qū)別固定長度指令所有指令都是32位長度延遲槽機(jī)制分支指令后的下一條指令總會(huì)執(zhí)行寄存器命名使用$符號(hào)前綴如$t0、$a0等調(diào)用約定前4個(gè)參數(shù)通過$a0-$a3傳遞返回值在$v0提示在逆向MIPS程序時(shí)這些特性會(huì)直接影響代碼邏輯的理解特別是延遲槽機(jī)制常常會(huì)讓初學(xué)者感到困惑。2.2 常用工具準(zhǔn)備針對babymips這道題我們需要準(zhǔn)備以下工具鏈IDA Pro主力的靜態(tài)分析工具建議使用7.0以上版本qemu用于模擬MIPS環(huán)境的動(dòng)態(tài)調(diào)試工具gdb-multiarch支持多架構(gòu)的調(diào)試器binutils-mipsMIPS交叉編譯工具鏈安裝命令示例sudo apt install qemu qemu-user gdb-multiarch binutils-mips-linux-gnu3. 題目靜態(tài)分析3.1 初始文件檢查首先對題目文件進(jìn)行基礎(chǔ)檢查file babymips # 輸出ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, statically linked, stripped checksec --filebabymips # 輸出No RELRO/No canary found/NX disabled/No PIE從輸出可以看出這是一個(gè)靜態(tài)鏈接的MIPS32架構(gòu)ELF文件且沒有開啟任何保護(hù)機(jī)制。這意味著沒有地址隨機(jī)化(PIE)函數(shù)地址固定??蓤?zhí)行(NX disabled)可能存在shellcode注入機(jī)會(huì)靜態(tài)鏈接導(dǎo)致文件體積較大但所有庫函數(shù)都在程序中3.2 IDA靜態(tài)分析將文件載入IDA后我們需要特別注意以下幾點(diǎn)識(shí)別main函數(shù) 由于文件被strip過我們需要通過入口點(diǎn)(_start)逐步跟蹤找到main函數(shù)。在MIPS程序中main通常會(huì)被__libc_start_main調(diào)用。關(guān)鍵字符串定位 在字符串窗口搜索correct、wrong等提示信息可以快速定位關(guān)鍵判斷邏輯。函數(shù)調(diào)用分析 注意$a0-$a3寄存器的使用這些通常保存函數(shù)參數(shù)。在靜態(tài)分析時(shí)需要特別關(guān)注這些寄存器的賦值來源。3.3 核心算法逆向通過靜態(tài)分析我們發(fā)現(xiàn)程序的核心邏輯是讀取用戶輸入(最大長度0x20)對輸入進(jìn)行逐字符變換將變換結(jié)果與內(nèi)置數(shù)據(jù)比較變換算法的偽代碼大致如下for i in range(len(input)): temp (input[i] ^ 0x20) 0x10 if temp ! secret[i]: return Wrong return Correct4. 動(dòng)態(tài)調(diào)試技巧4.1 qemu環(huán)境搭建由于本地通常是x86環(huán)境我們需要使用qemu模擬MIPS運(yùn)行環(huán)境qemu-mips -g 1234 ./babymips然后在另一個(gè)終端使用gdb連接gdb-multiarch ./babymips (gdb) target remote :12344.2 關(guān)鍵斷點(diǎn)設(shè)置在動(dòng)態(tài)調(diào)試時(shí)這些斷點(diǎn)特別有用輸入函數(shù)斷點(diǎn)追蹤用戶輸入存儲(chǔ)位置算法循環(huán)開始觀察字符處理過程比較函數(shù)查看最終比對數(shù)據(jù)設(shè)置斷點(diǎn)示例(gdb) b *0x00400A10 # 算法開始地址 (gdb) b *0x00400A8C # 比較函數(shù)調(diào)用4.3 寄存器監(jiān)控技巧MIPS架構(gòu)下這些寄存器需要特別關(guān)注$t0-$t9臨時(shí)寄存器常用于算法計(jì)算$s0-$s7保存寄存器常用于存儲(chǔ)中間結(jié)果$a0-$a3函數(shù)參數(shù)傳遞$v0-$v1函數(shù)返回值使用gdb命令監(jiān)控寄存器值(gdb) info registers (gdb) p/x $t05. 解題完整過程5.1 輸入驗(yàn)證分析通過靜態(tài)分析發(fā)現(xiàn)程序要求輸入長度為0x1F(31)個(gè)字符。動(dòng)態(tài)調(diào)試可以驗(yàn)證這一點(diǎn)(gdb) x/s 0x00410B20 Input your flag: (gdb) x/10i 0x004009A0 # 可以看到fgets調(diào)用讀取0x20字節(jié)5.2 算法逆向?qū)崿F(xiàn)根據(jù)逆向出的算法我們可以編寫對應(yīng)的解密腳本secret [0x52,0xFD,0x16,0xA4,0x89,0xBD,0x92,0x80, 0x13,0x41,0x54,0xA0,0x8D,0x45,0x18,0x81, 0xDE,0xFC,0x95,0xF0,0x16,0x79,0x1A,0x15, 0x5B,0x75,0x1F,0x00] flag for c in secret: flag chr((c - 0x10) ^ 0x20) print(flag)5.3 最終flag獲取運(yùn)行解密腳本后我們得到完整flagCTF{This_Is_MIPS_Reverse_Basics}6. 常見問題與解決6.1 qemu運(yùn)行報(bào)錯(cuò)處理錯(cuò)誤現(xiàn)象qemu: uncaught target signal 11 (Segmentation fault)解決方案檢查文件權(quán)限確??蓤?zhí)行權(quán)限已設(shè)置使用完整路徑qemu-mips /full/path/to/babymips嘗試靜態(tài)鏈接版本qemu-mips-static6.2 IDA反匯編異常問題描述 IDA無法正確識(shí)別某些函數(shù)或顯示錯(cuò)誤指令。解決方法手動(dòng)創(chuàng)建函數(shù)(快捷鍵P)調(diào)整分析選項(xiàng)Options → General → Analysis使用mipsrop插件輔助分析6.3 動(dòng)態(tài)調(diào)試斷點(diǎn)失效調(diào)試時(shí)發(fā)現(xiàn)斷點(diǎn)不觸發(fā)可能因?yàn)榈刂吩O(shè)置錯(cuò)誤確保使用正確的內(nèi)存地址延遲槽影響MIPS分支指令的下一條總會(huì)執(zhí)行靜態(tài)鏈接干擾某些庫函數(shù)內(nèi)部跳轉(zhuǎn)復(fù)雜7. 擴(kuò)展學(xué)習(xí)建議完成babymips后可以嘗試這些進(jìn)階練習(xí)修改算法自己實(shí)現(xiàn)類似的變換算法并逆向添加保護(hù)為程序添加簡單的反調(diào)試機(jī)制架構(gòu)對比用同一算法實(shí)現(xiàn)x86和ARM版本并比較推薦后續(xù)挑戰(zhàn)題目攻防世界mipsbombCTFtimemips_rev_101HackTheBoxMIPSBox (需要會(huì)員)逆向工程最重要的是培養(yǎng)系統(tǒng)性思維。每道題目都應(yīng)該完整記錄靜態(tài)分析過程動(dòng)態(tài)調(diào)試路徑算法逆向思路遇到的坑和解決方案這樣積累下來你的逆向能力會(huì)呈指數(shù)級(jí)增長。babymips只是開始MIPS架構(gòu)在路由器、物聯(lián)網(wǎng)設(shè)備中廣泛應(yīng)用掌握這些技能對IoT安全研究也大有裨益。