抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

32位无壳程序

CEF简介:

嵌入式Chromium框架(简称CEF) 是一个由Marshall Greenblatt在2008建立的开源项目,它主要目的是开发一个基于Google Chromium的Webbrowser控件。CEF支持一系列的编程语言和操作系统,并且能很容易地整合到新的或已有的工程中去。

解题:

正面去分析的话,十分困难。去搜索相应字符串无果

这里我们可以去从数据调用去分析,我们去分析.data的数据

一组奇怪的数据,猜测加密时用到,交叉引用找到调用的地方

调试验证一下,一开始会停在调用的dll函数里面,我们直接步过,然后输入32位之后就会断下F9提示correct,验证我们的猜想是正确的。调试发现其实,加密整个逻辑就在else里面,一个魔改的SM4,其基本运算为异或^和循环左移<<<

round函数

解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <stdio.h>
#include <string.h>

unsigned int SK[32] = {
0xE8DB227C, 0x012451B9, 0xED08A9DB, 0xC91F65C3,
0xB3D1E981, 0x319B4734, 0xA4BA5551, 0xD0F2ED2D,
0x4A00D692, 0xE0AEFE30, 0x6BBCDB4A, 0xC315F6F1,
0xB4E1B030, 0x694C4ACE, 0x479208D3, 0x3F8C7B97,
0x747777A6, 0xEDEC9BBB, 0xC8E506C1, 0xB955A92A,
0xB388FDBB, 0x1A4697C3, 0xB10826AA, 0xBB1F2207,
0x291DCD60, 0x2BA3E3A7, 0x1B83DFDD, 0x014D4FD5,
0x80C659F3, 0x3EB45B23, 0x43E36266, 0xBD22532C
};

#define GET_ULONG(n, b, i) \
(n) = ( (unsigned long) (b)[(i + 3)] << 24 ) \
| ( (unsigned long) (b)[(i + 2)] << 16 ) \
| ( (unsigned long) (b)[(i + 1)] << 8 ) \
| ( (unsigned long) (b)[(i )] ); \

#define PUT_ULONG(n, b, i) \
{ \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) ] = (unsigned char) ( (n) ); \
}

#define SHL(x, n) ( ((x) & 0xFFFFFFFF) << n )

#define ROTL(x, n) ( SHL((x), n) | ((x) >> (32 - n)) )

#define SWAP(a, b) { unsigned t = a; a = b; b = t; t = 0; }


void SM4_Decrypt(unsigned char * input, unsigned char * output, int len);
void Round(unsigned char input[16], unsigned char output[16]);

int main(void)
{

unsigned char input[] =
{
0x7D, 0x54, 0xCB, 0xC0, 0x74, 0xDB, 0xF5, 0xD7, 0x6F, 0xD9,
0x92, 0x1B, 0xEB, 0x28, 0x46, 0x20, 0xE5, 0xD5, 0xD3, 0x60,
0x80, 0x6D, 0x36, 0x2F, 0xB0, 0x63, 0x2F, 0x61, 0x20, 0x0F,
0xA9, 0x30
};
unsigned char output[32] = { 0 };
int i;

SM4_Decrypt(input, output, 32);

for ( i = 0; i < 32; i++ )
{
// printf("0x%X, ", output[i]);
printf("%c", output[i]);
}


return 0;
}

void SM4_Decrypt(unsigned char * input, unsigned char * output, int len)
{
int i;

for ( i = 0; i < 16; i++ )
SWAP(SK[i], SK[31 - i]);
while ( len > 0 )
{
Round(input, output);

input += 16;
output += 16;
len -= 16;
}
}

void Round(unsigned char input[16], unsigned char output[16])
{
unsigned long tmp[4] = { 0 };
int i;
unsigned int t = 0;

GET_ULONG(tmp[0], input, 0);
GET_ULONG(tmp[1], input, 4);
GET_ULONG(tmp[2], input, 8);
GET_ULONG(tmp[3], input, 12);
for ( i = 0; i < 32; i++ )
{
t = SK[i] ^ tmp[(i + 1) % 4] ^ tmp[(i + 2) % 4] ^ tmp[(i + 3) % 4];
tmp[i % 4] ^= t ^ ROTL(t, 2) ^ ROTL(t, 24) ^ ROTL(t, 10) ^ ROTL(t, 18);
}
for ( i = 0 ; i < 4; i++ )
GET_ULONG(SK[26 - i], input, i * 4); // 正好是把加密后的值放入 那么解密的时候就是把密文放入即可
PUT_ULONG(tmp[3], output, 0);
PUT_ULONG(tmp[2], output, 4);
PUT_ULONG(tmp[1], output, 8);
PUT_ULONG(tmp[0], output, 12);
}

运行得到 3b2365b04700b5eac3a5fd0ba21b687f

参考:DASCTF2022 X VOID-CEF - P.Z’s Blog (ppppz.net)

评论