-
-
[原创]第三题 影分身之术
-
发表于: 2019-3-25 15:05 3124
-
第三题是一个dephi编写的程序,主要利用了WebBrowser控件,将密码藏在js代码中。拖入ida,观察到如下函数Tfrmcrackme_FormShow(int a1):
该函数是webbrowser主要内容,通过跟踪和调试,可以比较好的确定webbrowser的代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta charset="utf-8"> <title></title> <script> function sptWBCallback(spt_wb_id,spt_wb_name,optionstr){ url='#sptWBCallback:id='; url=url+spt_wb_id+';eventName='+spt_wb_name; if(optionstr) url=url+';params=optionstr'; location=url; } function ckpswd() { key="simpower91"; a = document.all.pswd.value; if (a.indexOf(key) ==0) { l=a.length; i=key.length; sptWBCallback(a.substring(i,l)); } else { alert("wrong!<" + a + "> is not my GUID ;-)"); return "1234"; } } function ok(){ alert("congratulations!"); } </script> </head> <body> <input value="" id="pswd" size=39></input> <br><br><br> <input type=button value="checkMyFlag" onclick="ckpswd();"></center> </body> </html>
得出来key为simpower91,然后会触发sptWBCallback函数,函数会通过location=url复制进行url的变化,在delphi中,该操作是会触发onnavigator2回调函数的,在Tfrmcrackme_FormCreate(int a1)函数中的sub_491DCC函数中,有如下的函数,尝试对sub_492088()下断点,发现可以直接断下,判断该函数为js中location=url的回调函数。
int __fastcall sub_491DCC(int a1) { int v1; // ebx int result; // eax v1 = a1; sub_491B78(a1); result = *(_DWORD *)(v1 + 64); *(_DWORD *)(result + 676) = v1; *(_DWORD *)(result + 672) = 0x00492088; return result; }
跟踪该函数如下:
int __userpurge sptWBCallback@<eax>(int a1@<eax>, int a2@<edx>, int a3@<ecx>, int a4@<ebx>, int a5@<esi>, int edi0@<edi>, _WORD *a6, int a7, int a8, int a9, int a10, int a11) { System::AnsiString = 0; v29 = 0; *(_DWORD *)input_url_str = 0; v27 = 0; v26 = 0; v25 = 0; v24 = a4; v23 = a5; v31 = a3; v32 = a2; v12 = a1; v22 = &savedregs; v21 = &loc_4921D1; v20 = __readfsdword(0); __writefsdword(0, (unsigned int)&v20); Variants::__linkproc__ VarToLStr(&v29, a11); v13 = sub_465C88((int)&str__sptWBCallback_[1], v29); if ( (signed int)v13 > 0 ) { *a6 = -1; Variants::__linkproc__ VarToLStr(&System::AnsiString, a11); v14 = LStrLen(System::AnsiString); v15 = System::__linkproc__ LStrCopy(System::AnsiString, (int)(v13 + 15),v14 - (_DWORD)v13 - 14,(int)&System::AnsiString); LOBYTE(v15) = 1; LStrReplace(System::AnsiString, (int)&str___41[1], (int)&str____19[1], v12, edi0, (int)v13, (int)input_url_str, v15); System::__linkproc__ LStrLAsg(&System::AnsiString, *(_DWORD *)input_url_str); v16 = (Classes::TStrings *)TObject_Create((int)cls_Classes_TStringList, 1); (*(void (__fastcall **)(Classes::TStrings *, int))(*(_DWORD *)v16 + 44))(v16, System::AnsiString);// TStrings.SetTextStr if ( *(_WORD *)(v12 + 50) ) { Classes::TStrings::GetValue(v16, (const int)&str_params[1]); v17 = v27; Classes::TStrings::GetValue(v16, (const int)&str_eventName[1]); v18 = v26; Classes::TStrings::GetValue(v16, (const int)&str_id[1]); (*(void (__fastcall **)(_DWORD, int, int, int))(v12 + 48))(*(_DWORD *)(v12 + 52), v25, v18, v17); } } if ( *(_WORD *)(v12 + 58) ) (*(void (__fastcall **)(_DWORD, int, int, int, int, int, int, int, _WORD *))(v12 + 56))( *(_DWORD *)(v12 + 60), v32, v31, a11, a10, a9, a8, a7, a6); __writefsdword(0, v20); v22 = (int *)&loc_4921D8; return System::__linkproc__ LStrArrayClr(&v25, 6); }
继续调试,进入到((void (__fastcall **)(_DWORD, int, int, int))(v12 + 48))((_DWORD *)(v12 + 52), v25, v18, v17)函数中,继续步进,发现如下函数:
CODE:0047394C sub_47394C proc near ; CODE XREF: _Tfrmcrackme_Button2Click+A1↓p CODE:0047394C CODE:0047394C var_2C = dword ptr -2Ch CODE:0047394C var_8 = dword ptr -8 CODE:0047394C var_4 = dword ptr -4 CODE:0047394C var_s0 = dword ptr 0 CODE:0047394C arg_4 = dword ptr 0Ch CODE:0047394C CODE:0047394C push ebp CODE:0047394D mov ebp, esp CODE:0047394F leave CODE:00473950 push dword ptr [esp+0] CODE:00473953 push [esp+var_s0] CODE:00473956 push [esp+4+var_4] CODE:00473959 pusha CODE:0047395A pushf CODE:0047395B call GetA400BaseAddr CODE:00473960 mov ebx, eax CODE:00473962 xor eax, eax CODE:00473964 mov [ebx+1050h], eax CODE:0047396A mov eax, 0FFFFFFFFh CODE:0047396F mov [ebx+1054h], eax CODE:00473975 mov [esp+2Ch+var_8], ebx CODE:00473979 add [esp+2Ch+var_4], 5 CODE:0047397E mov eax, [esp+2Ch+arg_4] CODE:00473982 mov [esp+2Ch+var_s0], eax CODE:00473986 mov eax, [ebx+1090h] CODE:0047398C cmp eax, 0 CODE:0047398F jnz short loc_47399C CODE:00473991 mov eax, offset sub_47378C CODE:00473996 mov [ebx+1090h], eax CODE:0047399C CODE:0047399C loc_47399C: ; CODE XREF: sub_47394C+43↑j CODE:0047399C popf CODE:0047399D popa CODE:0047399E call sub_4734B0 CODE:004739A3 pushf CODE:004739A4 pushf CODE:004739A5 pushf CODE:004739A6 pusha CODE:004739A7 pushf CODE:004739A8 jmp short loc_4739CE CODE:004739AA ; --------------------------------------------------------------------------- CODE:004739AA CODE:004739AA loc_4739AA: ; CODE XREF: sub_47394C+95↓j CODE:004739AA mov eax, [ebx+1058h] CODE:004739B0 mov [esp+2Ch+var_s0], eax CODE:004739B4 mov eax, [ebx+1050h] CODE:004739BA mov [esp+2Ch+var_4], eax CODE:004739BE mov [esp+2Ch+var_8], ebx CODE:004739C2 popf CODE:004739C3 popa CODE:004739C4 call sub_4734B0 CODE:004739C9 pushf CODE:004739CA pushf CODE:004739CB pushf CODE:004739CC pusha CODE:004739CD pushf CODE:004739CE CODE:004739CE loc_4739CE: ; CODE XREF: sub_47394C+5C↑j CODE:004739CE call GetA400BaseAddr CODE:004739D3 mov ebx, eax CODE:004739D5 mov eax, [ebx+1050h] CODE:004739DB cmp eax, [ebx+1054h] CODE:004739E1 jb short loc_4739AA CODE:004739E3 mov eax, [ebx+1050h] CODE:004739E9 mov [esp+30h], eax CODE:004739ED mov eax, [esp+2Ch+var_2C] CODE:004739F0 mov [esp+2Ch+var_s0], eax CODE:004739F4 popf CODE:004739F5 popa CODE:004739F6 add esp, 8 CODE:004739F9 popf CODE:004739FA retn 8 CODE:004739FA sub_47394C endp
这个还挺麻烦的,里面有很多的popa,pusha,popf等,所以慢慢跟踪到如下函数.
CODE:004734B0 push ebp CODE:004734B1 mov ebp, esp CODE:004734B3 leave CODE:004734B4 pusha CODE:004734B5 pushf CODE:004734B6 push ebp CODE:004734B7 mov ebp, esp CODE:004734B9 sub esp, 10h CODE:004734BC lea edx, [ebp+var_10] CODE:004734BF push edx CODE:004734C0 lea edx, [ebp+var_C] CODE:004734C3 push edx CODE:004734C4 lea edx, [ebp+var_8] CODE:004734C7 push edx CODE:004734C8 push [ebp+arg_2C] CODE:004734CB push [ebp+arg_20] CODE:004734CE push [ebp+arg_28] CODE:004734D1 mov edx, [ebp+arg_24] CODE:004734D4 mov ecx, [ebp+4] CODE:004734D7 mov [edx+105Ch], ecx CODE:004734DD push edx CODE:004734DE call sub_472EAC CODE:004734E3 leave CODE:004734E4 mov eax, [esp+30h+var_30] CODE:004734E7 mov [esp+30h+var_s0], eax CODE:004734EB popf CODE:004734EC popa CODE:004734ED add esp, 0Ch CODE:004734F0 popf CODE:004734F1 jmp [esp-4+var_40] CODE:004734F1 sub_4734B0 endp
函数利用了jmp [esp-4+var_40]该语句不停的跳转不同的指令进行对比,跟踪进去,发现这些指令就是用来比较flag的,单步跟踪和调试去满足它的比较条件,得出最后的flag为simpowera123。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
- [原创]看雪CTF2019参赛题目 3561
- [原创]第四题 拯救单身狗 4466
- [原创]第十题 初入好望角 3943
- [原创]第六题 Repwn 3962
- [原创]第三题 影分身之术 3125
看原图
赞赏
雪币:
留言: