-
-
[原创]KCTF2022春季赛第三题:解题过程
-
发表于: 2022-5-16 00:19 7420
-
1.初步流程分析
题目流程比较简洁,初步判断该exe定义了一个大的结构体进行操作,简单根据偏移量进行了结构体判断。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
struct context{ int iterator1; / / 0
int unknow1; / / 1
unsigned int md5[ 5 ]; / / 2 - 6
int unknow7; / / 7
int unknow8; / / 8
byte keys[ 16 ]; / / 9 - 12
int unknow13; / / 13
int unknow14; / / 14
int unknow15; / / 15
int iterator2; / / 16
int unknow17; / / 17
unsigned int cipher[ 10 ]; / / 18 - 27
int unknow28; / / 28
int unknow29; / / 29
char sn[ 4000 ];
int a3;
int a4;
}; |
重新对main进行解析,比较友好了。
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
|
int __cdecl main_0( int argc, const char * * argv, const char * * envp)
{ void * v3; / / esp
int result; / / eax
char v7; / / [esp - 10h ] [ebp - 1048h ]
context ctx; / / [esp + 0h ] [ebp - 1038h ] BYREF
CPPEH_RECORD ms_exc; / / [esp + 1020h ] [ebp - 18h ]
v3 = alloca( 4128 );
memset(&ctx, 0xCCu , sizeof(ctx));
ms_exc.registration.ScopeTable = (ms_exc.registration.ScopeTable ^ __security_cookie);
memset(ctx.sn, 0 , sizeof(ctx.sn));
ctx.cipher[ 0 ] = 0 ;
ctx.cipher[ 1 ] = 0 ;
ctx.cipher[ 2 ] = 0 ;
ctx.cipher[ 3 ] = 0 ;
ctx.cipher[ 4 ] = 0 ;
ctx.cipher[ 5 ] = 0 ;
ctx.cipher[ 6 ] = 0 ;
ctx.cipher[ 7 ] = 0 ;
ctx.cipher[ 8 ] = 0 ;
ctx.cipher[ 9 ] = 0 ;
gets_s(ctx.sn, 4000u );
if ( strlen(ctx.sn) = = 32 )
{
for ( ctx.iterator2 = 0 ; ctx.iterator2 < 512 ; + + ctx.iterator2 )
{
ctx.unknow15 = 0 ;
MEMORY[ 0 ] = ctx.iterator2;
ms_exc.registration.TryLevel = 0xFFFFFFFE ;
}
strcpy(ctx.keys, "Enj0y_1t_4_fuuuN" ); / / 16bytes
_DX = 0x5F00 ;
* (&ctx.unknow13 + 1 ) = 0 ;
HIBYTE(ctx.unknow13) = 0 ;
ctx.md5[ 0 ] = 0 ;
ctx.md5[ 1 ] = 0 ;
ctx.md5[ 2 ] = 0 ;
ctx.md5[ 3 ] = 0 ;
ctx.md5[ 4 ] = 0 ;
for ( ctx.iterator1 = 0 ; ctx.iterator1 < 512 ; + + ctx.iterator1 )
{
__asm { insb }
ms_exc.registration.TryLevel = - 2 ;
_DX = LOWORD(ctx.iterator1) + 1 ;
}
j_MD5_402DB0(ctx.keys, 0x10u , ctx.md5);
j_aes_402070(ctx.md5, 0x10u , ctx.sn, ctx.cipher, 32 );
if ( !memcmp(ctx.cipher, byte_40B200, 0x20u ) )
printf_401037( "OK\n" , v7);
else
printf_401037( "NO\n" , v7);
result = 0 ;
}
else
{
printf_401037( "NO\n" , v7);
result = 0 ;
}
return result;
} |
存在较多的反调试。
流程较为清晰:
1、keys = MD5(Enj0y_1t_4_fuuuN)
2、AES(keys , 16bytes , plain , cipher , 32bytes) == byte_40B200[0:20]
直接进行解密计算发现是乱码,判断算法进行了改变。
2.算法分析
2.1 MD5分析
直接使用MD5(Enj0y_1t_4_fuuuN)结果。并未具体分析过程,因为是固定值。
2.2 AES分析
整个AES算法结构比较标准,在正常的128bit密钥流程中增加了对16字节输入输出的转置操作。
需要找一份类似的代码实现。
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
|
int __cdecl aes_402070(void * Src, size_t KeySize, unsigned __int8 input [], unsigned __int8 uccipher[], int iLen)
{ int j; / / [esp + 4h ] [ebp - 1C8h ]
unsigned int i; / / [esp + 8h ] [ebp - 1C4h ]
int state[ 6 ]; / / [esp + 10h ] [ebp - 1BCh ] BYREF
int key[ 11 ]; / / [esp + 28h ] [ebp - 1A4h ] BYREF
unsigned int * iKeyOffset; / / [esp + 54h ] [ebp - 178h ]
unsigned __int8 * __attribute__((__org_arrdim( 0 , 0 ))) output; / / [esp + 58h ] [ebp - 174h ]
unsigned int KeyExtend[ 90 ]; / / [esp + 60h ] [ebp - 16Ch ] BYREF
output = uccipher;
iKeyOffset = KeyExtend;
key[ 6 ] = 0 ;
key[ 7 ] = 0 ;
key[ 8 ] = 0 ;
key[ 9 ] = 0 ;
key[ 0 ] = 0 ;
key[ 1 ] = 0 ;
key[ 2 ] = 0 ;
key[ 3 ] = 0 ;
state[ 0 ] = 0 ;
state[ 1 ] = 0 ;
state[ 2 ] = 0 ;
state[ 3 ] = 0 ;
if ( !Src || ! input || !uccipher )
return - 1 ;
if ( KeySize > 0x10 )
return - 1 ;
if ( iLen % 0x10u )
return - 1 ;
memcpy(key, Src, KeySize);
KeyExtend_4010BE(key, 16 , KeyExtend);
for ( i = 0 ; i < iLen; i + = 16 )
{
input_transpose_401145(state, input );
AddRoundKey_401186(state, iKeyOffset);
for ( j = 1 ; j < 10 ; + + j )
{
iKeyOffset + = 4 ;
ByteSub_401172(state);
ShiftRow_40122B(state);
MixColumn_40100F(state);
AddRoundKey_401186(state, iKeyOffset);
}
ByteSub_401172(state);
ShiftRow_40122B(state);
AddRoundKey_401186(state, iKeyOffset + 4 );
output_transpose_40125D(state, output);
output + = 16 ;
input + = 16 ;
iKeyOffset = KeyExtend;
}
return 0 ;
} |
2.2.1 KeyExtend_4010BE
密钥扩展函数正常。
2.2.2 ByteSub_401172
[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!
最后于 2022-5-16 20:49
被kanxue编辑
,原因:
赞赏记录
参与人
雪币
留言
时间
東陽不列山
为你点赞!
2024-12-13 03:13
伟叔叔
为你点赞~
2023-3-18 02:28
PLEBFE
为你点赞~
2022-7-27 23:32
赞赏
他的文章
- [原创]第七题解题 4470
- [原创]KCTF2022春季赛第三题 解题过程 7750
- [原创]KCTF2022春季赛第三题:解题过程 7421
- [原创]KCTF2022春季赛第二题 解题过程 7517
赞赏
雪币:
留言: