0%

上海省赛/陕西省赛初赛

2023上海省赛:

好久没写wp了,重新使用一下博客吧,re不难,但时间不是很够

REVERSE

flag在哪?

通过搜索字符串和交叉引用,找到加密处:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int sub_401670()
{
char v0; // cl
int v2; // [esp+0h] [ebp-44h] BYREF
char v3[4]; // [esp+20h] [ebp-24h] BYREF
int v4; // [esp+40h] [ebp-4h]

sub_401780();
sub_4026A0(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
__scrt_stub_for_initialize_mta();
sub_4017B0(v3);
sub_401840((char)&v2);
v4 = sub_402770(&v2, v3);
return sub_4018A0(v0, v4);
}
1
2
3
4
5
6
7
8
9
10
int __cdecl sub_402770(int a1, int a2)
{
int v2; // ecx
int v4; // [esp+0h] [ebp-4h]

sub_401C40(v2);
v4 = ((int (__cdecl *)(int, int))Block)(a1, a2);
free(Block);
return v4;
}

该函数是加密函数,但是需要smc一下

把这个地方的call nop掉可以看到函数

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
char *__cdecl sub_5040A0(int a1, int a2)
{
char v3[4132]; // [esp+0h] [ebp-1254h] BYREF
char v4[256]; // [esp+1024h] [ebp-230h] BYREF
char v5[256]; // [esp+1124h] [ebp-130h] BYREF
int v6; // [esp+1224h] [ebp-30h]
int v7; // [esp+1228h] [ebp-2Ch]
char *v8; // [esp+122Ch] [ebp-28h]
char *v9; // [esp+1230h] [ebp-24h]
char *v10; // [esp+1234h] [ebp-20h]
char *v11; // [esp+1238h] [ebp-1Ch]
void *v12; // [esp+123Ch] [ebp-18h]
int v13; // [esp+1240h] [ebp-14h]
int v14; // [esp+1244h] [ebp-10h]
int (__cdecl *v15)(int); // [esp+1248h] [ebp-Ch]
int j; // [esp+124Ch] [ebp-8h]
int i; // [esp+1250h] [ebp-4h]

v15 = dword_4062B4;
v7 = dword_406448;
v6 = dword_40644C;
v14 = dword_4062B4(a1);
v13 = v15(a2);
for ( i = 0; i < v14; ++i )
{
v5[i] = *(_BYTE *)(i + a1) ^ 4;
if ( i % 3 == 1 )
v5[i] ^= byte_406000[3 * i];
}
v5[v14] = 0;
for ( j = 0; j < v13; ++j )
{
v4[j] = *(_BYTE *)(j + a2) ^ 6;
if ( j % 2 == 1 )
v4[j] = *(_BYTE *)(j + a2 + 7);
}
v4[v13] = 0;
v12 = v3;
dword_406458(v3, sub_401AC0, 4132);
v9 = v3;
v10 = v5;
v11 = v4;
v8 = v3;
return v3;
}

对flag进行加密,key的加密是动调获取,再看被nop掉的函数

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
int __cdecl sub_19EC64(char *Str, char *a2)
{
char v3[80]; // [esp+0h] [ebp-78h]
int v4; // [esp+50h] [ebp-28h]
int v5; // [esp+54h] [ebp-24h]
unsigned int v6; // [esp+58h] [ebp-20h]
int v7; // [esp+5Ch] [ebp-1Ch]
int v8; // [esp+60h] [ebp-18h]
unsigned int v9; // [esp+64h] [ebp-14h]
unsigned int v10; // [esp+68h] [ebp-10h]
unsigned int v11; // [esp+6Ch] [ebp-Ch]
int v12; // [esp+70h] [ebp-8h]
unsigned int i; // [esp+74h] [ebp-4h]

v10 = dword_4062B4(Str);
v6 = dword_4062B4(a2);
dword_4062B4(byte_406274);
v12 = 15;
v11 = 15 - v10;
if ( v10 != 15 )
return v11;
for ( i = 0; i < v10; ++i )
{
v4 = 0;
v9 = i % 3;
v7 = dword_406450(i % 3);
v5 = (v7 + 2) ^ Str[i];
v8 = a2[i];
if ( i >= v6 )
v8 = 0;
v3[i] = v8 + v5;
if ( v3[i] != byte_406274[i] )
return i + 1;
}
return 0;
}

很轻松的用爆破解决问题:下面是脚本:

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
flag = "111111111111111"
a = [0] * len(flag)
che = [0x66, 0x6C, 0x61, 0x67, 0x7B, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x74, 0x6F, 0x6D, 0x7D, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x4D, 0x79, 0x20, 0x63, 0x68, 0x65, 0x65, 0x73, 0x65, 0x7D, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x69, 0x20, 0x6D, 0x69, 0x73, 0x73, 0x20, 0x74, 0x6F, 0x6D, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x6C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x66, 0x75, 0x6E, 0x7D, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x75, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x73, 0x74, 0x65, 0x61, 0x6C, 0x20, 0x6D, 0x79, 0x20, 0x63, 0x68, 0x65, 0x65, 0x73, 0x65, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x69, 0x20, 0x68, 0x61, 0x76, 0x65, 0x64, 0x20, 0x6C, 0x6F, 0x73, 0x74, 0x20, 0x61, 0x20, 0x63, 0x68, 0x65, 0x65, 0x73, 0x65, 0x7D, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x63, 0x68, 0x65, 0x65, 0x73, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6D, 0x79, 0x20, 0x6C, 0x69, 0x66, 0x65, 0x7D, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x69, 0x64, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6B, 0x66, 0x61, 0x73, 0x74, 0x7D, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x6C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x64, 0x61, 0x6E, 0x63, 0x69, 0x6E, 0x67, 0x7D, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x63, 0x61, 0x6E, 0x20, 0x75, 0x20, 0x70, 0x6C, 0x61, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x61, 0x6E, 0x6F, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x6D, 0x65, 0x7D, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x69, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x20, 0x64, 0x72, 0x65, 0x61, 0x6D, 0x7D, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x69, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x67, 0x6F, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x50, 0x6F, 0x6C, 0x65, 0x7D, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x6C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x66, 0x69, 0x67, 0x68, 0x74, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x69, 0x27, 0x6D, 0x20, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x6E, 0x20, 0x61, 0x6E, 0x74, 0x69, 0x2D, 0x48, 0x75, 0x6C, 0x6B, 0x20, 0x61, 0x72, 0x6D, 0x6F, 0x72, 0x20, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x69, 0x20, 0x6B, 0x6E, 0x65, 0x77, 0x20, 0x74, 0x6F, 0x6D, 0x20, 0x77, 0x61, 0x73, 0x20, 0x67, 0x6F, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x6F, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x6D, 0x65, 0x20, 0x74, 0x6F, 0x6E, 0x69, 0x67, 0x68, 0x74, 0x7D, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x69, 0x27, 0x76, 0x65, 0x20, 0x61, 0x6C, 0x72, 0x65, 0x61, 0x64, 0x79, 0x20, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x64, 0x6F, 0x7D, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x6E, 0x6F, 0x74, 0x20, 0x64, 0x72, 0x75, 0x6E, 0x6B, 0x20, 0x6E, 0x6F, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x7D, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x6F, 0x68, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x6F, 0x68, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x69, 0x20, 0x62, 0x65, 0x74, 0x20, 0x69, 0x74, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x72, 0x61, 0x69, 0x6E, 0x20, 0x74, 0x6F, 0x6D, 0x6F, 0x72, 0x72, 0x6F, 0x77, 0x7D, 0x00, 0x00, 0x00, 0x66, 0x6C, 0x61, 0x67, 0x7B, 0x74, 0x6F, 0x6D, 0x20, 0x74, 0x6F, 0x6C, 0x64, 0x20, 0x6D, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6C, 0x6C, 0x79, 0x20, 0x61, 0x20, 0x74, 0x69, 0x67, 0x65, 0x72, 0x7D]
for i in range(len(flag)):
a[i] = ord(flag[i]) ^ 0x4
if i % 3 == 1:
a[i] ^= che[i * 3]
b = "e4bdtRV02"
a1 = a #key
a2 = b #flag
v3 = [0] * 15
cmp = [0xD3, 0x38, 0xD1, 0xD3, 0x7B, 0xAD, 0xB3, 0x66, 0x71, 0x3A, 0x59, 0x5F, 0x5F, 0x2D, 0x73]
cmp2 = [ 0x3A, 0x59, 0x5F, 0x5F, 0x2D, 0x73]
flag1 = ""
for i in range(15):
for j in range(0,0xff):
if i % 3 == 0:
v7 = 10
elif i%3 == 1:
v7 = 9
elif i %3 == 2:
v7 = 8
v5 = (v7 + 2) ^ j
if i >= len(b):
v8 = 0
else:
v8 = ord(b[i])
v3[i] = v8 + v5
if cmp[i] == v3[i]:
print(j)
for i in range(len(v3)):
print(hex(v3[i]),end = ",")
flag1 = ""
x = [98,
15,
101,
99,
12,
81,
81,
61,
53,
54,
82,
85,
83,
38,
121]
for i in range(len(x)):
for j in range(27,127):
vv = j ^ 0x4
if i % 3 == 1:
vv ^= che[i * 3]
if vv == x[i]:
flag1 += chr(j)
print(flag1)
#flag{UUU123QWE}

ezEXE

主要加密在:

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
int __cdecl sub_40179A(char *a1)
{
char v2[117]; // [esp+2Ah] [ebp-9Eh] BYREF
char Str[17]; // [esp+9Fh] [ebp-29h] BYREF
int v4; // [esp+B0h] [ebp-18h]
size_t v5; // [esp+B4h] [ebp-14h]
size_t v6; // [esp+B8h] [ebp-10h]
size_t i; // [esp+BCh] [ebp-Ch]

strcpy(Str, "VrDQ-ffgaEig04qx");
v6 = strlen(Str);
v5 = strlen(a1);
strcpy(v2, "RQpxxZgUqxzwonBuDApb3PyRJ8CcLIyXVozsVjurmPQdUdND+cly4HFq");
sub_4016EB(lpAddress, 494, 5);
((void (__cdecl *)(char *, size_t, char *, size_t, char *))lpAddress)(Str, v6, a1, v5, &v2[57]);
v4 = sub_401535(&v2[57], v5 + 1);
for ( i = 0; i < strlen(v2); ++i )
{
if ( *(_BYTE *)(i + v4) != v2[i] )
{
printf(&Format);
return 0;
}
}
printf(&byte_404005);
return 0;
}

又是smc,tls里有反调试,可以用set ip跳过,找到smc的加密。发现是rc4,所以加密就是rc4+base64

1
2
3
4
5
6
7
8
9
10
import base64
base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
diy_base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
s = 'RQpxxZgUqxzwonBuDApb3PyRJ8CcLIyXVozsVjurmPQdUdND+cly4HFq=='
ss = ''
for i in range(len(s)-2):
ss += base[diy_base.find(s[i])]
ss += '=='
a = base64.b64decode(ss)
print(list(map(hex,a)))
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
import base64
def rc4_main(key = "init_key", message = "init_message"):
print("RC4解密主函数调用成功")
print('\n')
s_box = rc4_init_sbox(key)
crypt = rc4_excrypt(message, s_box)
return crypt
def rc4_init_sbox(key):
s_box = list(range(256))
print("原来的 s 盒:%s" % s_box)
print('\n')
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
print("混乱后的 s 盒:%s"% s_box)
print('\n')
return s_box
def rc4_excrypt(plain, box):
print("调用解密程序成功。")
print('\n')
plain = base64.b64decode(plain.encode('utf-8'))
plain = bytes.decode(plain)
res = []
i = j = 0
for s in plain:
i = (i + 1) % 256
j = (j + box[i]) % 256
box[i], box[j] = box[j], box[i]
t = (box[i] + box[j]) % 256
k = box[t]
res.append(chr(ord(s) ^ k))
print("res用于解密字符串,解密后是:%res" %res)
print('\n')
cipher = "".join(res)
print("解密后的字符串是:%s" %cipher)
print('\n')
print("解密后的输出(没经过任何编码):")
print('\n')
return cipher
a=[0x45,0xa,0x71,0xc5,0x98,0x14,0xab,0x1c,0xf0,0xa2,0x70,0x6e,0xc,0xa,0x5b,0xdc,0xfc,0x91,0x27,0xc0,0x9c,0x2c,0x8c,0x97,0x56,0x8c,0xec,0x56,0x3b,0xab,0x98,0xf4,0x1d,0x51,0xd3,0x43,0xf9,0xc9,0x72,0xe0,0x71,0x6a] #cipher
key="VrDQ-ffgaEig04qx"
s=""
for i in a:
s+=chr(i)
s=str(base64.b64encode(s.encode('utf-8')), 'utf-8')
rc4_main(key, s)

得到flag:flag{e0f18a30-d573-41d6-a1fb-f4691a82f701}

encrytor

加密是这样的逻辑,先随机生成4个字节/3个字节或者2个字节的数,然后sha256加密,然后是进行对sbox的初始化,然后是对flag进行加密,用的是sbox来异或。

下面是正向加密:

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
import hashlib

def change(hex_string):
int_array = [int(hex_string[i:i+2], 16) for i in range(0, len(hex_string), 2)]
return int_array

def sbox_init(h):
a = [0x00, 0x00,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, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF]
v7 = 0
v6 = 0
sha = change(h)
for i in range(256):
v9 = v7 + 1
v10 = a[v7 + 2]
v11 = v10 + v6
if(0x20 | v7) >> 32:
v8 = v7 % 0x20
else:
v8 = v7 % 0x20
v6 = (sha[v8] + v11) & 0xff
a[v7 + 2] = a[v6 + 2]
a[v6 + 2] = v10
v7 += 1
return a

def encode1(xbox):
v5 = 0
v6 = 1
flag = "111111111111111111111111111111111111111"
cmp = [255, 75, 90, 35, 133, 90, 109, 11, 11, 117, 67, 48, 107, 163, 38, 179, 27, 57, 109, 104, 200, 234, 116, 204, 127, 160, 119, 212, 49, 65, 93, 107, 107, 69]
xx = [0] * len(cmp)
result = 0
v7 = 0
for i in range(len(cmp)):
xbox[0] = v6 + i
v8 = (v6 +i) & 0xff
v9 = xbox[v8 + 2]
v5 += v9
v5 = v5 & 0xff
xbox[v8 + 2] = xbox[(v5 + 2) & 0xff]
xbox[(v5 + 2) & 0xff] = v9
xx[i] = xbox[(xbox[v8 + 2] + v9 + 2) & 0xff] ^ cmp[i]

print(xx)

key = '480'
h="965761235685bf29fc5a962a08187f9902867a2ba1aaf72c470adea20eccb7fc"
print(h)
box = sbox_init(h)
print(box)
encode1(box)
arr = [i1, i2, i3,i4]
if(hashlib.sha1(bytes(arr)).hexdigest().lower() == "2e60865e94119223c4657eac98d744ee909e66b8"

下面是爆破脚本:

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
import hashlib

def change(hex_string):
int_array = [int(hex_string[i:i+2], 16) for i in range(0, len(hex_string), 2)]
return int_array

def sbox_init(h):
a = [0x00, 0x00,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, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF]
v7 = 0
v6 = 0
sha = change(h)
for i in range(256):
v9 = v7 + 1
v10 = a[v7 + 2]
v11 = v10 + v6
if(0x20 | v7) >> 32:
v8 = v7 % 0x20
else:
v8 = v7 % 0x20
v6 = (sha[v8] + v11) & 0xff
a[v7 + 2] = a[v6 + 2]
a[v6 + 2] = v10
v7 += 1
return a

def encode1(xbox):
v5 = 0
v6 = 1
flag = ""
cmp = [0xa2,0x05,0x05,0xdb,0x23,0x11,0x0e,0x39,0x46,0x06,0x0c,0xd1,0x91,0xc6,0x44,0xe2,0x1a,0x9c,0x61,0xf1,0xd3,0xeb,0x75,0x3a,0x81,0x5d,0xa2,0x12,0xb4,0x58,0x2a,0xdb,0x94,0x14]
xx = [0] * len(cmp)
result = 0
v7 = 0
for i in range(len(cmp)):
xbox[0] = v6 + i
v8 = (v6 +i) & 0xff
v9 = xbox[v8 + 2]
v5 += v9
v5 = v5 & 0xff
xbox[v8 + 2] = xbox[(v5 + 2) & 0xff]
xbox[(v5 + 2) & 0xff] = v9
flag += chr(xbox[(xbox[v8 + 2] + v9 + 2) & 0xff] ^ cmp[i])
if "flag" in flag:
print(flag)

dic="0123456789abcdef"
for i in dic:
for j in dic:
for k in dic:
for m in dic:
key = i + j + k + m
h=hashlib.sha256(key.encode('ascii')).hexdigest()
box = sbox_init(h)
encode1(box)
#flag{3df837d045ea07d9230cd23047a}

后面看到是个rc4,没看出来说是,白逆半天了。

陕西省赛逆向ak

战队名称:第1名

easyupx

先修一下

![Untitled](./上海省赛-陕西省赛初赛/Untitled 1.png)

发现还是脱不了壳,直接esp定律手脱

![Untitled](./上海省赛-陕西省赛初赛/Untitled 2.png)

找到进入

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
int sub_40143C()
{
char v1[100]; // [esp+1Ch] [ebp-74h] BYREF
int v2; // [esp+80h] [ebp-10h]
int v3; // [esp+84h] [ebp-Ch]
int v4; // [esp+88h] [ebp-8h]
int i; // [esp+8Ch] [ebp-4h]

sub_401B10();
sub_403F74(aPleaseInputYou);
sub_403F64(&unk_40605D, v1);
v2 = sub_403F44(v1);
v4 = 1;
v3 = 1;
for ( i = 0; i < v2; ++i )
{
switch ( v1[i] )
{
case 'U':
--v4;
break;
case 'D':
++v4;
break;
case 'L':
--v3;
break;
case 'R':
++v3;
break;
}
if ( sub_401410(v4, v3) )
break;
if ( aS0000000000000[15 * v4 + v3] == 35 )
{
sub_403F74(aYouAreRightFla);
return 0;
}
}
sub_403F6C(aWrong);
return 0;
}

经典迷宫

1
2
3
4
5
6
7
8
9
maze = "****************D000*0000000***0**000*****0***0*00*0*000*0***000**0*0*0*0***0***00*0*0*00**0***0**0*0**0**000*0*00*00*0****0*0******0#****0*00000000***000********0***0***00000*00***0*0*****0**0***0000000*00000****************"
print(len(maze))
for i in range(15):
for j in range(15):
print(maze[i*15+j],enR="")
print('\n')

U-w D-s L-a R-d
RRRDRRURRRRRRDDDDRDDD

外面加上flag{md5}就行

babypython

python字节码,

第一段加密,是对flag每一位异或8

1
2
968 LOAD_CONST             150 (8)
970 BINARY_OP 12 (^)

然后转16进制存入数组

1
2
3
4
5
6
7
8
9
159         990 LOAD_NAME               33 (value)
992 LOAD_NAME 35 (temp)
994 BINARY_OP 13 (+=)
998 STORE_NAME 33 (value)

160 1000 LOAD_NAME 30 (i)
1002 LOAD_CONST 149 (1)
1004 BINARY_OP 13 (+=)
1008 STORE_NAME 30 (i)

下一个加密是+3

1
2
1224 LOAD_CONST             152 (3)
1226 BINARY_OP 0 (+)

然后后面有个base64,猜测base64加密然后反转。其实有一个替换

1
2
3
4
5
6
7
8
9
10
11
12
13
1886 LOAD_CONST             166 ('g')
1888 LOAD_CONST 167 ('1')
1890 PRECALL 2
1894 CALL 2
1904 LOAD_METHOD 50 (replace)
1926 LOAD_CONST 168 ('H')
1928 LOAD_CONST 169 ('3')
1930 PRECALL 2
1934 CALL 2
1944 LOAD_METHOD 50 (replace)
1966 LOAD_CONST 170 ('W')
1968 LOAD_CONST 171 ('9')
1970 PRECALL 2

所以解密先反转base64把3→H,9→W,1→g

![Untitled](./上海省赛-陕西省赛初赛/Untitled 3.png)

拿到的结果先减再异或

1
2
3
4
5
6
7
data = "qglrv@onmlqpA>qmq>mBo3A?Bn<lppA@;lp4nx"
p = data[::-1]
flag = ""
for i in range(len(data)):
flag += chr((ord(p[i]) -3 ) ^ 8)
print(flag[::-1])
#flag{5dcbafe63fbf3b7d8647c1aee650ae9c}

Badcoffee

js代码,直接看逻辑就行有混淆,用https://deobfuscate.io/

逻辑很清晰,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
function _0x3e7b() {
var _0x293934 = ["8QWULJr", "414933buASiW", "log", "uuIPk", "2hWBkZw", "50830UgfzNJ", "search", "toString", "nPakj", "118810yaFCRd", "apply", "YES", "3279144wTrqht", "FRwAT", "204nSqkLC", "kGYrv", "XmyuE", "2810463LgnfkD", "qGnaj", "1665531censkz", "flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}", "1166JQjGyF", "(((.+)+)+)+$", "TKKGW", "charAt", "constructor", "5882863UAzTOx"];
_0x3e7b = function () {
return _0x293934;
};
return _0x3e7b();
}
function _0x229b(_0x21da69, _0x31c369) {
var _0x1d6e59 = _0x3e7b();
return _0x229b = function (_0x52956b, _0x1581c3) {
_0x52956b = _0x52956b - 307;
var _0x62d41 = _0x1d6e59[_0x52956b];
return _0x62d41;
}, _0x229b(_0x21da69, _0x31c369);
}
(function (_0x5484af, _0x1c1acb) {
var _0x42b6ee = _0x229b, _0x24c9f0 = _0x5484af();
while (true) {
try {
var _0x2b3ed9 = parseInt(_0x42b6ee(307)) / 1 * (parseInt(_0x42b6ee(310)) / 2) + parseInt(_0x42b6ee(323)) / 3 + parseInt(_0x42b6ee(318)) / 4 + -parseInt(_0x42b6ee(311)) / 5 * (-parseInt(_0x42b6ee(320)) / 6) + parseInt(_0x42b6ee(332)) / 7 * (-parseInt(_0x42b6ee(333)) / 8) + parseInt(_0x42b6ee(325)) / 9 + parseInt(_0x42b6ee(315)) / 10 * (-parseInt(_0x42b6ee(327)) / 11);
if (_0x2b3ed9 === _0x1c1acb) break; else _0x24c9f0.push(_0x24c9f0.shift());
} catch (_0x52aa75) {
_0x24c9f0.push(_0x24c9f0.shift());
}
}
}(_0x3e7b, 602448));
function xxx(_0x53b7bb, _0x590286) {
var _0xafde9a = _0x229b, _0x324e3a = {};
_0x324e3a[_0xafde9a(314)] = function (_0x318579, _0x2c8042) {
return _0x318579 ^ _0x2c8042;
};
var _0x3ba534 = _0x324e3a;
return _0x3ba534.nPakj(_0x53b7bb, _0x590286);
}
function enc(_0x4bda4c) {
var _0x137834 = _0x229b, _0x3aaed1 = {XmyuE: function (_0x57b977, _0x20fa18, _0x570bf6) {
return _0x57b977(_0x20fa18, _0x570bf6);
}}, _0x8ff1dd = [], _0x6aca75 = [233, 129, 127, 238, 145, 144, 11, 43, 87, 134, 243, 158, 197, 216, 111, 136, 152, 29, 204, 31, 26, 228, 39, 148, 215, 220, 90, 76, 251, 57, 183, 184, 150, 157, 156, 176, 13, 41, 30, 86, 244, 8];
console.log(_0x6aca75);
for (let _0x7bc200 = 0; _0x7bc200 < 42; _0x7bc200++) {
_0x8ff1dd[_0x7bc200] = _0x3aaed1[_0x137834(322)](xxx, _0x6aca75.at(_0x7bc200), _0x4bda4c[_0x137834(330)](_0x7bc200).charCodeAt());
}
for (let _0x4f674a = 0; _0x4f674a < 42; _0x4f674a++) {
_0x8ff1dd[_0x4f674a] = xxx(_0x8ff1dd.at(_0x4f674a), _0x6aca75.at(41 - _0x4f674a));
}
console.log(_0x8ff1dd);
return _0x8ff1dd;
}
function fff() {
var _0x47409d = _0x229b, _0x45e04c = {uuIPk: _0x47409d(328), qGnaj: function (_0x5bc07b, _0x400faa, _0x441f85) {
return _0x5bc07b(_0x400faa, _0x441f85);
}, BnVXl: function (_0x189883) {
return _0x189883();
}, dhkyF: _0x47409d(326), FRwAT: function (_0x3ab36f, _0x124b7f) {
return _0x3ab36f(_0x124b7f);
}, kGYrv: function (_0x127f5c, _0x4a909c) {
return _0x127f5c < _0x4a909c;
}, MrEod: function (_0x3d6620, _0x297ded) {
return _0x3d6620 != _0x297ded;
}, arYUV: "Error", TKKGW: _0x47409d(317)}, _0x5a5ca7 = function () {
var _0x201045 = true;
return function (_0x69fca7, _0x2b8ad0) {
var _0x5c3c95 = _0x201045 ? function () {
var _0x579f2d = _0x229b;
if (_0x2b8ad0) {
var _0xd4d9a8 = _0x2b8ad0[_0x579f2d(316)](_0x69fca7, arguments);
return _0x2b8ad0 = null, _0xd4d9a8;
}
} : function () {};
return _0x201045 = false, _0x5c3c95;
};
}(), _0x59c26e = _0x45e04c[_0x47409d(324)](_0x5a5ca7, this, function () {
var _0x25f3ae = _0x47409d;
return _0x59c26e.toString()[_0x25f3ae(312)](_0x45e04c.uuIPk)[_0x25f3ae(313)]()[_0x25f3ae(331)](_0x59c26e)[_0x25f3ae(312)](_0x45e04c[_0x25f3ae(309)]);
});
_0x45e04c.BnVXl(_0x59c26e);
var _0xe4960c = _0x45e04c.dhkyF, _0x55dae6 = _0x45e04c[_0x47409d(319)](enc, _0xe4960c), _0xbb5ecd = [135, 25, 72, 151, 195, 212, 228, 212, 250, 101, 39, 77, 163, 77, 70, 167, 119, 184, 7, 77, 144, 154, 93, 10, 185, 48, 179, 77, 71, 163, 67, 61, 113, 156, 196, 136, 239, 241, 128, 93, 84, 156];
console.log(_0xbb5ecd);
for (let _0x37df9d = 0; _0x45e04c[_0x47409d(321)](_0x37df9d, 42); _0x37df9d++) {
if (_0x45e04c.MrEod(_0x55dae6.at(_0x37df9d), _0xbb5ecd.at(_0x37df9d))) {
console[_0x47409d(308)](_0x45e04c.arYUV);
return;
}
}
console[_0x47409d(308)](_0x45e04c[_0x47409d(329)]);
return;
}
fff();

下面是脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
a= [
233, 129, 127, 238, 145, 144, 11, 43, 87,
134, 243, 158, 197, 216, 111, 136, 152, 29,
204, 31, 26, 228, 39, 148, 215, 220, 90,
76, 251, 57, 183, 184, 150, 157, 156, 176,
13, 41, 30, 86, 244, 8
]
flag = ""
b = [
135, 25, 72, 151, 195, 212, 228, 212, 250,
101, 39, 77, 163, 77, 70, 167, 119, 184,
7, 77, 144, 154, 93, 10, 185, 48, 179,
77, 71, 163, 67, 61, 113, 156, 196, 136,
239, 241, 128, 93, 84, 156
]
for i in range(42):
flag += chr(b[i] ^ a[41-i] ^ a[i])
print(flag)
#flag{I_c0uld_neu3r_undeRstand_jvaVs3rIpt!}

Web&Assembly

wasm不好看,但是鸡爪的插件可以很好的看wasm

check是重点

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
uint check(char *some,char *input,int hash)

{
bool bVar1;
uint uVar2;
size_t sVar3;
int l;
int k;
int j;
undefined8 array;
undefined8 local_58;
undefined8 local_50;
undefined8 local_48;
uint i;
uint flag;
undefined8 local_30;
undefined8 local_28;
char local_20;
int local_10;
char *input_str;
char *local_8;
uint local_4;

local_20 = s_0123456789abcdef_ram_00010000[16];
local_28 = s_0123456789abcdef_ram_00010000._8_8_;
local_30 = s_0123456789abcdef_ram_00010000._0_8_;
local_10 = hash;
input_str = input;
local_8 = some;
/* 114!514! */
sVar3 = strlen(some);
if (sVar3 < 8) {
local_4 = 0;
}
else {
flag = 0;
for (i = 0; uVar2 = i, sVar3 = strlen(input_str), uVar2 < sVar3; i = i + 8) {
local_48 = 0;
local_50 = 0;
local_58 = 0;
array = 0;
for (j = 0; j < 8; j = j + 1) {
*(uint *)((int)&array + j * 4) = (int)(char)(local_8[j] ^ input_str[j + i]) & 0xff;
}
for (k = 0; k < 114; k = k + 1) {
do_something((int *)&array,0,1,2,3);
do_something((int *)&array,4,5,6,7);
do_something((int *)&array,0,1,4,5);
do_something((int *)&array,2,3,6,7);
}
for (l = 0; l < 8; l = l + 1) {
bVar1 = true;
if (flag == 0) {
bVar1 = *(char *)((int)&local_30 + *(int *)((int)&array + l * 4) / 0x10) ==
*(char *)(local_10 + (l + i) * 2);
}
flag = 1;
if (!bVar1) {
flag = (uint)(*(char *)((int)&local_30 + *(int *)((int)&array + l * 4) % 0x10) ==
*(char *)(local_10 + (l + i) * 2 + 1));
}
}
}
local_4 = flag;
}
return local_4;
}

大致逻辑就是先让flag和key异或,然后进入do_somthing进行114次操作,接下来是把值转成16进制来对比,z3可以解,不过时间很长,需要等待,差点就ctrl+z了

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
from z3 import*
s=Solver()
flag = [BitVec("flag%d" % i,16) for i in range(0x20)]

def do_something(arr,in1,in2,in3,in4):
arr[in4] = (arr[in4] ^ arr[in1] + arr[in3]) & 0xFF
arr[in3] = (arr[in3] ^ arr[in1] + arr[in2]) & 0xFF
arr[in2] = (arr[in2] ^ arr[in3] + arr[in4]) & 0xFF
arr[in1] = (arr[in1] ^ arr[in2] + arr[in4]) & 0xFF

str_1 = "0123456789abcdef"
tmp = [0] * 32
hash = "91fba5ccfef6e0905eeeb47940d25543c286b10de778fbb268ab7580414c0758"
hash1 = [0x91,0xfb,0xa5,0xcc,0xfe,0xf6,0xe0,0x90,0x5e,0xee,0xb4,0x79,0x40,0xd2,0x55,0x43,0xc2,0x86,0xb1,0x0d,0xe7,0x78,0xfb,0xb2,0x68,0xab,0x75,0x80,0x41,0x4c,0x07,0x58]
key = "114!514!"
for i in range(0,len(flag),8):
arr = [0] * 8
for j in range(8):
arr[j] = ord(key[j]) ^ flag[i + j]
for j in range(114):
do_something(arr,0,1,2,3)
do_something(arr,4,5,6,7)
do_something(arr,0,1,4,5)
do_something(arr,2,3,6,7)
for ii in range(8):
tmp[ii + i] = arr[ii]

for i in range(32):
s.add(tmp[i]&0xff == hash1[i])
if s.check() == sat:
m = s.model()
res = []
for i in range(32):
res.append(chr(m[flag[i]].as_long()))
s=''.join(res)
print(s)
else:
print("nope")
#print(v5)
#flag{Y0u_Kn0w_W45M_n0w!!W0oO0ow}

这个太难爆了,爆了几分钟,幸好中间去找哥们唠嗑了。