-
-
第七题 不问少年crackme Writeup
-
2017-6-15 00:13 3029
-
本题主要对输入进行多次置换后,与一固定的表进行匹配,若匹配成功,输入将用于解密一段加密后的shellcode,最后执行这段shellcode。解这题主要是通过逆推得到最初的正确输入。
第一步对输入处理的函数位于sub_411b30,这个函数的内容在执行前是经过加密的,通过与“PEDIY”异或进行解密,解密函数为sub_410dd6。
进入sub_411b30中,首先将输入的每一位与0xcc异或得v1,最后到一个大小为0x40的表中查找v1的偏移offset。表如下所示。
得到偏移offset后,会将offset除以5,得到的商加上5后加上offset得到新的偏移Newoffset。同样还会将Newoffset继续除以5得到商加上5后加上Newoffset得到Newoffset1,如此循环,循环的次数取决于这是输入数据的第几位。循环如下所示。
00411C4A 8B0E mov ecx,dword ptr ds:[esi] 00411C4C 0FBEC3 movsx eax,bl 00411C4F 47 inc edi 00411C50 99 cdq 00411C51 F77D E4 idiv dword ptr ss:[ebp-0x1C] 00411C54 6A 05 push 0x5 00411C56 5A pop edx 00411C57 03C2 add eax,edx 00411C59 3BF8 cmp edi,eax 00411C5B ^ 75 E7 jnz short 7-不问少.00411C44 00411C5D 8B7D EC mov edi,dword ptr ss:[ebp-0x14] 00411C60 8AC1 mov al,cl 00411C62 2A06 sub al,byte ptr ds:[esi] 00411C64 8807 mov byte ptr ds:[edi],al 00411C66 75 05 jnz short 7-不问少.00411C6D 00411C68 33DB xor ebx,ebx 00411C6A 43 inc ebx 00411C6B EB 03 jmp short 7-不问少.00411C70 00411C6D 0FBED8 movsx ebx,al 00411C70 836D D4 01 sub dword ptr ss:[ebp-0x2C],0x1 00411C74 881F mov byte ptr ds:[edi],bl 00411C76 ^ 75 CA jnz short 7-不问少.00411C42 00411C78 0FBE0F movsx ecx,byte ptr ds:[edi] 00411C7B 8B06 mov eax,dword ptr ds:[esi] 00411C7D 8A0401 mov al,byte ptr ds:[ecx+eax] 00411C80 8807 mov byte ptr ds:[edi],al 00411C82 8B4D E8 mov ecx,dword ptr ss:[ebp-0x18] 00411C85 41 inc ecx 00411C86 47 inc edi 00411C87 894D E8 mov dword ptr ss:[ebp-0x18],ecx 00411C8A 897D EC mov dword ptr ss:[ebp-0x14],edi 00411C8D 3B4D D0 cmp ecx,dword ptr ss:[ebp-0x30] 00411C90 7D 08 jge short 7-不问少.00411C9A 00411C92 8B5D 1C mov ebx,dword ptr ss:[ebp+0x1C] 00411C95 ^ E9 64FFFFFF jmp 7-不问少.00411BFE
最后将得到一串值,这串值的每一位将和0xcc进行异或得到v2,并将v2逻辑左移3位的值和v算术右移5位的值进行或运算,得到新的一串值。这些是在函数sub_4116ec中实现的。
00410F75 55 push ebp 00410F76 8BEC mov ebp,esp 00410F78 8B55 08 mov edx,dword ptr ss:[ebp+0x8] 00410F7B 33C0 xor eax,eax 00410F7D 56 push esi 00410F7E 8B75 0C mov esi,dword ptr ss:[ebp+0xC] ; 7-不问少.00411CDA 00410F81 2BF2 sub esi,edx 00410F83 57 push edi 00410F84 33FF xor edi,edi 00410F86 3B55 0C cmp edx,dword ptr ss:[ebp+0xC] ; 7-不问少.00411CDA 00410F89 0F47F0 cmova esi,eax 00410F8C 85F6 test esi,esi 00410F8E 74 17 je short 7-不问少.00410FA7 00410F90 8A0A mov cl,byte ptr ds:[edx] 00410F92 80F1 CC xor cl,0xCC 00410F95 8AC1 mov al,cl 00410F97 C0E1 03 shl cl,0x3 00410F9A C0F8 05 sar al,0x5 00410F9D 0AC1 or al,cl 00410F9F 8802 mov byte ptr ds:[edx],al 00410FA1 42 inc edx 00410FA2 47 inc edi 00410FA3 3BFE cmp edi,esi 00410FA5 ^ 75 E9 jnz short 7-不问少.00410F90 00410FA7 5F pop edi ; 7-不问少.00411CA9 00410FA8 5E pop esi ; 7-不问少.00411CA9 00410FA9 5D pop ebp ; 7-不问少.00411CA9 00410FAA C3 retn
下一步处理是在函数sub_411825中实现的,上一步得到的一串值将被转化为四进制。转换代码如下所示。
004119F9 2A45 AC sub al,byte ptr ss:[ebp-0x54] 004119FC 83C4 10 add esp,0x10 004119FF 0FBEC8 movsx ecx,al 00411A02 8BC1 mov eax,ecx 00411A04 99 cdq 00411A05 83E2 03 and edx,0x3 00411A08 03C2 add eax,edx 00411A0A C1F8 02 sar eax,0x2 00411A0D 8845 C4 mov byte ptr ss:[ebp-0x3C],al 00411A10 81E1 03000080 and ecx,0x80000003 00411A16 79 05 jns short 7-不问少.00411A1D
得到的四进制串必须大小为0x50才能满足要求,也就是说输入的字符串必须长度为20才能满足要求。之后将会比较这个四进制串和固定的一串四进制串,只有两者相等才能通过。固定的四进制串如下所示。
当判断通过后,将调用VirtualAlloc申请一段空间,写入shellcode并用输入进行异或解密,最后执行这段shellcode。值得一提的是,当输入不同时,最后得出来的四进制值也可能相同,但shellcode不能正常执行。因此必须测试不同的具有相同四进制值的输入,保证shellcode能够正常执行。按照步骤进行逆推即可得到答案,不过例如查表操作以及左移右移操作比较难从输出逆推出输入,这时候就得正向去求不同输入所得到的输出,然后再去比对正确的输出。最后,得答案为“BwnsAtPediy2017KX9Ok”。
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界