首页
社区
课程
招聘
[看雪CTF2016]第二十六题分析
发表于: 2016-12-23 14:41 2507

[看雪CTF2016]第二十六题分析

2016-12-23 14:41
2507
以调试模式启动子进程Broiler.exe, 处理int3事件
.text:00401C20                 push    eax             ; lpThreadId
.text:00401C21                 push    0               ; dwCreationFlags
.text:00401C23                 push    ecx             ; lpParameter
.text:00401C24                 push    offset StartAddress ; lpStartAddress
.text:00401C29                 push    0               ; dwStackSize
.text:00401C2B                 push    0               ; lpThreadAttributes
.text:00401C2D                 call    ds:CreateThread


第一次处理sn, 结果记为buf
.text:00401C7E                 lea     ecx, [esp+30h+sn]
.text:00401C82                 push    ecx
.text:00401C83                 call    sub_401060


第二次处理sn, 在子进程分配内存mem1写入buf, 分配内存mem2写入处理函数(记为func)
.text:00401C88                 lea     edx, [esp+34h+sn]
.text:00401C8C                 push    edx
.text:00401C8D                 call    sub_4010D0


处理子进程func中的第一处int3
xor     ecx, edi
int3
add     al, cl
=>
xor     ecx, edi
nop
sub     al, cl


处理子进程func中的第二处int3, 读取mem1处的内存并与固定的内容比较
.text:0040209E                 call    ds:ReadProcessMemory
.text:004020A4                 xor     ecx, ecx
.text:004020A6                 xor     eax, eax
.text:004020A8                 mov     dl, [esp+eax+40h+Buffer]
.text:004020AC                 cmp     dl, [esp+eax+40h+var_30]


处理函数func见xx_408800
BYTE ary[4][3][3] = {
	0x8C, 0x4C, 0x96, 0x5B, 0x2A, 0x3F, 0xB6, 0x5B, 0x2A, 
	0x11, 0xB1, 0x15, 0xAC, 0xC3, 0x53, 0xB6, 0x2A, 0x3F, 
	0xB2, 0xFC, 0x69, 0x10, 0xBF, 0xFD, 0xB6, 0x5B, 0x3F, 
	// out of bound area, 0xFF + count + mem
	0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x00
};

void xx_401060(BYTE *buf, int len)
{
	// generated from first char, bug?
	int v = (char)buf[0];
	for (int i = 0; i < len; i++)
	{
		BYTE t = (BYTE)((buf[0] >> 2) ^ (v >> 8));
		buf[i] = t ^ 0x41;
		v = 8956 * (v >> 2) + 5478 * (v + t);
	}
}

void xx_408800(BYTE *buf, int len)
{
	// VirtualAlloc
	DWORD mem = 0x003A0000;
	DWORD count = len;

	for (DWORD i = 0; i < count; i++)
	{
		*((PDWORD)&ary[3][0][1]) = count - i;
		*((PDWORD)&ary[3][1][2]) = mem + i;
		for (int k1 = 0; k1 < 3; k1++)
		{
			for (int k2 = 0; k2 < 2; k2++)
			{
				for (int k3 = 0; k3 < 4; k3++)
				{
					if ( buf[i] == ary[k1][k2][k3])
					{
						// out of bound when k3 == 3
						buf[i] = ary[k3][k1][k2] * (ary[k1][k2][k3] - (buf[i] ^ ary[k2][k3][k1]));
					}
				}
			}
		}
	}
}

void test()
{
	BYTE expected[21] = {
		0xEF, 0x86, 0x85, 0x0C, 0xD2, 0x89, 0x64, 0xA6, 0x9E, 0xC8, 0xCC, 0x70, 0x00, 0x90, 0x09, 0xF4, 
		0x28, 0x6E, 0x5A, 0x04, 0xF9,
	};
	BYTE sn[22] = {0};
	BYTE buf[21];
	for (int i = 0; i < 256; i++)
	{
		if (!isalnum(i)) continue;
		ZeroMemory(sn, sizeof(sn));
		sn[0] = i;
		CopyMemory(buf, sn, sizeof(buf));
		xx_401060(buf, sizeof(buf));
		xx_408800(buf, sizeof(buf));
		if (memcmp(buf, expected, sizeof(buf)) == 0)
		{
			printf("sn: %s\n", sn);
			return;
		}
	}
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//