-
-
[原创]看雪CTF2017第11题
-
2017-6-21 23:41 3122
-
1. 原始文件(记为0.exe)处理逻辑
内存加载内嵌的exe, 直接dump下来(RVA: 0x1000, SIZE: 0x45000, 记为1.exe)
.text:00447145 mov eax, [ebp+lpBaseAddress] .text:0044714B add eax, 1000h .text:00447150 push 45000h ; Size .text:00447155 push eax ; Src .text:00447156 push [ebp+Dst] ; Dst .text:0044715C call ds:memcpy
2. 1.exe处理逻辑
.rdata:0042A1A0 dword_42A1A0 dd 0 ; DATA XREF: __cinit+50o .rdata:0042A1A4 dd offset sub_4011D0 .rdata:0042A1A8 dd offset sub_4011F0 .rdata:0042A1AC dd offset sub_40120D .rdata:0042A1B0 dd offset sub_401219 .rdata:0042A1B4 dd offset sub_401225 .rdata:0042A1B8 dd offset sub_401000
根据当前进程的父进程(explorer.exe/cmd.exe/自身)来置标志位(0x439B50, 0x439B51)
当父进程是自身时, 会将0x437A08处的值置0
.text:00401000 sub_401000
当父进程是explorer.exe/cmd.exe时, 会以调试模式启动子进程
.text:00401690 ; int __stdcall wWinMain
当子进程执行此处时会发生除0异常
.text:004017B7 mov ecx, dword_437A08 .text:004017BD div ecx
父进程会修改子进程两处代码并继续执行(patch这两处dump, 记为2.exe)
.text:004017BD nop .text:004017BE nop .text:00401A43 jmp loc_402303
3. 验证逻辑
载入2.exe
读取文件0x41000处, 大小为0x5000的数据(记为M)
00402491 6A 00 push 0 00402493 68 80000000 push 80 00402498 6A 03 push 3 0040249A 6A 00 push 0 0040249C 6A 01 push 1 0040249E 68 00000080 push 80000000 004024A3 E8 F8F0FFFF call 004015A0 004024A8 8B40 30 mov eax, dword ptr [eax+30] 004024AB 50 push eax ; 自身文件名, 修改此处为0.exe 004024AC FFD7 call edi ... 00402810 6A 00 push 0 00402812 6A 00 push 0 00402814 68 00100400 push 41000 ; 文件偏移 00402819 FF75 D0 push dword ptr [ebp-30] 0040281C FFD7 call edi ... 004029B7 6A 00 push 0 004029B9 8D45 80 lea eax, dword ptr [ebp-80] 004029BC 50 push eax 004029BD 68 00500000 push 5000 004029C2 FF75 F4 push dword ptr [ebp-C] 004029C5 FF75 D0 push dword ptr [ebp-30] 004029C8 FFD7 call edi
sn格式: XXXXXXXXYYZZZZ...(XXXXXXXX记为v, YY记为k, ZZZZ...记为z)
使用v和k解密M
004029E4 E8 D7F1FFFF call 00401BC0 ; hex2bin(0, 8) ... 004029FB E8 10F1FFFF call 00401B10 ; hex2bin(8, 2) ... 00402A12 0FB645 F3 movzx eax, byte ptr [ebp-D] 00402A16 8B7D F8 mov edi, dword ptr [ebp-8] 00402A19 8B5D F4 mov ebx, dword ptr [ebp-C] 00402A1C 69F0 01010101 imul esi, eax, 1010101 00402A22 8B0493 mov eax, dword ptr [ebx+edx*4] 00402A25 8D0C3A lea ecx, dword ptr [edx+edi] 00402A28 03C6 add eax, esi 00402A2A 33C8 xor ecx, eax 00402A2C 890C93 mov dword ptr [ebx+edx*4], ecx 00402A2F 42 inc edx 00402A30 8B45 80 mov eax, dword ptr [ebp-80] 00402A33 C1E8 02 shr eax, 2 00402A36 3BD0 cmp edx, eax 00402A38 ^ 72 E8 jb short 00402A22
比较M与0x4340B0处的数据
00402A50 8A81 B0404300 mov al, byte ptr [ecx+4340B0] 00402A56 3A8411 B0404300 cmp al, byte ptr [ecx+edx+4340B0] 00402A5D 0F85 D7000000 jnz 00402B3A 00402A63 41 inc ecx 00402A64 83F9 60 cmp ecx, 60 00402A67 ^ 72 E7 jb short 00402A50
v,k可直接穷举得到
void test1() { DWORD d_enc[] = { 0x83F08EA7, 0x3F0FBA29, 0xE747E97C, 0x93D03647, 0xEC72CD2C, 0x93C0BA2E, 0x90A578A3, 0x2A40BA2F, 0xDB3FF233, 0x9031FB09, 0xD1477258, 0x905E3DAC, 0xAB817C35, 0x6BD43434, 0xC49E84E4, 0x83B426AF, 0x51C0BA3A, 0x280080B8, 0x93BE3FF3, 0x8E36BA3B, 0xE9C0BA3C, 0x93C0BA29, 0x93C0B2C5, 0x1680CD3F }; DWORD d_dec[] = { 0x1070EC81, 0x55530000, 0xBC8B5756, 0x00108424, 0xBBF63300, 0x00000001, 0x0725C68B, 0x79800000, 0xC8834805, 0x07B140F8, 0xC68BC82A, 0x07E28399, 0xF8C1C203, 0x38148A03, 0xD322FAD2, 0x10349488, 0x46000002, 0x7C40FE83, 0x0002BDCF, 0x05BA0000, 0xBE000000, 0x00000014, 0x000008B9, 0x8DC03300 }; int count = sizeof(d_enc)/sizeof(d_enc[0]); for (DWORD k = 0; k < 256; k++) { DWORD v = 0; BOOL bFound = TRUE; for (int i = 0; i < count; i++) { if (i == 0) { v = ((d_enc[i] + (k * 0x1010101)) ^ d_dec[i]) - i; } else { DWORD v2 = ((d_enc[i] + (k * 0x1010101)) ^ d_dec[i]) - i; if (v2 != v) { bFound = FALSE; break; } } } if (!bFound) { continue; } printf("%08lX%02X\n", v, k); } }
>>> 75A29C09E1
des key: 19930907
des_decrypt(z, key)== "!HelloHaniella!"
00402AA9 E8 92F7FFFF call 00402240 ; hex2bin(10, 32) 00402AAE 66:0F6F05 10414>movq mm0, qword ptr [434110] 00402AB6 8BF0 mov esi, eax 00402AB8 8D85 DCFCFFFF lea eax, dword ptr [ebp-324] 00402ABE C745 84 3139393>mov dword ptr [ebp-7C], 33393931 00402AC5 50 push eax 00402AC6 8BC2 mov eax, edx 00402AC8 C745 88 3039303>mov dword ptr [ebp-78], 37303930 00402ACF 50 push eax 00402AD0 8D45 84 lea eax, dword ptr [ebp-7C] 00402AD3 56 push esi 00402AD4 50 push eax 00402AD5 F3: prefix rep: 00402AD6 0F7F85 DCFEFFFF movq qword ptr [ebp-124], mm0 00402ADD FFD7 call edi ; des decrypt 00402ADF 83C4 14 add esp, 14 00402AE2 3BC6 cmp eax, esi 00402AE4 75 54 jnz short 00402B3A 00402AE6 8D8D DCFEFFFF lea ecx, dword ptr [ebp-124] 00402AEC 8D85 DCFCFFFF lea eax, dword ptr [ebp-324] 00402AF2 8A10 mov dl, byte ptr [eax] 00402AF4 3A11 cmp dl, byte ptr [ecx] 00402AF6 75 30 jnz short 00402B28 00434110 21 48 65 6C 6C 6F 48 61 6E 69 65 6C 6C 61 21 00 !HelloHaniella!.
这里的des用的应该是WjcDes的实现(修复bug后的)
同时加密前对原始数据转成bitstream(0~63)后的偶数位进行了位翻转
from Crypto.Cipher import DES def des_encrypt(k, message): des = DES.new(k, DES.MODE_ECB) return des.encrypt(message) def flip(v): nv = '' for i in range(len(v)): b = ord(v[i]) for k in range(8): if (k & 1) != 0: b ^= 1 << k nv += chr(b) return nv key = '19930907' text = '!HelloHaniella!\x00' ctext = des_encrypt(key, flip(text)) print ctext.encode('hex').upper()
>>> 80217C048420956C15DA309FF2B69170
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。
赞赏
他的文章
KCTF2022春季赛 第三题 石像病毒
8246
KCTF2022春季赛 第二题 末日邀请
15375
KCTF2021秋季赛 第二题 迷失丛林
17905
KCTF2020秋季赛 第十题 终焉之战
8079
KCTF2020秋季赛 第九题 命悬一线
5810
看原图