NCTF2021_RE_WP

Hello せかい

记事本都能做的题.IDA打开直接看到flag

image-20211128220631446

flag为 NCTF{We1come_2_Reverse_Engineering}

Shadowbringer

base64换了2次表,调试起来找到表,逆回去即可

image-20211128223954505

image-20211129131911977

image-20211129131918276

写脚本解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import base64

flag = "U>F2UsQXN`5sXMELT=:7M_2<X]^1ThaWF0=KM?9IUhAsTM5:T==_Ns&<Vhb!"
std_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
my_table = '#$%&\x27()*+,-.s0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[h]^_`ab'
my_table2 = 'ba`_^]h[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210s.-,+*)(\x27&%$#'

flag = flag.translate(str.maketrans(my_table2, std_table))
flag = flag.replace("!", '=').encode() # "6G074JP+s)WV:Z+T<&(Q18`Ks)WV:Y4hs9[h:YCS?&0`"
flag = base64.b64decode(flag).decode()
flag = flag.translate(str.maketrans(my_table, std_table))
print(base64.b64decode(flag))

# NCTF{H0m3_r1d1n9_h0m3_dy1n9_h0p3}

flag 为 NCTF{H0m3_r1d1n9_h0m3_dy1n9_h0p3}

鲨鲨的秘密

这个题跟西湖论剑那个第一个RE题好像

image-20211128221354110

loc_404E3B为执行的指令,因为每次就33条汇编,也不长,直接调试把第一轮所有的汇编拿出来分析

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
mov     ds:dword_404E50, 0FFFFFFFFh					# dword_404E50 = -1
mov ecx, ds:I
mov dl, [ecx+4049F8h] # flag[0]
mov byte ptr ds:dword_404E4C, dl
movzx eax, byte ptr ds:dword_404E4C
xor eax, ds:dword_404E50 dword_404E4C = (flag[0] ^ 404E50 ) & 0xFF
mov byte ptr ds:dword_404E4C, al
movzx ecx, byte ptr ds:dword_404E4C
and ecx, 0FFh dword_404E50 >>= 8
mov byte ptr ds:dword_404E4C, cl
mov edx, ds:dword_404E50 dword_404E50 ^= dword_404A38[dword_404E4C * 4]
shr edx, 8
mov ds:dword_404E50, edx
movzx eax, byte ptr ds:dword_404E4C
mov ecx, ds:dword_404E50
xor ecx, ds:dword_404A38[eax*4]
mov ds:dword_404E50, ecx

mov edx, ds:I
mov al, [edx+4049F9h] # flag[1]
mov byte ptr ds:dword_404E4C, al
movzx ecx, byte ptr ds:dword_404E4C
xor ecx, ds:dword_404E50 404E4C = flag[1] ^ 404E50
mov byte ptr ds:dword_404E4C, cl
mov edx, ds:dword_404E50
shr edx, 8 dword_404E50 >>= 8
mov ds:dword_404E50, edx
movzx eax, byte ptr ds:dword_404E4C
mov ecx, ds:dword_404E50
xor ecx, ds:dword_404A38[eax*4] dword_404E50 ^= dword_404A38[dword_404E4C * 4]
mov ds:dword_404E50, ecx
mov edx, ds:dword_404E50
xor edx, 0FFFFFFFFh
mov ds:dword_404E50, edx

分析完毕,把程序中加密后的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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <stdio.h>
#include <windows.h>

unsigned char byte_404A38[] =
{
0x00, 0x00, 0x00, 0x00, 0x96, 0x30, 0x07, 0x77, 0x2C, 0x61,
0x0E, 0xEE, 0xBA, 0x51, 0x09, 0x99, 0x19, 0xC4, 0x6D, 0x07,
0x8F, 0xF4, 0x6A, 0x70, 0x35, 0xA5, 0x63, 0xE9, 0xA3, 0x95,
0x64, 0x9E, 0x32, 0x88, 0xDB, 0x0E, 0xA4, 0xB8, 0xDC, 0x79,
0x1E, 0xE9, 0xD5, 0xE0, 0x88, 0xD9, 0xD2, 0x97, 0x2B, 0x4C,
0xB6, 0x09, 0xBD, 0x7C, 0xB1, 0x7E, 0x07, 0x2D, 0xB8, 0xE7,
0x91, 0x1D, 0xBF, 0x90, 0x64, 0x10, 0xB7, 0x1D, 0xF2, 0x20,
0xB0, 0x6A, 0x48, 0x71, 0xB9, 0xF3, 0xDE, 0x41, 0xBE, 0x84,
0x7D, 0xD4, 0xDA, 0x1A, 0xEB, 0xE4, 0xDD, 0x6D, 0x51, 0xB5,
0xD4, 0xF4, 0xC7, 0x85, 0xD3, 0x83, 0x56, 0x98, 0x6C, 0x13,
0xC0, 0xA8, 0x6B, 0x64, 0x7A, 0xF9, 0x62, 0xFD, 0xEC, 0xC9,
0x65, 0x8A, 0x4F, 0x5C, 0x01, 0x14, 0xD9, 0x6C, 0x06, 0x63,
0x63, 0x3D, 0x0F, 0xFA, 0xF5, 0x0D, 0x08, 0x8D, 0xC8, 0x20,
0x6E, 0x3B, 0x5E, 0x10, 0x69, 0x4C, 0xE4, 0x41, 0x60, 0xD5,
0x72, 0x71, 0x67, 0xA2, 0xD1, 0xE4, 0x03, 0x3C, 0x47, 0xD4,
0x04, 0x4B, 0xFD, 0x85, 0x0D, 0xD2, 0x6B, 0xB5, 0x0A, 0xA5,
0xFA, 0xA8, 0xB5, 0x35, 0x6C, 0x98, 0xB2, 0x42, 0xD6, 0xC9,
0xBB, 0xDB, 0x40, 0xF9, 0xBC, 0xAC, 0xE3, 0x6C, 0xD8, 0x32,
0x75, 0x5C, 0xDF, 0x45, 0xCF, 0x0D, 0xD6, 0xDC, 0x59, 0x3D,
0xD1, 0xAB, 0xAC, 0x30, 0xD9, 0x26, 0x3A, 0x00, 0xDE, 0x51,
0x80, 0x51, 0xD7, 0xC8, 0x16, 0x61, 0xD0, 0xBF, 0xB5, 0xF4,
0xB4, 0x21, 0x23, 0xC4, 0xB3, 0x56, 0x99, 0x95, 0xBA, 0xCF,
0x0F, 0xA5, 0xBD, 0xB8, 0x9E, 0xB8, 0x02, 0x28, 0x08, 0x88,
0x05, 0x5F, 0xB2, 0xD9, 0x0C, 0xC6, 0x24, 0xE9, 0x0B, 0xB1,
0x87, 0x7C, 0x6F, 0x2F, 0x11, 0x4C, 0x68, 0x58, 0xAB, 0x1D,
0x61, 0xC1, 0x3D, 0x2D, 0x66, 0xB6, 0x90, 0x41, 0xDC, 0x76,
0x06, 0x71, 0xDB, 0x01, 0xBC, 0x20, 0xD2, 0x98, 0x2A, 0x10,
0xD5, 0xEF, 0x89, 0x85, 0xB1, 0x71, 0x1F, 0xB5, 0xB6, 0x06,
0xA5, 0xE4, 0xBF, 0x9F, 0x33, 0xD4, 0xB8, 0xE8, 0xA2, 0xC9,
0x07, 0x78, 0x34, 0xF9, 0x00, 0x0F, 0x8E, 0xA8, 0x09, 0x96,
0x18, 0x98, 0x0E, 0xE1, 0xBB, 0x0D, 0x6A, 0x7F, 0x2D, 0x3D,
0x6D, 0x08, 0x97, 0x6C, 0x64, 0x91, 0x01, 0x5C, 0x63, 0xE6,
0xF4, 0x51, 0x6B, 0x6B, 0x62, 0x61, 0x6C, 0x1C, 0xD8, 0x30,
0x65, 0x85, 0x4E, 0x00, 0x62, 0xF2, 0xED, 0x95, 0x06, 0x6C,
0x7B, 0xA5, 0x01, 0x1B, 0xC1, 0xF4, 0x08, 0x82, 0x57, 0xC4,
0x0F, 0xF5, 0xC6, 0xD9, 0xB0, 0x65, 0x50, 0xE9, 0xB7, 0x12,
0xEA, 0xB8, 0xBE, 0x8B, 0x7C, 0x88, 0xB9, 0xFC, 0xDF, 0x1D,
0xDD, 0x62, 0x49, 0x2D, 0xDA, 0x15, 0xF3, 0x7C, 0xD3, 0x8C,
0x65, 0x4C, 0xD4, 0xFB, 0x58, 0x61, 0xB2, 0x4D, 0xCE, 0x51,
0xB5, 0x3A, 0x74, 0x00, 0xBC, 0xA3, 0xE2, 0x30, 0xBB, 0xD4,
0x41, 0xA5, 0xDF, 0x4A, 0xD7, 0x95, 0xD8, 0x3D, 0x6D, 0xC4,
0xD1, 0xA4, 0xFB, 0xF4, 0xD6, 0xD3, 0x6A, 0xE9, 0x69, 0x43,
0xFC, 0xD9, 0x6E, 0x34, 0x46, 0x88, 0x67, 0xAD, 0xD0, 0xB8,
0x60, 0xDA, 0x73, 0x2D, 0x04, 0x44, 0xE5, 0x1D, 0x03, 0x33,
0x5F, 0x4C, 0x0A, 0xAA, 0xC9, 0x7C, 0x0D, 0xDD, 0x3C, 0x71,
0x05, 0x50, 0xAA, 0x41, 0x02, 0x27, 0x10, 0x10, 0x0B, 0xBE,
0x86, 0x20, 0x0C, 0xC9, 0x25, 0xB5, 0x68, 0x57, 0xB3, 0x85,
0x6F, 0x20, 0x09, 0xD4, 0x66, 0xB9, 0x9F, 0xE4, 0x61, 0xCE,
0x0E, 0xF9, 0xDE, 0x5E, 0x98, 0xC9, 0xD9, 0x29, 0x22, 0x98,
0xD0, 0xB0, 0xB4, 0xA8, 0xD7, 0xC7, 0x17, 0x3D, 0xB3, 0x59,
0x81, 0x0D, 0xB4, 0x2E, 0x3B, 0x5C, 0xBD, 0xB7, 0xAD, 0x6C,
0xBA, 0xC0, 0x20, 0x83, 0xB8, 0xED, 0xB6, 0xB3, 0xBF, 0x9A,
0x0C, 0xE2, 0xB6, 0x03, 0x9A, 0xD2, 0xB1, 0x74, 0x39, 0x47,
0xD5, 0xEA, 0xAF, 0x77, 0xD2, 0x9D, 0x15, 0x26, 0xDB, 0x04,
0x83, 0x16, 0xDC, 0x73, 0x12, 0x0B, 0x63, 0xE3, 0x84, 0x3B,
0x64, 0x94, 0x3E, 0x6A, 0x6D, 0x0D, 0xA8, 0x5A, 0x6A, 0x7A,
0x0B, 0xCF, 0x0E, 0xE4, 0x9D, 0xFF, 0x09, 0x93, 0x27, 0xAE,
0x00, 0x0A, 0xB1, 0x9E, 0x07, 0x7D, 0x44, 0x93, 0x0F, 0xF0,
0xD2, 0xA3, 0x08, 0x87, 0x68, 0xF2, 0x01, 0x1E, 0xFE, 0xC2,
0x06, 0x69, 0x5D, 0x57, 0x62, 0xF7, 0xCB, 0x67, 0x65, 0x80,
0x71, 0x36, 0x6C, 0x19, 0xE7, 0x06, 0x6B, 0x6E, 0x76, 0x1B,
0xD4, 0xFE, 0xE0, 0x2B, 0xD3, 0x89, 0x5A, 0x7A, 0xDA, 0x10,
0xCC, 0x4A, 0xDD, 0x67, 0x6F, 0xDF, 0xB9, 0xF9, 0xF9, 0xEF,
0xBE, 0x8E, 0x43, 0xBE, 0xB7, 0x17, 0xD5, 0x8E, 0xB0, 0x60,
0xE8, 0xA3, 0xD6, 0xD6, 0x7E, 0x93, 0xD1, 0xA1, 0xC4, 0xC2,
0xD8, 0x38, 0x52, 0xF2, 0xDF, 0x4F, 0xF1, 0x67, 0xBB, 0xD1,
0x67, 0x57, 0xBC, 0xA6, 0xDD, 0x06, 0xB5, 0x3F, 0x4B, 0x36,
0xB2, 0x48, 0xDA, 0x2B, 0x0D, 0xD8, 0x4C, 0x1B, 0x0A, 0xAF,
0xF6, 0x4A, 0x03, 0x36, 0x60, 0x7A, 0x04, 0x41, 0xC3, 0xEF,
0x60, 0xDF, 0x55, 0xDF, 0x67, 0xA8, 0xEF, 0x8E, 0x6E, 0x31,
0x79, 0xBE, 0x69, 0x46, 0x8C, 0xB3, 0x61, 0xCB, 0x1A, 0x83,
0x66, 0xBC, 0xA0, 0xD2, 0x6F, 0x25, 0x36, 0xE2, 0x68, 0x52,
0x95, 0x77, 0x0C, 0xCC, 0x03, 0x47, 0x0B, 0xBB, 0xB9, 0x16,
0x02, 0x22, 0x2F, 0x26, 0x05, 0x55, 0xBE, 0x3B, 0xBA, 0xC5,
0x28, 0x0B, 0xBD, 0xB2, 0x92, 0x5A, 0xB4, 0x2B, 0x04, 0x6A,
0xB3, 0x5C, 0xA7, 0xFF, 0xD7, 0xC2, 0x31, 0xCF, 0xD0, 0xB5,
0x8B, 0x9E, 0xD9, 0x2C, 0x1D, 0xAE, 0xDE, 0x5B, 0xB0, 0xC2,
0x64, 0x9B, 0x26, 0xF2, 0x63, 0xEC, 0x9C, 0xA3, 0x6A, 0x75,
0x0A, 0x93, 0x6D, 0x02, 0xA9, 0x06, 0x09, 0x9C, 0x3F, 0x36,
0x0E, 0xEB, 0x85, 0x67, 0x07, 0x72, 0x13, 0x57, 0x00, 0x05,
0x82, 0x4A, 0xBF, 0x95, 0x14, 0x7A, 0xB8, 0xE2, 0xAE, 0x2B,
0xB1, 0x7B, 0x38, 0x1B, 0xB6, 0x0C, 0x9B, 0x8E, 0xD2, 0x92,
0x0D, 0xBE, 0xD5, 0xE5, 0xB7, 0xEF, 0xDC, 0x7C, 0x21, 0xDF,
0xDB, 0x0B, 0xD4, 0xD2, 0xD3, 0x86, 0x42, 0xE2, 0xD4, 0xF1,
0xF8, 0xB3, 0xDD, 0x68, 0x6E, 0x83, 0xDA, 0x1F, 0xCD, 0x16,
0xBE, 0x81, 0x5B, 0x26, 0xB9, 0xF6, 0xE1, 0x77, 0xB0, 0x6F,
0x77, 0x47, 0xB7, 0x18, 0xE6, 0x5A, 0x08, 0x88, 0x70, 0x6A,
0x0F, 0xFF, 0xCA, 0x3B, 0x06, 0x66, 0x5C, 0x0B, 0x01, 0x11,
0xFF, 0x9E, 0x65, 0x8F, 0x69, 0xAE, 0x62, 0xF8, 0xD3, 0xFF,
0x6B, 0x61, 0x45, 0xCF, 0x6C, 0x16, 0x78, 0xE2, 0x0A, 0xA0,
0xEE, 0xD2, 0x0D, 0xD7, 0x54, 0x83, 0x04, 0x4E, 0xC2, 0xB3,
0x03, 0x39, 0x61, 0x26, 0x67, 0xA7, 0xF7, 0x16, 0x60, 0xD0,
0x4D, 0x47, 0x69, 0x49, 0xDB, 0x77, 0x6E, 0x3E, 0x4A, 0x6A,
0xD1, 0xAE, 0xDC, 0x5A, 0xD6, 0xD9, 0x66, 0x0B, 0xDF, 0x40,
0xF0, 0x3B, 0xD8, 0x37, 0x53, 0xAE, 0xBC, 0xA9, 0xC5, 0x9E,
0xBB, 0xDE, 0x7F, 0xCF, 0xB2, 0x47, 0xE9, 0xFF, 0xB5, 0x30,
0x1C, 0xF2, 0xBD, 0xBD, 0x8A, 0xC2, 0xBA, 0xCA, 0x30, 0x93,
0xB3, 0x53, 0xA6, 0xA3, 0xB4, 0x24, 0x05, 0x36, 0xD0, 0xBA,
0x93, 0x06, 0xD7, 0xCD, 0x29, 0x57, 0xDE, 0x54, 0xBF, 0x67,
0xD9, 0x23, 0x2E, 0x7A, 0x66, 0xB3, 0xB8, 0x4A, 0x61, 0xC4,
0x02, 0x1B, 0x68, 0x5D, 0x94, 0x2B, 0x6F, 0x2A, 0x37, 0xBE,
0x0B, 0xB4, 0xA1, 0x8E, 0x0C, 0xC3, 0x1B, 0xDF, 0x05, 0x5A,
0x8D, 0xEF, 0x02, 0x2D
};

