-
-
[原创]看雪2023 第三题 秘密计划
-
2023-9-6 17:37 3535
-
- 运行exe,随便输着玩,发现必须32位,才能验证
- 然后上调试器,运行崩溃,要把反调试nop掉
第一处
1 2 3 4 5 6 7 8 | .text: 00AE4952 loc_AE4952: ; CODE XREF: start - 7B ↑j .text: 00AE4952 56 push esi ; uExitCode .text: 00AE4953 E8 78 67 01 00 call sub_AFB0D0 .text: 00AE4958 .text: 00AE4958 loc_AE4958: ; CODE XREF: start - 3D ↑j .text: 00AE4958 FF 75 E0 push dword ptr [ebp - 20h ] ; uExitCode .text: 00AE495B E8 34 67 01 00 call sub_AFB094 .text: 00AE4960 CC int 3 ; Trap to Debugger # |
第二处
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 | void __stdcall sub_4079D0(PVOID a1, BOOLEAN a2) { HMODULE v2; / / eax FARPROC v3; / / eax HANDLE v4; / / eax HANDLE v5; / / eax int v6; / / [esp + 0h ] [ebp - 8h ] if ( dword_E4309C || ((v2 = GetModuleHandleW(L "ntdll.dll" )) = = 0 ? (v3 = (FARPROC)dword_E4309C) : (v3 = GetProcAddress( v2, "NtQueryInformationProcess" ), dword_E4309C = ( int (__stdcall * )(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))v3), v3) ) { v6 = 0 ; v4 = GetCurrentProcess(); if ( !dword_E4309C(v4, 7 , &v6, 4 , 0 ) ) { if ( v6 ) { v5 = GetCurrentProcess(); TerminateProcess(v5, 0 ); } } } } |
第三处
还有一堆int3的指令
3. 反复调试,看到了消息循环的函数4061D0
先看弹窗代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | if ( a4 ! = 0x47A ) { if ( a4 = = 0x47B ) { if ( * (_BYTE * )(a1 + 652 ) ) / / 就是shellcode 发消息机制 修改为 1 的那个 MessageBoxW( * (HWND * )(a1 + 28 ), &Text, "衏:y" , 0 ); / / 验证成功 else ( * (void (__stdcall * * )( int , signed int , _DWORD, _DWORD))( * (_DWORD * )a1 + 176 ))(a1, 1149 , 0 , 0 ); return 0 ; } if ( a4 = = 0x47D ) { MessageBoxW( * (HWND * )(a1 + 28 ), a1y, "衏:y" , 0 ); / / 验证失败 return 0 ; } if ( a4 ! = 0x47C ) { if ( a4 = = 0x47E && input ) { * (_OWORD * )(a1 + 628 ) = * input ; / / 接收验证段发来的结果 * (_OWORD * )(a1 + 644 ) = input [ 1 ]; } return 0 ; } |
继续往下能看到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | if ( ! * (_WORD * ) input ) { j_fun_free( input ); return 0 ; } sub_406850( input , &sha256, ( int )&v31, input_len); / / 计算SHA256 v30 = 0 ; sha256_1 = (__int128 * )&sha256; if ( v22 > = 0x10 ) sha256_1 = sha256; sub_406D20(sha256_1, ( int )&rsa_out, ( int )&v31, ( int )v9, esi0); / / 把SHA256用RSA公钥加密 LOBYTE(v30) = 1 ; if ( v24 ) { v11 = &rsa_out; if ( v25 > = 0x10 ) v11 = rsa_out; ( * (void (__thiscall * * )(_DWORD * , _DWORD * , int , _DWORD))(v9[ 170 ] + 8 ))(v9 + 170 , v11, v24, v9[ 7 ]); / / 40cf10 ,将RSA加密结果,再次复制过去。。。 ( * (void (__thiscall * * )(_DWORD * , unsigned int ))(v9[ 170 ] + 12 ))(v9 + 170 , v18); / / 这个,就是喜闻乐见的Function了 40cf60 } else { ( * (void (__stdcall * * )(_DWORD * , signed int , _DWORD, _DWORD))( * v9 + 176 ))(v9, 1149 , 0 , 0 ); / / 没走 } |
- 分析下一层函数 Function-40cf60,它调用40CF80
- 函数中先调用 40D6A0,获取了一堆 GUID 字符串
1 2 3 4 5 6 7 8 | F33FC7A6 - 5A29 - 44E7 - 921E - 1A3E9D88B648 93E5A078 - 5BA5 - 44F2 - 94B7 - 3109EA01DE10 0377E944 - EFB5 - 4AE8 - A5D8 - C6AE0677CDB3 E7FDEE55 - 7AB9 - 4495 - A48E - F510DF009792 9D5E62A2 - AA9E - 42D8 - B3AB - 17A4ACD94D2B EB1DB27D - 50FB - 4CEC - 8EAC - C0EBE37C6EAE 56214411 - 0AB7 - 4FB7 - B8B4 - 3B8DFE906E42 8FADFA6A - 5DB6 - 4F9C - BECA - 5C8D1E4003FF |
- 先看到循环调用0x40DA90,只有传入 56214411-0AB7-4FB7-B8B4-3B8DFE906E42 时,才能通过文件头的hash校验,解密出 code.dat 中的代码
1 2 3 4 5 6 7 | .text: 0040E195 A08 8A 11 mov dl, [ecx] .text: 0040E197 A08 3A 10 cmp dl, [eax] .text: 0040E199 A08 75 1A jnz short loc_40E1B5 .text: 0040E19B A08 84 D2 test dl, dl .text: 0040E19D A08 74 12 jz short loc_40E1B1 .text: 0040E19F A08 8A 51 01 mov dl, [ecx + 1 ] .text: 0040E1A2 A08 3A 50 01 cmp dl, [eax + 1 ] |
- 看到调用 0x40E670,实际上就是再把之前RSA加密,原封不动的解密回去。。。拿到sha256
1 2 3 4 5 6 | if ( (_DWORD)code_byte_len ) / / 0x754 ,就是纯密文的字节码长度 { v10 = v57; ( * (void (__thiscall * * )(LPVOID, _BYTE * * ))( * (_DWORD * )v57 + 4 ))(v57, &sha256); / / 40E670 调用核心函数 LOBYTE(v71) = 1 ; if ( !v62 ) / / 此时 = 0x20 本次验证就通过了... |
- 继续往下走,看到一堆奇怪的代码,思考若干时长发现是unicorn,然后手动识别函数名。并分析出unicorn内存布局:
0——0xA00000
0x4033:存放sha256,64字节
0x14390:保存运行结果,32字节,其中0和0x18处存放结果
0x43000:存放0x754个奇怪字符串,就是shellcode
0x43000+0x754:shellcode结尾
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | if ( uc_open( 1 , 0 , (signed int * * )&o_uc) ) / / 1 = UC_ARCH_ARM? UC_MODE_ARM { ptr_SendMessageW = (void (__stdcall * )(HWND, UINT, WPARAM, LPARAM))SendMessageW; } uc_ctl(o_uc, 0x44000007 , 17 ); / / 7 = UC_CTL_CPU_MODEL ,垃圾代码 故意返回UC_ERR_ARG uc_mem_map(o_uc, 0 , 0 , ( int )sub_A00000, 7 , ( int )lpAddress); / / 这里是分配了 0xA00000 空间,从地址 0 开始 v23 = code_byte_len_1; uc_mem_write(o_uc, 0x43000 , 0 , ( int )all_str, code_byte_len_1); / / all_str,一堆奇怪的字符串 00 00 结尾 input_sha256 = &v64; if ( v66 > = 0x10 ) input_sha256 = (__int128 * )v64; uc_mem_write(o_uc, 0x4033 , 0 , ( int )input_sha256, input_sha256_len); / / 明文sha256,长度是 64 个字节 if ( uc_emu_start(a1, v19, o_uc, 0x43000 , 0 , v23 + 0x43000 , 0i64 , 0 ) ) / / 返回了 0 ,代表模拟执行成功了 { v10 = v57; ptr_SendMessageW = (void (__stdcall * )(HWND, UINT, WPARAM, LPARAM))SendMessageW; } uc_mem_read(o_uc, 0x14390 , 0 , ( int )wParam, 0x20u ); / / wParam 应该是返回的值 uc_mem_unmap(o_uc, 0i64 , (unsigned int )sub_A00000); uc_close(o_uc); |
- 然后就是shellcode,根据上面分析结果,查资料发现是 ARM架构arm模式,将0x754字节保存,用IDA识别为ARM分析:
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 | ROM: 00000000 8D 01 00 EA B sub_63C ; 开辟空间 0x2000 ROM: 00000000 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ROM: 00000004 65 30 62 63 36 31 34 65 34 + aE0bc614e4fd035 DCB "e0bc614e4fd035a488619799853b075143deea596c477b8dc077e309c0fe42e9" ROM: 00000046 36 62 38 36 62 32 37 33 66 + a6b86b273ff34fc DCB "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b" 省略号 ROM: 00000634 66 6C 61 67 73 3A 00 aFlags DCB "flags:" , 0 ; DATA XREF: sub_63C + 94 ↓o ROM: 0000063C 02 DA A0 E3 MOV SP, #0x2000 ROM: 00000640 44 00 4F E2 06 0C 40 E2 ADRL R0, aE0bc614e4fd035 ; "e0bc614e4fd035a488619799853b075143deea5" ... ROM: 00000648 04 00 2D E5 STR R0, [SP, #var_4]! ROM: 0000064C CC 00 4F E2 05 0C 40 E2 ADRL R0, aD8bdf9a0cb27a1 ; "d8bdf9a0cb27a193a1127de2924b6e5a9e4c2d3" ... ROM: 00000654 04 00 2D E5 STR R0, [SP, #4+var_8]! ROM: 00000658 54 00 4F E2 05 0C 40 E2 ADRL R0, a6749dae311865d ; "6749dae311865d64db83d5ae75bac3c9e36b3aa" ... ROM: 00000660 04 00 2D E5 STR R0, [SP, #8+var_C]! ROM: 00000664 DC 00 4F E2 04 0C 40 E2 ADRL R0, a5b65712d565c15 ; "5b65712d565c1551340998102d418ceccb35db8" ... ROM: 0000066C 04 00 2D E5 STR R0, [SP, #0xC+var_10]! ROM: 00000670 64 00 4F E2 04 0C 40 E2 ADRL R0, a033c339a797554 ; "033c339a7975542785be7423a5b32fa80478136" ... ROM: 00000678 04 00 2D E5 STR R0, [SP, #0x10+var_14]! ROM: 0000067C FB 0F 4F E2 ADR R0, aC81d40dbeed369 ; "c81d40dbeed369f1476086cf882dd36bf1c3dc3" ... ROM: 00000680 00 00 A0 E1 NOP ROM: 00000684 04 00 2D E5 STR R0, [SP, #0x14+var_18]! ROM: 00000688 DD 0F 4F E2 ADR R0, a9e259b7f6b4c74 ; "9e259b7f6b4c741937a96a9617b3e6b84e166ff" ... ROM: 0000068C 00 00 A0 E1 NOP ROM: 00000690 04 00 2D E5 STR R0, [SP, #0x18+var_1C]! ROM: 00000694 BF 0F 4F E2 ADR R0, a1048f03db5d45f ; "1048f03db5d45f654b955eae20d84b72673680f" ... ROM: 00000698 00 00 A0 E1 NOP ROM: 0000069C 04 00 2D E5 STR R0, [SP, #0x1C+var_20]! ROM: 000006A0 A1 0F 4F E2 ADR R0, a8f0703d406fdb0 ; "8f0703d406fdb0ea8011d5de342c3aca6221475" ... ROM: 000006A4 00 00 A0 E1 NOP ROM: 000006A8 04 00 2D E5 STR R0, [SP, #0x20+var_24]! ROM: 000006AC 83 0F 4F E2 ADR R0, a182b32359558eb ; "182b32359558eb092511b7166867503ddd83fbe" ... ROM: 000006B0 00 00 A0 E1 NOP ROM: 000006B4 04 00 2D E5 STR R0, [SP, #0x24+var_28]! ROM: 000006B8 65 0F 4F E2 ADR R0, aFe5f0fc640cbbc ; "fe5f0fc640cbbc113406f042d08cc60ba784c77" ... ROM: 000006BC 00 00 A0 E1 NOP ROM: 000006C0 04 00 2D E5 STR R0, [SP, #0x28+var_2C]! ROM: 000006C4 47 0F 4F E2 ADR R0, a4fc82b26aecb47 ; "4fc82b26aecb47d2868c4efbe3581732a3e7cbc" ... ROM: 000006C8 00 00 A0 E1 NOP ROM: 000006CC 04 00 2D E5 STR R0, [SP, #0x2C+var_30]! ROM: 000006D0 A4 10 4F E2 ADR R1, aFlags ; "flags:" ROM: 000006D4 00 00 A0 E1 NOP ROM: 000006D8 0C 10 A0 E3 MOV R1, #0xC ROM: 000006DC ROM: 000006DC loc_6DC ; CODE XREF: sub_63C + E0↓j ROM: 000006DC 01 09 A0 E3 33 00 80 E2 MOV R0, #0x4033 ; 存放了64字节sha256 ROM: 000006E4 04 20 9D E4 LDR R2, [SP + 0x30 + var_30], #4 ; 定位到栈中常量字符串 ROM: 000006E8 02 80 A0 E1 MOV R8, R2 ; R8缓存一下,用于后续比较 ROM: 000006EC 00 50 A0 E3 MOV R5, #0 ROM: 000006F0 01 10 41 E2 SUB R1, R1, #1 ROM: 000006F4 ROM: 000006F4 loc_6F4 ; CODE XREF: sub_63C + D8↓j ROM: 000006F4 00 30 90 E5 LDR R3, [R0] ROM: 000006F8 00 40 92 E5 LDR R4, [R2] ROM: 000006FC 01 50 85 E2 ADD R5, R5, #1 ROM: 00000700 10 00 55 E3 CMP R5, #0x10 ROM: 00000704 06 00 00 AA BGE loc_724 ROM: 00000708 04 00 80 E2 ADD R0, R0, #4 ROM: 0000070C 04 20 82 E2 ADD R2, R2, #4 ROM: 00000710 04 00 53 E1 CMP R3, R4 ROM: 00000714 F6 FF FF 0A BEQ loc_6F4 ROM: 00000718 00 00 51 E3 CMP R1, #0 ; 如果所有数据都比较完,还没找到相同的,就退出 ROM: 0000071C EE FF FF 1A BNE loc_6DC ; 存放了 64 字节sha256 ROM: 00000720 0A 00 00 EA B loc_750 ROM: 00000724 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ROM: 00000724 ROM: 00000724 loc_724 ; CODE XREF: sub_63C + C8↑j ROM: 00000724 62 9E 4F E2 ADR R9, a6749dae311865d ; "6749dae311865d64db83d5ae75bac3c9e36b3aa" ... ROM: 00000728 00 00 A0 E1 NOP ROM: 0000072C 09 00 58 E1 CMP R8, R9 ; R8和R9相等,才是正确的 ROM: 00000730 06 00 00 1A BNE loc_750 ROM: 00000734 01 18 A0 E3 01 19 81 E2 03 + MOV R1, #0x14390 ; 这个地址,是成功后,存放数值的! ROM: 00000744 01 20 A0 E3 MOV R2, #1 ROM: 00000748 00 20 81 E5 STR R2, [R1] ROM: 0000074C 18 20 81 E5 STR R2, [R1, #0x18] |
- 大概含义就是从24个字符串中,遍历第0 2 4...11个字符串,看是否等于
传入的sha256(input),如果相等并且再等于"6749dae311865d64db83d5ae75bac3c9e36b3aa6f24caba655d9682f7f071023",就成功了。 - 然后就是好玩的根据sha256找明文的过程,又返回exe中找漏掉的代码,结果没找到。又回来看shellcode,把24个字符串抄出来玩。再瞎算sha256,发现了一定规律,字符串A=sha256(字符串B),最后只剩2组,猜测flag为:
ea96b41c1f9365c2c9e6342f5faaeab2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | e0bc614e4fd035a488619799853b075143deea596c477b8dc077e309c0fe42e9 sha256(sha256( 1 )) 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b 1 d8bdf9a0cb27a193a1127de2924b6e5a9e4c2d3b3fe42e935e160c011f3df1fc s.s. 2 d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35 2 6749dae311865d64db83d5ae75bac3c9e36b3aa6f24caba655d9682f7f071023 这个是正确flag的sha256 ea96b41c1f9365c2c9e6342f5faaeab2a44471efe1e65a2356a974646d2588fd ea96b41c1f9365c2c9e6342f5faaeab2 5b65712d565c1551340998102d418ceccb35db8dbfb45f9041c4cae483d8717b s.s. 3 4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce 3 033c339a7975542785be7423a5b32fa8047813689726214143cdd7939747709c s.s. 4 4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a 4 c81d40dbeed369f1476086cf882dd36bf1c3dc35e07006f0bec588b983055487 s.s. 5 ef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39d 5 9e259b7f6b4c741937a96a9617b3e6b84e166ff6e925e414e7b72936f5a2a51f s.s. 6 e7f6c011776e8db7cd330b54174fd76f7d0216b612387a5ffcfb81e6f0919683 6 1048f03db5d45f654b955eae20d84b72673680fb13b318e7da22e8dce58df21c s.s. 7 7902699be42c8a8e46fbbb4501726517e86b22c56a189f7625a6da49081b2451 7 8f0703d406fdb0ea8011d5de342c3aca62214758a8a2b5b8a4e9f1c8c6c42462 s.s. 8 2c624232cdd221771294dfbb310aca000a0df6ac8b66b696d90ef06fdefb64a3 8 182b32359558eb092511b7166867503ddd83fbe5b42f2545e1903016e721393d s.s. 9 19581e27de7ced00ff1ce50b2047e7a567c76b1cbaebabe5ef03f7c3017bb5b7 9 fe5f0fc640cbbc113406f042d08cc60ba784c775f7c3299985665323c5fbcdc4 s.s. 10 4a44dc15364204a80fe80e9039455cc1608281820fe2b24f1e5233ade6af1dd5 10 4fc82b26aecb47d2868c4efbe3581732a3e7cbcc6c2efb32062c08170a05eeb8 11 1ba586c0b89202f7307b61f1229330978a843afc98589ffc6a62f209225d3528 s.s. 11 |
赞赏
他的文章
[原创]看雪2023 第三题 秘密计划
3536