步驟如下
1.這個(gè)題目是迄今遇到的最坑題目版姑。話不多說,上題目宇姚。鏈接:http://pan.baidu.com/s/1hr5CtpU 密碼:r9wi
2.首先運(yùn)行題目夭拌,如下圖所示蒜绽,跟平常的題目沒什么兩樣躲雅。隨便輸入字符串慰于,發(fā)現(xiàn)彈出報(bào)錯(cuò)信息。咋一看,有關(guān)鍵字符串璃吧,好咧楣导,這題不難,肯定可以找到關(guān)鍵挑戰(zhàn)畜挨,然后問題就簡單了。(太天真噩凹。巴元。。)
3 打開OD載入程序驮宴,搜索字符串逮刨,發(fā)現(xiàn)關(guān)鍵字符串,很高興堵泽。
在字符串上方發(fā)現(xiàn)兩個(gè)跳轉(zhuǎn)都跳到失敗處修己,猜想應(yīng)該是二次驗(yàn)證,一個(gè)一個(gè)分析迎罗,分析第一個(gè)call crackme.00402e40 睬愤,發(fā)現(xiàn)是對輸入的字符串進(jìn)行一系列處理,然后得到一個(gè)數(shù)值纹安,在下面語句中發(fā)現(xiàn)是和0x92381221 進(jìn)行比較尤辱。不等則跳轉(zhuǎn)向失敗,打開IDA厢岂,分析關(guān)鍵call ,發(fā)現(xiàn)0x92381221代表的十進(jìn)制數(shù)2453148193剛好符合條件光督,心中頓感,我實(shí)在是太聰明了塔粒。
繼續(xù)往下看下一個(gè)跳轉(zhuǎn)结借,call crackme.00401DF0,發(fā)現(xiàn)是兩個(gè)字符串比較,猜想是我們前面的字符串進(jìn)行再次的運(yùn)算得到一堆字符串然后比較卒茬,然后分析可得處理函數(shù)為call crackme.00401990,分析關(guān)鍵call 發(fā)現(xiàn)是把輸入進(jìn)行MD5運(yùn)算得到的一堆字符串船老。沃日。扬虚。努隙。這控制不了啊。辜昵。荸镊。然后感覺不太對,于是我嘗試暴力把跳轉(zhuǎn)改一下,看會出現(xiàn)什么情況躬存。發(fā)現(xiàn)既彈出了成功张惹,又彈出來失敗,感覺不對岭洲。
4.想著對消息框下個(gè)斷點(diǎn)宛逗,F(xiàn)9運(yùn)行,點(diǎn)擊工具欄的W發(fā)現(xiàn)盾剩,竟然出現(xiàn)了兩個(gè)輸入Input,覺得肯定玄機(jī)在此雷激,覺得其中一個(gè)按鈕一定是被隱藏了,在command 位置下斷點(diǎn)告私,輸入 bp ShowWindow,尋找ShowWindow函數(shù)屎暇,重新運(yùn)行程序,發(fā)現(xiàn)運(yùn)行到了用戶層驻粟,alt+f9運(yùn)行出來根悼,發(fā)現(xiàn)前面就是ShowWindow 窗口在此下斷點(diǎn),刪除剛剛下的user32里的斷點(diǎn)蜀撑,發(fā)現(xiàn)參數(shù)信息為0時(shí)挤巡,為隱藏,為1時(shí)為顯現(xiàn)酷麦,于是更改參數(shù)值如下圖所示:
復(fù)制到可執(zhí)行文件矿卑,保存文件。再次運(yùn)行發(fā)現(xiàn)果然出現(xiàn)了兩個(gè)輸入按鈕贴铜。
5.修改后的程序重新加載進(jìn)OD粪摘,此時(shí)發(fā)現(xiàn)感覺沒什么思路,對獲取輸入字符串的函數(shù)進(jìn)行下斷點(diǎn)绍坝,在IDA中發(fā)現(xiàn)有GetWindowText函數(shù)徘意,雙加該函數(shù),ctrl+x 獲取其引用的位置轩褐,記下地址椎咧,在OD中ctrl+g 查找,找到該函數(shù)位置下斷點(diǎn)把介,重新運(yùn)行程序勤讽,輸入字符串,點(diǎn)擊左邊的Input,程序運(yùn)行到斷點(diǎn)處拗踢,F(xiàn)8單步運(yùn)行脚牍,發(fā)現(xiàn)下面有一個(gè)call ,F7進(jìn)去看看,發(fā)現(xiàn)是獲取字符串的長度巢墅,感覺好多Crackme都會對字符串的長度進(jìn)行檢查诸狭,于是對存字符串的位置下一個(gè)內(nèi)存訪問斷點(diǎn)券膀,看看是否有什么意外的驚喜,F(xiàn)9運(yùn)行程序驯遇,發(fā)現(xiàn)程序到了這芹彬,IDA查看此位置的反編譯結(jié)果,發(fā)現(xiàn)果然是對字符串的長度進(jìn)行了檢查叉庐,0x27u說明字符串長度為39,79舒帮,79,67,84,70,123,125剛好是題目所說的格式00CTF{},繼續(xù)運(yùn)行尋找返回的地方。最后回到401f96的位置陡叠,此處果然為一個(gè)調(diào)用玩郊,檢查長度和格式。如果不符合返回值為0匾竿,跳到失敗的位置瓦宜。符合的話返回值為1,繼續(xù)往下進(jìn)行岭妖。
6 繼續(xù)往下分析,分析各個(gè)call 的作用反璃,發(fā)現(xiàn)call 1.00401860 位置的call 有很大的嫌疑昵慌,里面有各種循環(huán),猜測為算法處理過程淮蜈,IDA定位此處位置分析基本確定此位置斋攀,繼續(xù)向下運(yùn)行,查找字符串比較的過程梧田,發(fā)現(xiàn)地址為401fca的調(diào)用淳蔼,是彈出錯(cuò)錯(cuò)誤的位置,此處下斷點(diǎn)裁眯,重新運(yùn)行程序到這個(gè)位置鹉梨,F(xiàn)7進(jìn)去分析,同時(shí)打開IDA穿稳,定位此函數(shù)存皂,輔助分析,果然發(fā)現(xiàn)了兩個(gè)MessageBOXA函數(shù)逢艘。分析不同的彈框結(jié)果發(fā)現(xiàn)前面是一個(gè)字符串比較函數(shù)旦袋,IDA按table鍵定位此函數(shù)的位置。
進(jìn)去發(fā)現(xiàn)是一個(gè)一個(gè)進(jìn)行字符的比較它改,比較字符串b5h760h64R867618bBwB48BrW92H4w5r 錯(cuò)誤的話最后函數(shù)返回值為1疤孕,彈出錯(cuò)誤對話框。
7.現(xiàn)在的問題就只剩下解決算法出路的問題了央拖。IDA反編譯出的代碼如下
分析可知其對數(shù)字不做變換祭阀,大寫字母減去65然后再進(jìn)行關(guān)鍵操作鹉戚,
V9=(V6+V5V7)%26+((V6+V5V7)%26<0?0X1a:0)
v6在調(diào)試的時(shí)候會出現(xiàn)32-2-2=28,v5情況有點(diǎn)復(fù)雜柬讨,可能是3或者5崩瓤,待會再說為什么,小寫字母減去97然后進(jìn)行關(guān)鍵操作踩官,這樣就進(jìn)行了字符串的變換却桶。
關(guān)于v6的問題:該數(shù)值最早是函數(shù)0041458e 的返回值,返回值為-1的時(shí)候就賦值為3蔗牡,否則為原數(shù)颖系。我用3進(jìn)行測試的時(shí)候發(fā)現(xiàn)是錯(cuò)誤的,那這個(gè)函數(shù)0041458e 就很有問題辩越。
在此處下斷點(diǎn)嘁扼,F(xiàn)7進(jìn)去發(fā)現(xiàn)是再次調(diào)用了函數(shù)41459c,繼續(xù)跟進(jìn)去同時(shí)觀察IDA的結(jié)果,
發(fā)現(xiàn)其實(shí)就是判斷_mbschr((const unsigned __int8 *)(a3 + *(_DWORD *)this),a2))的結(jié)果黔攒,點(diǎn)擊該函數(shù)進(jìn)去趁啸,OD定位該位置,單步運(yùn)行會發(fā)現(xiàn)督惰,其實(shí)是檢查輸入字符串的第六位是否為0不傅,如果為0則返回 值為0的地址,后面是字符串的地址減去該地址為5赏胚,即為v6,否則的話返回值為-1访娶,在后面的判斷中賦值為3.此為v6的具體賦值過程。