unsigned char compare[] = {
0x5E, 0x60, 0xF6, 0xC0, 0x0A, 0x6E, 0xB1, 0x00, 0xD2, 0xA2,
0x19, 0x33, 0xB7, 0xB7, 0xCA, 0x57, 0x9C, 0x6D, 0x64, 0x9A,
0x26, 0x27, 0xD8, 0xBD, 0x91, 0xFB, 0x38, 0xD8, 0xB3, 0x0B,
0xE1, 0x8D, 0xAD, 0x0D, 0x6B, 0x17, 0xEF, 0xDE, 0x5F, 0x68,
0xB1, 0xF7, 0x1F, 0x2C, 0x96, 0x42, 0x44, 0x6C, 0x90, 0xFE,
0x5C, 0xA1, 0x21, 0x87, 0xCD, 0x20, 0xE8, 0x7C, 0x96, 0x62,
0xFD, 0x41, 0x16, 0x2C, 0x9A, 0x0F, 0x2D, 0x57, 0x2C, 0xDC,
0x52, 0xAE, 0xCF, 0x7D, 0x49, 0x50, 0x4A, 0xBF, 0x6A, 0xFF
};

int main() {

DWORD* dword_404A38 = (DWORD*)byte_404A38;
DWORD* dwcompare = (DWORD*)compare;
char flag[40] = {0};

for (int k = 0; k < 40; k+=2) {
for (int i = 32; i < 128; i++)
{
for (int j = 32; j < 128; j++)
{
flag[0] = i;
flag[1] = j;

DWORD dword_404E50 = 0xFFFFFFFF;
DWORD dword_404E4C = (flag[0] ^ dword_404E50) & 0xFF;
dword_404E50 >>= 8;
dword_404E50 ^= dword_404A38[dword_404E4C];

dword_404E4C = (flag[1] ^ dword_404E50) & 0Xff;
dword_404E50 >>= 8;
dword_404E50 ^= dword_404A38[dword_404E4C];
dword_404E50 = 0xFFFFFFFF - dword_404E50;


if (dword_404E50 == dwcompare[k/2])
{
printf("%c%c", i, j);
}
}
}
}

return 0;
}

flag为 NCTF{rLdE57TG0iHA39qUnFZp6LeJyYEBcxMNL7}

狗狗的秘密

image-20211128221743368

前面是47进制,直接用C语言实现上面那个框中的算法,调试,输几个数试试就能试出来了

先写脚本从下往上把47进制后的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
byte_405018 = [
0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0x65, 0xA2, 0x9B,
0xF4, 0xDF, 0xAC, 0x7C, 0xA1, 0xC6, 0x16, 0xD0, 0x0F, 0xDD,
0xDC, 0x73, 0xC5, 0x6B, 0xD1, 0x96, 0x47, 0xC2, 0x26, 0x67,
0x4E, 0x41, 0x82, 0x20, 0x56, 0x9A, 0x6E, 0x33, 0x92, 0x88,
0x29, 0xB5, 0xB4, 0x71, 0xA9, 0xCE, 0xC3, 0x34, 0x50, 0x59,
0xBF, 0x2D, 0x57, 0x22, 0xA6, 0x30, 0x04, 0xB2, 0xCD, 0x36,
0xD5, 0x68, 0x4D, 0x5B, 0x45, 0x9E, 0x85, 0xCF, 0x9D, 0xCC,
0x61, 0x78, 0x32, 0x76, 0x31, 0xE3, 0x80, 0xAD, 0x39, 0x4F,
0xFA, 0x72, 0x83, 0x4C, 0x86, 0x60, 0xB7, 0xD7, 0x63, 0x0C,
0x44, 0x35, 0xB3, 0x7B, 0x19, 0xD4, 0x69, 0x08, 0x0B, 0x1F,
0x3D, 0x11, 0x79, 0xD3, 0xEE, 0x93, 0x42, 0xDE, 0x23, 0x3B,
0x5D, 0x8D, 0xA5, 0x77, 0x5F, 0x58, 0xDB, 0x97, 0xF6, 0x7A,
0x18, 0x52, 0x15, 0x74, 0x25, 0x62, 0x2C, 0x05, 0xE8, 0x0D,
0x98, 0x2A, 0x43, 0xE2, 0xEF, 0x48, 0x87, 0x49, 0x1C, 0xCA,
0x2B, 0xA7, 0x8A, 0x09, 0x81, 0xE7, 0x53, 0xAA, 0xFF, 0x6F,
0x8E, 0x91, 0xF1, 0xF0, 0xA4, 0x46, 0x3A, 0x7D, 0x54, 0xEB,
0x2F, 0xC1, 0xC0, 0x0E, 0xBD, 0xE1, 0x6C, 0x64, 0xBE, 0xE4,
0x02, 0x3C, 0x5A, 0xA8, 0x9F, 0x37, 0xAF, 0xA0, 0x13, 0xED,
0x1B, 0xEC, 0x8B, 0x3E, 0x7E, 0x27, 0x99, 0x75, 0xAB, 0xFE,
0xD9, 0x3F, 0xF3, 0xEA, 0x70, 0xF7, 0x95, 0xBA, 0x1D, 0x40,
0xB0, 0xF9, 0xE5, 0xF8, 0x06, 0xBC, 0xB6, 0x03, 0xC9, 0x10,
0x9C, 0x2E, 0x89, 0x5C, 0x7F, 0xB1, 0x1A, 0xD6, 0x90, 0xAE,
0xDA, 0xE6, 0x5E, 0xB9, 0x84, 0xE9, 0x55, 0xBB, 0xC7, 0x0A,
0xE0, 0x66, 0xF2, 0xD8, 0xCB, 0x00, 0x12, 0xB8, 0x17, 0x94,
0x6A, 0x4A, 0x01, 0x24, 0x14, 0x51, 0x07, 0x65, 0x21, 0xC8,
0x38, 0xFD, 0x8F, 0xC4, 0xF5, 0xFC
]
byte_405118 = [
0xA7, 0x1C, 0x7E, 0xAF, 0xD9, 0xC2, 0xC0, 0xBE, 0x1F, 0x45,
0x9A, 0x85, 0x26, 0xE3, 0x87, 0xC3, 0x21, 0xE0, 0x95, 0x10,
0x71, 0x70, 0x02, 0x75, 0x35, 0xA5, 0x1D, 0x0D, 0x2F, 0xEE,
0x25, 0x7B, 0xB5, 0x82, 0x66, 0x8D, 0xDB, 0x53, 0x3A, 0x29,
0xD4, 0x43, 0x99, 0x97, 0x9D, 0xE8, 0x49, 0x00]

