首页
社区
课程
招聘
[原创]看雪CTF2017第11题
2017-6-21 23:41 3122

[原创]看雪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漏洞挖掘与利用;代码审计。

收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回