首页
社区
课程
招聘
[原创]KCTF2019_q4_第四题_西部乐园
2019-12-7 15:45 4176

[原创]KCTF2019_q4_第四题_西部乐园

ccfer 活跃值
16
2019-12-7 15:45
4176


验证逻辑:
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;
}


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞1
打赏
分享
最新回复 (1)
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
wx_moon_557 2019-12-16 12:02
2
0
大佬可以给一个联系方式么
游客
登录 | 注册 方可回帖
返回