byte_v17 = [0x52, 0xC3, 0x1A, 0xE0, 0x16, 0x5D, 0x5E, 0xE2, 0x67, 0x1F,
0x1F, 0x06, 0x06, 0x1F, 0x17, 0x06, 0x0F, 0xF9, 0x06, 0x67,
0x58, 0xB2, 0xE2, 0x8C, 0x0F, 0x2A, 0x06, 0x89, 0xCF, 0x2A,
0x06, 0x1F, 0x98, 0x1A, 0x3E, 0x17, 0x67, 0x1F, 0xF7, 0x3A,
0x44, 0xC3, 0x16, 0x33, 0x69, 0x1A, 0x75, 0x16, 0x3E, 0x17,
0xD5, 0x69, 0x7A, 0x1B, 0x44, 0x44, 0x3E, 0x67, 0xF7, 0x89,
0x67]
v11 = []


for v17 in byte_v17:
for i in range(256):
c = byte_405018[i] ^ i
if c == v17:
# print(hex(i))
if i in byte_405118:
print(byte_405118.index(i), end=" ")
print("")

索引为

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
2     
0
33 45
44
30
40
8
23
22 11 7
37 34
37 34
19 20 43
19 20 43
37 34
24
19 20 43
31 4
29
19 20 43
22 11 7
13
5
23
41
31 4
35
19 20 43
9
14
35
19 20 43
37 34
3
33 45
10
24
22 11 7
37 34
38
1
25
0
30
6
42
33 45
36
30
10
24
21
42
26
28
25
25
10
22 11 7
38
9
22 11 7

然后写脚本,从一头开始试,因为如果一头稍微一改,打印的字符串前面变化很大的话,说明改对了,因为数据高位一改,整个数字变化才大,然后long_to_bytes后对应的字符也变换很大了,如果从低位改,数据变化不大,long_to_bytes后头部的字符变化也不大了, 就这样一点点改,flag就一点点的显示出来了

可能描述的有点抽象,举个例子就很容易懂了

image-20211129132600731

对应的解密脚本

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
from Crypto.Util.number import *
compare = [2,
0,
45,
44,
30,
40,
8,
23,
11,
37,
34,
43,
43,
37,
24,
19,
4,
29,
19, # 19 20 43
22, # 22 11 7
13,
5,
23,
41,
4, # 31 4
35,
20, # 19 20 43
9,
14,
35,
43, # 19 20 43
37, # 37 34
3,
33, # 33 45
10,
24,
22, # 22 11 7
37, # 37 34
38,
1,
25,
0,
30,
6,
42,
45, # 33 45
36,
30,
10,
24,
21,
42,
26,
28,
25,
25,
10,
7,
38,
9,
11]

sum = 0
re_compare = compare[::-1]
for i in range(len(compare)):
tmp = re_compare[i] * pow(47, i)
sum += tmp

print(long_to_bytes(sum))
# NCTF{ADF0E239-D911-3781-7E40-A575A19E5835}

