KCTF2019_q4_第四题_西部乐园
2019-12-11 02:12:07 Author: bbs.pediy.com(查看原文) 阅读量:300 收藏

验证逻辑:

if ( (signed __int64)v5 <= 96000 && (signed __int64)v5 >= 90000 )

{

    ...

    dwIoControlCode = 0x222041;

    ...

    v7 = DeviceIoControl(hDevice, dwIoControlCode, &InBuffer, 0x107u, &OutBuffer, 0x400u, &BytesReturned, 0i64);

    if ( !v7 )

    {

      MessageBoxW(0i64, L"wrong!", L"err", 0);

      return 0i64;

    }

}    

输入数SN的范围在90000~96000之间,通过DeviceIoControl与驱动交互

InBuffer:

F0 F8 2C 00 00 00 00 00 //

50 20 99 3F 01 00 00 00 //

E0 1F 00 00 00 00 00 00 //pid

62 64 01 00 00 00 00 00 //SN

EB 18 //一段可执行代码

00 00 00 00 00 00 00 00 

08 00 00 00 00 00 00 00 

60 6B 99 3F 01 00 00 00 //

55 48 8B EC E8 01 00 00 00 90 48 8B C4 48 C7 C1 10 00 00 00 48 33 D2 48 F7 F1 83 FA 00 75 17 48 

8B 04 24 48 89 44 24 F8 48 8B 44 24 08 48 89 04 24 48 8D 64 24 F8 48 8B 0C 24 48 8B 51 DF 48 83 

FA 00 74 04 48 89 55 08 48 8B 51 E7 48 83 FA 00 48 BA 2D 7F 6C 43 F6 7F 00 00 48 B8 CE 7F 6C 43 

F6 7F 00 00 9C 48 2B C2 9D 74 17 48 8D 51 DD 48 8D 14 10 48 8B 41 E7 48 8D 04 10 48 8B 49 EF 51 

FF D0 48 8B E5 5D C3 

00 00 00 00 

E8 59 0D 6D 80 3C A2 78 15 87 16 16 07 26 68 55 7F 12 F1 EF F9 A1 9C E8 EA 9C 90 F4 9F 3A A8 8C //一段密文

27 47 79 F6 DC 20 7F 86 ED 34 7E F7 1C 55 6B F6 EF F2 2A 7A F0 44 50 8A 9B E1 C4 E1 45 90 2B 0E 

CF AF 

再到驱动里看一看:

PAGE:00000001400050A6                 cmp     dword ptr [rax+18h], 222041h

PAGE:00000001400050AD                 mov     r13d, [rax+10h]

PAGE:00000001400050B1                 jnz     loc_14000514E

PAGE:00000001400050B7                 mov     rcx, [rdx+8]

PAGE:00000001400050BB                 mov     r15, [rdx+18h] //InBuffer

PAGE:00000001400050BF                 test    byte ptr [rcx+0Ah], 5

PAGE:00000001400050C3                 jz      short loc_1400050CB

PAGE:00000001400050C5                 mov     r12, [rcx+18h]

PAGE:00000001400050C9                 jmp     short loc_1400050EA

...

PAGE:00000001400050EA loc_1400050EA:  mov     rax, [r15]

PAGE:00000001400050ED                 mov     r14, [r15+8]

PAGE:00000001400050F1                 mov     rdi, [r15+18h] //SN

PAGE:00000001400050F5                 mov     [rsp+58h+arg_8], rax

PAGE:00000001400050FA                 call    sub_14000110D         //获取一段shellcode长度 = 0xA1

PAGE:00000001400050FF                 movsxd  rbx, eax

PAGE:0000000140005102                 mov     esi, r13d                 //InBuffer总长度 = 0x107

PAGE:0000000140005105                 mov     r8d, edi                  //SN作为解密key

PAGE:0000000140005108                 lea     ecx, [rax+24h]

PAGE:000000014000510B                 sub     esi, ecx                  //密文长度0x107 - 0xA1 - 0x24 = 0x42

PAGE:000000014000510D                 lea     rcx, [r15+24h]

PAGE:0000000140005111                 add     rcx, rbx                  //密文指针

PAGE:0000000140005114                 mov     edx, esi                  //密文长度

PAGE:0000000140005116                 call    sub_1400015A0             //解密算法

PAGE:000000014000511B                 cmp     [rbx+r15+24h], esi        //如果解密出的数据第一个DWORD等长度0x42,就OK了

PAGE:0000000140005120                 jnz     short loc_140005139

所以把sub_1400015A0扔进ida里F5一下,写个穷举程序就得到了SN=91024

穷举代码:

#include <windows.h>
#include <stdio.h>
#include <math.h>


void decode(BYTE *a1, int len, int key)
{
	void **v3; // rax
	int v4; // er10
	__int64 v5; // rbx
	int v6; // esi
	__int64 v7; // r11
	unsigned __int8 v8; // al
	__int64 v9; // r8
	__int16 v10; // di
	unsigned __int16 v11; // dx
	void *retaddr; // [rsp+0h] [rbp+0h]
	
	v3 = &retaddr;
	v4 = key - 1;
	v5 = len;
	if ( key - 1 >= 0 )
	{
		v6 = len - 1;
		do
		{
			v7 = v4 % (signed int)v5;
			if ( v4 % (signed int)v5 )
			{
				v8 = a1[v7 - 1];
				v9 = v4 % (signed int)v5;
			}
			else
			{
				v8 = a1[v5 - 1];
				v9 = 0i64;
			}
			if ( (DWORD)v7 == v6 )
				v10 = (unsigned __int8)*a1 + ((unsigned __int8)a1[v9] << 8);
			else
				v10 = *(WORD *)&a1[v9];
			v11 = v10 + v8;
			*(WORD *)v3 = v11 >> 8;
			a1[v9] = HIBYTE(v11);
			if ( (DWORD)v7 == v6 )
				*a1 = v11;
			else
				a1[v9 + 1] = v11;
			--v4;
		}
		while ( v4 >= 0 );
	}
}

BYTE data[] = {
	0xE8,0x59,0x0D,0x6D,0x80,0x3C,0xA2,0x78,0x15,0x87,0x16,0x16,0x07,0x26,0x68,0x55,
	0x7F,0x12,0xF1,0xEF,0xF9,0xA1,0x9C,0xE8,0xEA,0x9C,0x90,0xF4,0x9F,0x3A,0xA8,0x8C,
	0x27,0x47,0x79,0xF6,0xDC,0x20,0x7F,0x86,0xED,0x34,0x7E,0xF7,0x1C,0x55,0x6B,0xF6,
	0xEF,0xF2,0x2A,0x7A,0xF0,0x44,0x50,0x8A,0x9B,0xE1,0xC4,0xE1,0x45,0x90,0x2B,0x0E,
	0xCF,0xAF
};

void crack04()
{
	BYTE t[0x100];
	int i;

	for (i=90000;i<96000;i++)
	{
		memcpy(t,data,sizeof(data));
		decode(t,sizeof(data),i);
		if (*(DWORD *)t == 0x42)
		{
			printf("%d",i);
		}
	}
	
}

int main(int argc, char* argv[])
{
	crack04();

	getchar();

	return 1;
}

[进行中]2019 KCTF总决赛 | 巅峰对决,谁与争锋!(感谢第五空间和安恒信息对活动的支持!)


文章来源: https://bbs.pediy.com/thread-256286.htm
如有侵权请联系:admin#unsafe.sh