首页
社区
课程
招聘
[原创]PEDIY2017P.CTF01Writeup 60s内的动静之争
发表于: 2017-10-24 17:04 4640

[原创]PEDIY2017P.CTF01Writeup 60s内的动静之争

2017-10-24 17:04
4640
Target:样品为VC 6.0 MFC CHello 基础编程样例
0x01 60s内攻破的碰撞成分
0x02 动态分析与静态分析之争
0x03 MFC的启动过程 


0x01 60s内攻破的碰撞成分
    贞:从拿到样品开始算,如何在60s内得到验证的passKey?
(1)样品的图标折射出MFC的特征;
(2)拖进已经打开的IDA开始自动分析,同时双击启动样品实例;
(3)打开IDA->View->Open subviews->Strings查阅字符信息,如下;
    Address Length Type String
    .rdata:0040333E 00000006 C (16 bits) @7
    .rdata:00403558 00000008 C (&A)...
    .rdata:00403560 00000006 C pass!
    .rdata:00403580 00000017 C WelcomeToKanXueCtf2017
    .rdata:0040359E 00000006 C pass!
    .rdata:0040392C 0000000A C MFC42.DLL
    .rdata:00403976 0000000B C MSVCRT.dll
    .rdata:00403A8A 0000000D C KERNEL32.dll
    .rdata:00403B2C 0000000B C USER32.dll
(4)若不怀疑CTF存在简单性的可能,直接复制WelcomeToKanXueCtf2017到提交框就能恰好碰撞成功。
(5)若有所怀疑,且觉得WelcomeToKanXueCtf2017更可能是欢迎标题,敏感点落在pass!字符串身上。
    搁置验证尝试,IDA交叉引用pass!(快捷键X)到函数 Hi_msg_pass_success_401770 的如下代码段
.text:0040177B push    offset Caption  ;
.text:0040177B         ; 恭喜!
.text:00401780 push    offset Text     ; "pass!"
.text:00401785 push    0               ; hWnd
.text:00401787 call    ds:MessageBoxA
(6)继续追溯Hi_msg_pass_success_401770的交叉引用到Hi_CDialogPassCheck__Check_sub_4017F0函数体内,如下;
   在调用提示通过的函数Hi_msg_pass_success_401770上下文发现了strcmp 和 "WelcomeToKanXueCtf2017",
   这时可以足够的信任,"WelcomeToKanXueCtf2017"至少作为passKey最终比对明文的一部分,
   再多看一眼局部变量loc_passKeyPtr在上文的来源,其直接就是CEdit的内容,
   中间没有任何变换处理,与"WelcomeToKanXueCtf2017"比对后也没有更多的比对操作,
   基本可以肯定"WelcomeToKanXueCtf2017"就是该CTF的签到暗语,直接复制提交。
.text:004017F0 Hi_CDialogPassCheck__Check_sub_4017F0 proc near
.text:004017F0 loc_passKeyPtr             = dword ptr -8
.text:004017F0 loc_thisptrCDialogPassCheck= dword ptr -4
.text:004017F0 push    ebp
.text:004017F1 mov     ebp, esp
.text:004017F3 sub     esp, 48h
.text:004017F6 push    ebx
.text:004017F7 push    esi
.text:004017F8 push    edi
.text:004017F9 mov     [ebp+loc_thisptrCDialogPassCheck], ecx
.text:004017FC mov     eax, [ebp+loc_thisptrCDialogPassCheck]
.text:004017FF add     eax, 64h
.text:00401802 push    eax             ; struct CString *
.text:00401803 push    3EAh            ; int //CEdit 控件ID
.text:00401808 mov     ecx, [ebp+loc_thisptrCDialogPassCheck] ; this
.text:0040180B call    CWnd::GetDlgItem(int) //获取CEdit空间对象
.text:00401810 mov     ecx, eax        ; this
.text:00401812 call    CWnd::GetWindowTextA(CString &) 
//将CEdit的字符值赋予验证对话框对象位于偏移0x64处的passKey成员
//loc_thisptrCDialogPassCheck.m_64h_CString_passKey = input_pass_key
.text:00401817 mov     ecx, [ebp+loc_thisptrCDialogPassCheck]
.text:0040181A add     ecx, 64h
.text:0040181D call    Hi_CString_GetLength_4018D0 //passKey 长度
.text:00401822 push    eax             ; int
.text:00401823 mov     ecx, [ebp+loc_thisptrCDialogPassCheck]
.text:00401826 add     ecx, 64h        ; this
.text:00401829 call    CString::GetBuffer(int)     //passKey Ptr
.text:0040182E mov     [ebp+loc_passKeyPtr], eax
.text:00401831 mov     ecx, [ebp+loc_passKeyPtr]
.text:00401834 push    ecx             ; loc_passKeyPtr
.text:00401835 call    strlen
.text:0040183A add     esp, 4
.text:0040183D test    eax, eax
.text:0040183F jnz     short loc_401854
.text:00401841 push    0               ; unsigned int
.text:00401843 push    0               ; char *
.text:00401845 push    offset byte_403598 ;
.text:00401845         ; 请输入pass!
.text:0040184A mov     ecx, [ebp+loc_thisptrCDialogPassCheck] ; this
.text:0040184D call    CWnd::MessageBoxA(char const *,char const *,uint)
.text:00401852 jmp     short loc_401875
.text:00401854 ; ---------------------------------------------------------------------------
.text:00401854 loc_401854:             
.text:00401854 push    offset Str2     ; "WelcomeToKanXueCtf2017"
.text:00401859 mov     edx, [ebp+loc_passKeyPtr]
.text:0040185C push    edx             ; Str1
.text:0040185D call    strcmp
.text:00401862 add     esp, 8
.text:00401865 test    eax, eax
.text:00401867 jnz     short loc_401870
.text:00401869 call    Hi_msg_pass_success_401770 ;
.text:00401869         ; MessageBoxA(0,"pass!","恭喜!")
.text:0040186E jmp     short loc_401875
.text:00401870 ; ---------------------------------------------------------------------------
.text:00401870 loc_401870:             
.text:00401870 call    Hi_msg_ComeOn_fail_4017B0 ;
.text:00401870         ; MessageBoxA(0,"加油!","错了!")
.text:00401875
.text:00401875 loc_401875:          
.text:00401875        
.text:00401875 pop     edi
.text:00401876 pop     esi
.text:00401877 pop     ebx
.text:00401878 mov     esp, ebp
.text:0040187A pop     ebp
.text:0040187B retn
.text:0040187B Hi_CDialogPassCheck__Check_sub_4017F0 endp


0x02 动态分析与静态分析之争
    贞:在从外表看出来是MFC,体积较小的印象之初,是选择动态调试还是静态分析先?
(1)因为这是小体积的独立样例,核心的逻辑或数据一般都会在里面,
   且若无法避免需要动态调试分析时,动态调试分析的针对性需要静态分析辅助,
   即先上静态,一窥全貌,再做应对安排。
(2)实际上在应对确定MFC消息响应函数这块,静态分析可能比动态来得更直接快速。
   包括直接从MFC类对象的虚表函数中找到其定义的消息映射表,
   或如上述通过敏感字符提示信息的交叉引用逆向追溯。
   

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 575
活跃值: (112)
能力值: ( LV5,RANK:140 )
在线值:
发帖
回帖
粉丝
2
牛逼,真的牛逼
2017-11-2 00:37
0
游客
登录 | 注册 方可回帖
返回
//