看雪.騰訊TSRC 2017 CTF 秋季賽 第三題點評及解析思路

Editor發表於2017-10-30

看雪CTF 官網看雪CTF

導語


週一快樂~

經過一個週末的奮戰,第三題攻破人數破百,第三題作者上升至第二位。

看雪.騰訊TSRC 2017 CTF 秋季賽 第三題點評及解析思路

第三題過後,攻擊方的排名如下:ccfer依然居於首位,風間仁、愛琴海緊隨其後。風間仁曾是上一屆看雪CTF 的冠軍,不知此次能夠繼續捍衛自己的冠軍寶座呢?讓我們拭目以待!

看雪.騰訊TSRC 2017 CTF 秋季賽 第三題點評及解析思路

革命尚未成功,同志仍需努力!

接下來讓我們一起來看看關於第三題的點評、出題思路和解析。

看雪評委 netwind 點評

作者用常見的反除錯手段對程式進行了一定的保護,然後通過一個迷宮演算法來實現程式的驗證流程。本來是一個很有趣的題目,但是作者的演算法有多處疏漏導致了破解方法也是五花八門。

第三題作者簡介

littlewisp,從同事那裡接觸看雪論壇以來,對破解產生了濃厚的興趣,陸續接觸了加殼脫殼,驅動,rootkit等。後來的研發轉向安全方向,長期從事外殼,虛擬機器等軟體保護產品的開發,在國內沒有混淆的虛擬機器保護的加密方案簡直就是裸奔。

第三題設計思路

簡單迷宮:從頭走到尾即可,q上z下p左l右將路徑字串採用morse碼編碼,將morse碼採用base64編碼兩次,得到第一部分結果;將morse碼採用sm3演算法Hash,得到的部分作為第二部分結果。

破解思路:過掉一些簡單的反除錯、單步跟蹤,找到迷宮的資料,很容易找到走迷宮字串,在根據對輸入序列號的處理演算法得到輸入字串。

下面選取攻擊者ccfer的解析過程

因為exe有重定位表,為了方便讀者閱讀分析程式碼,先用pe編輯工具把exe的重定位表地址rv清0

程式中有很多檢測,但檢測到異常後,都會呼叫一個共同入口0042E086來處理,因此只要在0042E086處改一個位元組ret直接返回就可以了。

ida開啟exe,從GetDlgItemTextA的參考入手找到讀取輸入的地方,並對後面的流程做個註釋:


.text:00435061                 push    401h            ; cchMax
.text:00435066                 lea     eax, [ebp+String]
.text:0043506C                 push    eax             ; lpString
.text:0043506D                 push    3E9h            ; nIDDlgItem
.text:00435072                 mov     ecx, [ebp+hDlg]
.text:00435075                 push    ecx             ; hDlg
.text:00435076                 call    ds:GetDlgItemTextA            //讀取輸入
...
.text:004350A6                 lea     eax, [ebp+var_C30]
.text:004350AC                 push    eax
.text:004350AD                 push    400h
.text:004350B2                 lea     ecx, [ebp+String]
.text:004350B8                 push    ecx
.text:004350B9                 call    sub_42D267                //對輸入做第一層base64解碼
...
.text:004350DE                 lea     eax, [ebp+var_1038]
.text:004350E4                 push    eax
.text:004350E5                 push    400h
.text:004350EA                 lea     ecx, [ebp+var_C30]
.text:004350F0                 push    ecx
.text:004350F1                 call    sub_42D267                //對輸入做第二層base64解碼
.text:004350F6                 add     esp, 0Ch
.text:004350F9                 push    400h
.text:004350FE                 lea     eax, [ebp+var_1440]
.text:00435104                 push    eax
.text:00435105                 lea     ecx, [ebp+var_1038]
.text:0043510B                 push    ecx
.text:0043510C                 call    sub_42D96A                //摩爾斯電碼解碼,空格分隔,4個字元轉成一個小寫字母
.text:00435111                 add     esp, 0Ch
.text:00435114                 mov     [ebp+var_144C], 3
.text:0043511E                 lea     eax, [ebp+var_1474]
.text:00435124                 push    eax
.text:00435125                 mov     ecx, [ebp+var_144C]
.text:0043512B                 push    ecx
.text:0043512C                 lea     edx, [ebp+var_1038]
.text:00435132                 push    edx
.text:00435133                 call    sub_42DA78                //計算前3個字元的hash
.text:00435138                 add     esp, 0Ch
.text:0043513B                 mov     [ebp+var_1888], 0
.text:00435145                 jmp     short loc_435156
.text:00435147 loc_435147:
.text:00435147                 mov     eax, [ebp+var_1888]
.text:0043514D                 add     eax, 1
.text:00435150                 mov     [ebp+var_1888], eax
.text:00435156 loc_435156:
.text:00435156                 cmp     [ebp+var_1888], 20h
.text:0043515D                 jge     short loc_43518B
.text:0043515F                 mov     eax, [ebp+var_1888]
.text:00435165                 movzx   ecx, [ebp+eax+var_1474]
.text:0043516D                 push    ecx
.text:0043516E                 push    offset a02x     ; "%02x"
.text:00435173                 mov     edx, [ebp+var_1888]
.text:00435179                 lea     eax, [ebp+edx*2+var_187C]
.text:00435180                 push    eax
.text:00435181                 call    sub_42DF05                //hash結果轉成16進位制字串
.text:00435186                 add     esp, 0Ch
.text:00435189                 jmp     short loc_435147
.text:0043518B loc_43518B:
...
.text:004351C0                 sub     esi, eax
.text:004351C2                 push    esi
.text:004351C3                 lea     eax, [ebp+var_187C]
.text:004351C9                 push    eax
.text:004351CA                 call    sub_42DB27                //hash串和輸入的後64個字元比較
.text:004351CF                 add     esp, 0Ch
.text:004351D2                 test    eax, eax
.text:004351D4                 jnz     short loc_435214
.text:004351D6                 call    sub_42D0B4
.text:004351DB                 lea     eax, [ebp+var_1440]
.text:004351E1                 push    eax
.text:004351E2                 push    offset unk_49B000            //迷宮資料
.text:004351E7                 call    sub_42D9AB                //根據輸入做迷宮尋路
.text:004351EC                 add     esp, 8
.text:004351EF                 movzx   ecx, al
.text:004351F2                 cmp     ecx, 1
.text:004351F5                 jnz     short loc_435214
.text:004351F7                 mov     esi, esp
.text:004351F9                 push    0               ; uType
.text:004351FB                 push    offset Caption  ; "CrackMe"
.text:00435200                 push    offset Text     ; "ok"
.text:00435205                 push    0               ; hWnd
.text:00435207                 call    ds:MessageBoxA
.text:0043520D                 cmp     esi, esp 

摩爾斯電碼解碼4個字元一組,空格是分隔符,空格前加'/'轉義表示空格本身,每4個字元查表0049B2A0處的資料表,按順序對應a~z:


.-**
-...
-.-.
-..*
.***
..-.
--.*
....
..**
.---
-.-*
.-..
--**
-.**
---*
.--.
--.-
.-.*
...*
-***
..-*
...-
.--*
-..-
-.--
--..



大小是10*10的迷宮資料49B000,要求從左上角走到右上角,0是可走點,1是障礙,x是個暗樁導致死鎖:
0 1 1 1 1 1 1 1 1 0
0 0 1 1 1 1 1 0 0 0
1 0 0 0 0 0 1 0 1 1
1 1 1 1 1 0 1 0 x 1
1 0 0 0 1 0 1 0 0 1
1 0 1 0 0 0 1 0 1 1
1 0 1 1 1 1 1 0 0 1
1 0 0 0 0 1 1 1 0 0
1 1 1 1 0 0 0 0 1 0
1 1 1 1 1 1 1 0 0 0


迷宮走法是:

z    下

l    右

q    上

p    左


所以解題流程就清楚了:把迷宮路線用zlqp四個字元表示出來(注意末尾帶個空格表示結束):

zlzllllzzzppqppzzzlllzlllzllqqpqpqqqqqllq

然後轉成摩爾斯編碼:

--.. .-.. --.. .-.. .-.. .-.. .-.. --.. --.. --.. .--. .--. --.- .--. .--. --.. --.. --.. .-.. .-.. .-.. --.. .-.. .-.. .-.. --.. .-.. .-.. --.- --.- .--. --.- .--. --.- --.- --.- --.- --.- .-.. .-.. --.-/


做兩層base64:

TFMwdUxpQXVMUzR1SUMwdExpNGdMaTB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDMHRMaTRnTFMwdUxpQXVMUzB1SUM0dExTNGdMUzB1TFNBdUxTMHVJQzR0TFM0Z0xTMHVMaUF0TFM0dUlDMHRMaTRnTGkwdUxpQXVMUzR1SUM0dExpNGdMUzB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDNHRMaTRnTGkwdUxpQXRMUzR0SUMwdExpMGdMaTB0TGlBdExTNHRJQzR0TFM0Z0xTMHVMU0F0TFM0dElDMHRMaTBnTFMwdUxTQXRMUzR0SUM0dExpNGdMaTB1TGlBdExTNHRMeUE

後面加上hash得到答案:

TFMwdUxpQXVMUzR1SUMwdExpNGdMaTB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDMHRMaTRnTFMwdUxpQXVMUzB1SUM0dExTNGdMUzB1TFNBdUxTMHVJQzR0TFM0Z0xTMHVMaUF0TFM0dUlDMHRMaTRnTGkwdUxpQXVMUzR1SUM0dExpNGdMUzB1TGlBdUxTNHVJQzR0TGk0Z0xpMHVMaUF0TFM0dUlDNHRMaTRnTGkwdUxpQXRMUzR0SUMwdExpMGdMaTB0TGlBdExTNHRJQzR0TFM0Z0xTMHVMU0F0TFM0dElDMHRMaTBnTFMwdUxTQXRMUzR0SUM0dExpNGdMaTB1TGlBdExTNHRMeUEb92a72497b685c31013347a7276f371f8cf91085ab8322009bfed2df41d94f94

實際情況是,題目中迷宮判斷有bug,遇到空格就會結束,判為成功,所以利用空格可以構造出無數的解來,甚至自己不加空格,程式都會自動從記憶體中一直向後找到一個空格為止。


溫馨提示

每道題結束過後都會看到很多盆友的精彩解題分析過程,因為公眾號內容的限制,每次題目過後我們將選出一篇與大家分享。解題方式多種多樣,各位參賽選手的腦洞也種類繁多,想要看到更多解題分析的小夥伴們可以前往看雪論壇【CrackMe】版塊檢視哦!

熱門推薦| 看雪CTF

看雪.騰訊TSRC 2017 CTF 秋季賽 第一題點評及解析思路 看雪.騰訊TSRC 2017 CTF 秋季賽 第二題點評及解析思路 看雪.騰訊TSRC 2017 CTF 秋季賽10月24日開賽,神祕大獎揭曉!看雪.騰訊TSRC 2017 CTF 秋季賽 明日開賽!你不得不知的參賽指南 【火熱報名中】看雪Android 安全訓練營,11月17號開課啦! 蟄伏17年,看雪社群主辦《安全開發者峰會》將於11月18日在北京舉行

相關文章