-
-
[原创]第三题 影分身之术
-
发表于: 2019-3-25 15:05 3268
-
第三题是一个dephi编写的程序,主要利用了WebBrowser控件,将密码藏在js代码中。拖入ida,观察到如下函数Tfrmcrackme_FormShow(int a1):
该函数是webbrowser主要内容,通过跟踪和调试,可以比较好的确定webbrowser的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <!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的回调函数。
1 2 3 4 5 6 7 8 9 10 11 12 | 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; } |
跟踪该函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 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)函数中,继续步进,发现如下函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 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等,所以慢慢跟踪到如下函数.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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。
赞赏
他的文章
- [原创]看雪CTF2019参赛题目 3732
- [原创]第四题 拯救单身狗 4641
- [原创]第十题 初入好望角 4105
- [原创]第六题 Repwn 4132
- [原创]第三题 影分身之术 3269
赞赏
雪币:
留言: