2024 古剑山网络安全大赛 Reverse 方向
carbofish

台州市赛 Reverse 方向

ipa

一血嘻嘻

IMG_20241203_190222

IOS 逆向,直接用 ida 打开分析 里面的 EasyIOS

img

在程序段下有三个初始化程序,里面把 密文、RC4 的 key、还有 base64 的表都给修改了

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
double InitFunc_0()
{
__int64 v0; // x8
unsigned int v1; // w9
int v2; // w13
int v3; // w9
int v4; // w14
__int64 i; // x9
double result; // d0
__int128 v7[2]; // [xsp+0h] [xbp-90h]
__int128 v8; // [xsp+20h] [xbp-70h]
__int128 v9; // [xsp+30h] [xbp-60h]

v0 = 0LL;
v1 = 0;

unsigned char v10[64] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
};

do
{
v2 = v10[v0];
v3 = v1 + v2 + byte_100007F00[(unsigned __int8)v0 % 5u];
v4 = v3 + 63;
if ( v3 >= 0 )
v4 = v3;
v1 = v3 - (v4 & 0xFFFFFFC0);
v10[v0] = v10[v1];
v10[v1] = v2;
++v0;
}
while ( v0 != 64 );

for (int j = 0; j < 64; ++j) {
printf("%c", aAbcdefghijklmn[v10[j]]);
}

return result;
}

可以得到码表 NF01ihUKST9q3lnjEBs47k2w5ad+AVHfPezg/CDyxrMLR6GvomIQJOXcpW8ZbutY

image-20241130131323764 image-20241130131330625

得到 base 后的密文 bExa9y+XlAbleJPlBJy5r0AFPeJQKEODCQ6D23jOpR+X
接下来写一下脚本就行了

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
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "defs.h"


uint8 sbox[250] = {0};

//初始化s表
void init_sbox(char *key, int klen) {
uint64 i, k;
int64 tmp;

for (i = 0; i < 250; i++) {
sbox[i] = i;
}

uint64 j = 0;
for (i = 0; i < 250; i++) {
tmp = (uint8) sbox[i];
int64 v13 = j + tmp;
char keyVal = key[i % klen];
int bitFlag = keyVal & 0x80;
uint64 covertVal = 0;
if (bitFlag) {
// 负数
covertVal = 0xFFFFFFFFFFFFFF00 | keyVal;
} else {
covertVal = keyVal;
}
j = (v13 + covertVal) % 250;
sbox[i] = sbox[j];
sbox[j] = tmp;
}
}

//加解密函数
void enc_dec(char *key, unsigned char *data, int slen, int klen) {
int i, j, k, R, tmp;

init_sbox(key, klen);

// for (int l = 0; l < 250; ++l) {
// printf("0x%x, ", (uint8) sbox[l]);
// }

j = k = 0;
for (i = 0; i < slen; i++) {
j = (j + 1) % 250;
k = (k + sbox[j]) % 250;

tmp = sbox[j];
sbox[j] = sbox[k];
sbox[k] = tmp;

R = sbox[(sbox[j] + sbox[k]) % 250];

data[i] ^= R;
}
}

int main() {
unsigned char key[13] = {0xF6, 0xCC, 0xC8, 0xD5, 0xC9, 0xC0, 0xEE, 0xC0, 0xDC, 0xED, 0xC0, 0xD7, 0xC0};
unsigned char data[33] = {0xf1,0x0a,0x19,0x2a,0x76,0xf6,0x35,0xcf,0x0d,0x87,0x48,0x0d,0x47,0x49,0xd8,0xa4,0x27,0x01,0x82,0x1d,0x33,0x1d,0x0d,0x66,0x97,0x3b,0x66,0x58,0xc3,0xf5,0xe2,0xc6,0xf6};

enc_dec((char *)key, data, 33, 13);

for (int i = 0; i < 33; ++i) {
printf("%c", data[i]);
}

return 0;
}
// flag{45_4_105_r3v3r51n6_b361nn3r}

这里有个问题就是这道题中的 RC4 在取 key 的时候用的是有符号字节拓展(LDRSB 指令),原本如果取模模的是 256 也就是 0xFF 那倒是不会出啥问题,但是这里模的是 250,就会导致出一点问题,得 key[i % klen] 取出来后强转成 int64 再加回去

585fe3f01e25c571a06e342f60dc7a03

ez_re

发现有个壳,用 x32dbg 调试,下断点在 VirtualProtect 运行几次然后单步走两下断在程序段

image-20241130130834259

然后用 Scylla dump fix,拉进 ida 分析
手动重命名一下函数后发现,就是一个替换

image-20241130130930855

image-20241130130954720

直接把伪C拉下来,改一下判断,加上打印就可以得到 Flag

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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defs.h"

unsigned char key_table[10] = {
0x7B, 0x64, 0x65, 0x32, 0x31, 0x63, 0x7A, 0x34, 0x79, 0x00
};

BOOL __fastcall sub_3B1150(char *v5_cp, char *v4_cp)
{
char *v2; // edi
int v4; // esi
char v5; // al
int v6; // esi
int v7; // ecx
char v8; // dl
char v9; // al
int v10; // edx
char v11; // cl
char v12; // al

v2 = v4_cp + 24; // flag开头
v4 = 0;
while ( 1 )
{
v5 = *v2++;
printf("%c", v5);
if ( ++v4 >= 4 )
{
v6 = 4;
v7 = 0;
while ( 1 )
{
v8 = key_table[v7];
if ( v8 == 121 )
{
key_table[v7] = 55;
v8 = 55;
}
if ( v8 == 122 )
{
key_table[v7] = 56;
v8 = 56;
}
v6++;
printf("%c", v8);
if ( ++v7 >= 9 )
{
v10 = 0;
while ( 1 )
{
v11 = v4_cp[v10];
if ( v11 == 121 )
{
v4_cp[v10] = 55;
v11 = 55;
}
if ( v11 == 122 )
{
v4_cp[v10] = 56;
v11 = 56;
}
v6++;
printf("%c", v11);
if ( ++v10 >= 24 ) {
printf("}");
return 1;
}
}
}
}
}
}
}

int main() {
char pt[] = "cedfz16az31zd2dycy65ac41flag";
sub_3B1150(pt, pt);

return 0;
}

// flag{de21c847cedf816a8318d2d7c765ac41}
 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
总字数 54k 访客数 访问量