flag为 NCTF{ADF0E239-D911-3781-7E40-A575A19E5835}

easy_mobile

JEB打开分析

image-20211129133043672

发现check_flag 的算法在对应的so文件里

image-20211129133838003

IDA打开找到 Java_com_example_rectf_MainActivity_checkflag 函数

image-20211129133146870

哇塞,看这优美的图形,是OLLVM,从网上找来各种脚本平坦化,要么是失败,要么是去了还不如不去容易看

我一共试了这2个脚本

https://github.com/cq674350529/deflat (成功去除,基址设置为0X400000,比如check_flag是0X7900,然后 就运行

python deflat.py -f libnative-lib.so --addr 0x407900,但是去了后我感觉更难看了)

https://github.com/pcy190/deobfuscator (这个我去除失败,可能是qiling版本的问题)

好吧,直接硬刚OLLVM,真机调试

如何搭建真机调试环境可以参考我写的这篇文章

https://zzzzsky.com/2021/11/29/IDA%E7%9C%9F%E6%9C%BA%E8%B0%83%E8%AF%95%E5%AE%89%E5%8D%93so%E6%96%87%E4%BB%B6/

image-20211129134112254

在下面每个框中第一条指令下断点,尤其是这种大的块肯定是有用的,先审视一下这种大的块

image-20211129134233317

发现在这个位置调用了strlen,然后与0X18对比 猜测是验证flag的长度,继续审视其他块

image-20211129134438579

在这个位置发现了一些类似密钥的字符串,还调用了一个函数,进入这个 sub_7D30F1E260 函数

image-20211129134631372

根据<< 4 >>5 0X12345678等特征,发现这是一种个TEA算法,delta改为了0X12345678

继续审视,在这个位置发现了一些明文

image-20211129134810778

F5,发现这里还有一些加减乘除的一些操作

image-20211129135242278

开始调试,直接在上面对应的位置下断点,flag先输入12345试试,一点点来到strlen的位置,发现果然是验证flag的长度

image-20211129135058075

继续F9,发现即没有到达加减乘除那个块,也没有到达TEA算法那里就显示NO了,我么输入flag为 123456789012345678901234

image-20211129135555940

好,程序断在了加减乘除那个块那里,直接一点点单步调试

image-20211129140054267

在mul之前停下,观察寄存器,发现X1指向的是最后8个字符,然后来到X16寄存器指向的内存位置,稍微整理整理

image-20211129140156055

发现系统初始化了16个字符 PRST0123789: "#$ ,然后下面紧跟着flag 的前16位,猜测flag是分开验证的16 + 8

跳过乘法,再看内存

image-20211129140515888

最终调试到memcpy的位置

image-20211129140714060

dword_7CD3B3E14C 处的数据为

image-20211129140754349

而刚才0007FD020C630处的数据已经变为了

image-20211129141049519

于是猜测是flag的前16位根据PRST0123789: "#$ 加减乘除后 与dword_7CD3B3E14C进行对比,然后flag 的后8位是那个tea算法

这里一点点调试,发现

1
2
3
4
['3', '4', '5', '6'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] = [1687, 1824, 1912, 2002]
['9', '0', '1', '2'] * ['0', '1', '2', '3'] + ['P', 'R', 'S', 'T'] = [2816, 2434, 2533, 2634]
['5', '6', '7', '8'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] = [1751, 1892, 1982, 2074]
['1', '2', '3', '4'] * [' ', '"', '#', '$'] + ['7', '8', '9', ':'] = [1623, 1756, 1842, 1930]

写脚本解密得到flag的前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
a = [3287, 1688, 3452, 1786,    
3255, 1994, 1947, 2002,
2384, 2777, 2783, 5286,
3319, 1824, 1842, 2038]


mul1 = [ord(i) for i in "0123"]

mul2 = [ord(i) for i in ' "#$']

add1 = [ord(i) for i in "PRST"]

add2 = [ord(i) for i in "789:"]

flag = []

flag1 = [(a[:4][i]-add2[i])/mul2[i] for i in range(4)]
flag2 = [(a[4:8][i]-add2[i])/mul2[i] for i in range(4)]
flag3 = [(a[8:12][i]-add1[i])/mul1[i] for i in range(4)]
flag4 = [(a[12:][i]-add2[i])/mul2[i] for i in range(4)]

print(flag1)
print(flag2)
print(flag3)
print(flag4)

flag = flag1 + flag2 + flag3 + flag4
flag = [chr(int(i)) for i in flag]
print("".join(flag))
# [101.0, 48.0, 97.0, 48.0]
# [100.0, 57.0, 54.0, 54.0]
# [48.0, 55.0, 54.0, 102.0]
# [102.0, 52.0, 51.0, 55.0]
# e0a0d966076ff437

然后flag输入e0a0d966076ff437ABCD1234重新调试,果然程序断在了TEA算法的位置

image-20211129142112345

image-20211129142119304

发现果然是对flag的后8个字符进行TEA加密,直接运行到加密完成

image-20211129142238913

然后进入汇编界面单步调试,注意CMP指令

image-20211129142317313

可以发现V0加密后应改为0XC65AEDA, 这里修改X13的值为0XC65AEDA,使其验证通过,然后再单步

image-20211129142540130

运行到这个位置,发现V1加密后的数据为 0xADBF8DB1

直接写脚本解密

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
#include <stdio.h>  
#include <stdint.h>

//加密函数
void encrypt(uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0, i;
uint32_t delta = 0x12345678;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++) {
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
}
v[0] = v0; v[1] = v1;
}
//解密函数
void decrypt(uint32_t* v, uint32_t* k) {
uint32_t delta = 0x12345678;
uint32_t v0 = v[0], v1 = v[1], sum = delta * 32, i;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
}
v[0] = v0; v[1] = v1;
}


unsigned char byte_key[] =
{
0x71, 0x69, 0x68, 0x61, 0x68, 0x61, 0x69, 0x6E, 0x69, 0x6E,
0x61, 0x6E, 0x61, 0x6E, 0x61, 0x6D
};

//char enc[] = { 'A', 'B', 'C', 'D', '1', '2', '3', '4' };
int main()
{
//uint32_t* v = (uint32_t*)enc;
uint32_t v[2] = { 0x000000000C65AEDA , 0x00000000ADBF8DB1 };
uint32_t* k = (uint32_t*)byte_key;
decrypt(v, k);
printf("解密后的数据:%u %u\n", v[0], v[1]);
return 0;
}

image-20211128222743505

后8位是 58af2715

拼凑得到 flag e0a0d966076ff43758af2715

1

验证成功


纪念AK RE, 拿了3一血,美滋滋

image-20211129143017613

zuizhongpaiming

继续加油~~

题目附件

链接:https://pan.baidu.com/s/1FaBD6_FDjKLziKpVqvGe-Q
提取码:ptjq