Reverse

CSGO

Go逆向静态不好看,考虑动调
在main_init有IsDebuggerPresent反调试,nop掉
img
img
看一眼findcrypt插件,识别到base64
img
看看main_main
img
main__Cfunc_enc_abi0是加密
runtime_memequal是最后的check,base64完是60位说明flag为44位
在81行下断
一直跟踪mian_Cfunc_enc_abi0,发现最后是指向fkReverse
img
下断,动调拿到base64表LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJK
img
然后继续F9来到main_main函数的check处
img
unk_6A9091是密文cPQebAcRp+n+ZeP+YePEWfP7bej4YefCYd/7cuP7WfcPb/URYeMRbesObi/=
img
DASCTF{73913519-A0A6-5575-0F10-DDCBF50FA8CA}

vm_wo

我擦,苹果
image.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
43
44
45
46
47
48
49
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 i; // x8
char __s[16]; // [xsp+10h] [xbp-E0h] BYREF
__int128 v6; // [xsp+20h] [xbp-D0h]
__int128 v7; // [xsp+30h] [xbp-C0h]
__int128 v8; // [xsp+40h] [xbp-B0h]
__int128 v9; // [xsp+50h] [xbp-A0h]
__int128 v10; // [xsp+60h] [xbp-90h]
__int128 v11; // [xsp+70h] [xbp-80h]
__int128 v12; // [xsp+80h] [xbp-70h]
__int128 v13; // [xsp+90h] [xbp-60h]
__int128 v14; // [xsp+A0h] [xbp-50h]
__int128 v15; // [xsp+B0h] [xbp-40h]
__int128 v16; // [xsp+C0h] [xbp-30h]
__int64 v17; // [xsp+D0h] [xbp-20h]

if ( ptrace(0, 0, (caddr_t)1, 0) == -1 )
goto LABEL_8;
v17 = 0LL;
v15 = 0u;
v16 = 0u;
v13 = 0u;
v14 = 0u;
v11 = 0u;
v12 = 0u;
v9 = 0u;
v10 = 0u;
v7 = 0u;
v8 = 0u;
*(_OWORD *)__s = 0u;
v6 = 0u;
printf("please input your flag:");
scanf("%s", __s);
if ( strlen(__s) != 29 )
LABEL_8:
exit(0);
myoperate(__s, 29);
for ( i = 0LL; i != 29; ++i )
{
if ( __s[i] != byte_100003F47[i] )
{
printf("error!");
goto LABEL_8;
}
}
printf("ok you get the flag");
return 0;
}

提取到密文:

1
2
3
4
5
6
unsigned char ida_chars[] =
{
0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD,
0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3, 0x85, 0x99, 0x87, 0xBF,
0xE9, 0xB1, 0x89, 0xE9, 0x91, 0x89, 0x89, 0x8F, 0xAD
};

指令好像写死了

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
__int64 __fastcall myoperate(char *a1, int a2)
{
__int64 v2; // x20
_QWORD v5[2]; // [xsp+8h] [xbp-98h] BYREF
_QWORD v6[2]; // [xsp+18h] [xbp-88h] BYREF
_QWORD v7[2]; // [xsp+28h] [xbp-78h] BYREF
_QWORD v8[2]; // [xsp+38h] [xbp-68h] BYREF

LODWORD(v2) = a2;
dword_100008003 = -1091715345;
if ( ptrace(0, 0, (caddr_t)1, 0) == -1 )
exit(0);
if ( (int)v2 >= 1 )
{
v2 = (unsigned int)v2;
do
{
v8[0] = 0x20D01011903001ALL;
*(_QWORD *)((char *)v8 + 7) = 0x300010201180702LL;
BYTE2(v8[0]) = *a1;
interpretBytecode((char *)v8, 15);
v7[0] = 0x20D02011903001ALL;
*(_QWORD *)((char *)v7 + 7) = 0x400010201180602LL;
BYTE2(v7[0]) = vm_body;
interpretBytecode((char *)v7, 15);
v6[0] = 0x20D03011903001ALL;
*(_QWORD *)((char *)v6 + 7) = 0x500010201180502LL;
BYTE2(v6[0]) = vm_body;
interpretBytecode((char *)v6, 15);
v5[0] = 0x20D04011903001ALL;
*(_QWORD *)((char *)v5 + 7) = 0x600010201180402LL;
BYTE2(v5[0]) = vm_body;
interpretBytecode((char *)v5, 15);
*a1++ = ((unsigned __int8)vm_body >> 5) | (8 * vm_body);
--v2;
}
while ( v2 );
}
return 0LL;
}

手撸,发现加密很对称,写出解密脚本(异或和位移)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enc = [
0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD, 0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3, 0x85, 0x99,
0x87, 0xBF, 0xE9, 0xB1, 0x89, 0xE9, 0x91, 0x89, 0x89, 0x8F, 0xAD, 0x57]
flag = ''
for tmp in enc:
tmp = ((tmp >> 3) | (tmp << 5)) & 0xff
tmp ^= 0xBE
tmp = ((tmp >> 4) | (tmp << 4)) & 0xff
tmp ^= 0xED
tmp = ((tmp >> 5) | (tmp << 3)) & 0xff
tmp ^= 0xBE
tmp = ((tmp >> 6) | (tmp << 2)) & 0xff
tmp ^= 0xEF
tmp = ((tmp >> 7) | (tmp << 1)) & 0xff
# print(tmp)
flag += chr(tmp)
print(flag)
# DASCTF{you_are_right_so_cool}

Ez加密器

通过------\nGetFlag!\n------定位到sub_7FF798C240E0
分析如下

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
__int64 sub_1400140E0()
{
char *v0; // r8
char *v1; // rcx
char *v2; // r9
char v3; // si
unsigned __int8 v4; // di
int v5; // eax
int v6; // edx
int v7; // edi
int v8; // eax
int v9; // edi
int v10; // ebp
int v11; // edi
int v12; // er12
int v13; // edi
char v14; // di
int v15; // eax
int v16; // edx
int v18; // esi
int v19; // eax
int v20; // esi
int v21; // edi
int v22; // esi
int v23; // ebp
int v24; // esi
char *enc; // [rsp+20h] [rbp-D8h] BYREF
__int64 v26; // [rsp+28h] [rbp-D0h]
char code_base64[8]; // [rsp+38h] [rbp-C0h] BYREF
char enc_hex[184]; // [rsp+40h] [rbp-B8h] BYREF

sub_140003D87();
get_input((__int64)code, (__int64)input);
base64_enc(code, 6i64, code_base64);
DES(&enc, code_base64, input, 40i64);
v0 = enc;
if ( (int)v26 <= 0 )
{
v2 = enc_hex;
}
else
{
v1 = enc_hex;
v2 = &enc_hex[2 * (int)v26];
do
{
v3 = *v0;
v4 = (unsigned __int8)*v0 >> 4;
v5 = v4;
if ( v4 <= 9u )
{
LOBYTE(v6) = v4 ^ 0x30;
if ( !v4 )
LOBYTE(v6) = 48;
}
else
{
v6 = 65;
do
{
v7 = v6 & v5;
v6 ^= v5;
v5 = 2 * v7;
}
while ( 2 * v7 );
v8 = -11;
v9 = 1;
do
{
v10 = v9;
v11 = v8 & v9;
v12 = v8;
v8 ^= v10;
v9 = 2 * v11;
}
while ( v9 );
if ( v10 != v12 )
{
do
{
v13 = v6 & v8;
v6 ^= v8;
v8 = 2 * v13;
}
while ( 2 * v13 );
}
}
*v1 = v6;
v1 += 2;
v14 = v3 & 0xF;
v15 = v3 & 0xF;
if ( (v3 & 0xFu) > 9 )
{
v16 = 65;
do
{
v18 = v16 & v15;
v16 ^= v15;
v15 = 2 * v18;
}
while ( 2 * v18 );
v19 = -11;
v20 = 1;
do
{
v21 = v20;
v22 = v19 & v20;
v23 = v19;
v19 ^= v21;
v20 = 2 * v22;
}
while ( v20 );
if ( v21 != v23 )
{
do
{
v24 = v16;
v16 ^= v19;
v19 = 2 * (v19 & v24);
}
while ( v19 );
}
}
else
{
LOBYTE(v16) = v14 ^ 0x30;
if ( !v14 )
LOBYTE(v16) = 48;
}
*(v1 - 1) = v16;
++v0;
}
while ( v1 != v2 );
}
*v2 = 0;
if ( !strcmp(Big_Numbers1_1400150A0, enc_hex) )
print("------\nGetFlag!\n------");
system("pause");
return 0i64;
}

可以知道程序先获取长度为6位的密钥和长度为40的flag,然后用自定义表base64编码密钥,接着DES加密
最后和Big_Numbers1_7FF798C250A0进行check
get_intput函数里有长度和格式检验
img
base64_enc那个函数里可以找到base64表
img
DES加密Findcrypt没识别出来,但是Signsrch识别出来了DES标志
img
在DES函数里的sub_140001A20函数里看到对Big_Numbers1_1400150A0的异或操作,可以在脚本中手动异或一下,这里选择动调直接拿到
img
image.png
据此可以通过爆破得到6位数字密钥key,然后用变表base64编码过的key去解Big_Numbers1_7FF798C250A0

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
from Crypto.Cipher import DES
import binascii
import itertools
import base64
def custom_base64_encode(data):
custom_chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+/'
# 创建标准Base64字符集和自定义字符集的映射表
base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
char_map = str.maketrans(base64_chars, custom_chars)
# 使用标准Base64编码
encoded_data = base64.b64encode(data.encode()).decode()
# 替换为自定义字符
encoded_data = encoded_data.translate(char_map)
return encoded_data

def generate_sequential_key():
digits = '0123456789'
for key_tuple in itertools.product(digits, repeat=6):
yield ''.join(key_tuple)

def des_decrypt(ciphertext, key):
# 将密钥转换为8字节
key = key.encode('utf-8')[:8]
# 将16进制字符串转换为字节
ciphertext = binascii.unhexlify(ciphertext)
# 创建DES加密器
cipher = DES.new(key, DES.MODE_ECB)
# 解密数据
plaintext = cipher.decrypt(ciphertext)
return plaintext
# 要解密的数据和密钥
encrypted_data = "0723105D5C12217DCDC3601F5ECB54DA9CCEC2279F1684A13A0D716D17217F4C9EA85FF1A42795731CA3C55D3A4D7BEA"
for psw in generate_sequential_key():
key = custom_base64_encode(psw)
#DES解密
decrypted_data = des_decrypt(encrypted_data, key)
if b'DASCTF' in decrypted_data:
print(f"Found key:{psw}\nIt's base64_encode:{key}\nDecrypted Data:{decrypted_data.decode()}")
encryption_key = key
break
pass
# Found key:151490
# It's base64_encode:mtuNndAM
# Decrypted Data: DASCTF{f771b96b71514bb6bc20f3275fa9404e}

Blast

ida Findcrypt插件看到MD5和好多个哈希值
image.png
image.png
定位到MD5加密函数,查看引用有两个
image.png
一个在main函数一个在sub_402370,发现main函数和sub_402370差不多且在main函数中调用了sub_402370
所以直接盲猜两次哈希MD5(MD5(data))

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
enc = [
'14d89c38cd0fb23a14be2798d449c182','a94837b18f8f43f29448b40a6e7386ba','af85d512594fc84a5c65ec9970956ea5','af85d512594fc84a5c65ec9970956ea5','10e21da237a4a1491e769df6f4c3b419','a705e8280082f93f07e3486636f3827a','297e7ca127d2eef674c119331fe30dff','b5d2099e49bdb07b8176dff5e23b3c14','83be264eb452fcf0a1c322f2c7cbf987','a94837b18f8f43f29448b40a6e7386ba','71b0438bf46aa26928c7f5a371d619e1','a705e8280082f93f07e3486636f3827a','ac49073a7165f41c57eb2c1806a7092e','a94837b18f8f43f29448b40a6e7386ba','af85d512594fc84a5c65ec9970956ea5','ed108f6919ebadc8e809f8b86ef40b05','10e21da237a4a1491e769df6f4c3b419','3cfd436919bc3107d68b912ee647f341','a705e8280082f93f07e3486636f3827a','65c162f7c43612ba1bdf4d0f2912bbc0','10e21da237a4a1491e769df6f4c3b419','a705e8280082f93f07e3486636f3827a','3cfd436919bc3107d68b912ee647f341','557460d317ae874c924e9be336a83cbe','a705e8280082f93f07e3486636f3827a','9203d8a26e241e63e4b35b3527440998','10e21da237a4a1491e769df6f4c3b419','f91b2663febba8a884487f7de5e1d249','a705e8280082f93f07e3486636f3827a','d7afde3e7059cd0a0fe09eec4b0008cd','488c428cd4a8d916deee7c1613c8b2fd','39abe4bca904bca5a11121955a2996bf','a705e8280082f93f07e3486636f3827a','3cfd436919bc3107d68b912ee647f341','39abe4bca904bca5a11121955a2996bf','4e44f1ac85cd60e3caa56bfd4afb675e','45cf8ddfae1d78741d8f1c622689e4af','3cfd436919bc3107d68b912ee647f341','39abe4bca904bca5a11121955a2996bf','4e44f1ac85cd60e3caa56bfd4afb675e','37327bb06c83cb29cefde1963ea588aa','a705e8280082f93f07e3486636f3827a','23e65a679105b85c5dc7034fded4fb5f','10e21da237a4a1491e769df6f4c3b419','71b0438bf46aa26928c7f5a371d619e1','af85d512594fc84a5c65ec9970956ea5','39abe4bca904bca5a11121955a2996bf']
import hashlib
import itertools

# 生成所有ASCII可见字符
characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
combinations = itertools.product(characters, repeat=1)
# 创建一个字典以存储已知哈希值和对应的原始字符
hashes_dict = {hash_val: None for hash_val in enc}
# 遍历所有组合,计算哈希值并与已知的哈希值进行比较
for combo in combinations:
plaintext = ''.join(combo)
hash1 = hashlib.md5(plaintext.encode()).hexdigest()
hash2 = hashlib.md5(hash1.encode()).hexdigest()
if hash2 in enc:
hashes_dict[hash2] = plaintext
flag = ''
for i in enc:
flag += hashes_dict[i]
print(f"Original Text for Hash '{i}': {hashes_dict[i]}")
print(flag)
'''
Original Text for Hash '14d89c38cd0fb23a14be2798d449c182': H
Original Text for Hash 'a94837b18f8f43f29448b40a6e7386ba': e
Original Text for Hash 'af85d512594fc84a5c65ec9970956ea5': l
Original Text for Hash 'af85d512594fc84a5c65ec9970956ea5': l
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '297e7ca127d2eef674c119331fe30dff': C
Original Text for Hash 'b5d2099e49bdb07b8176dff5e23b3c14': t
Original Text for Hash '83be264eb452fcf0a1c322f2c7cbf987': f
Original Text for Hash 'a94837b18f8f43f29448b40a6e7386ba': e
Original Text for Hash '71b0438bf46aa26928c7f5a371d619e1': r
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash 'ac49073a7165f41c57eb2c1806a7092e': V
Original Text for Hash 'a94837b18f8f43f29448b40a6e7386ba': e
Original Text for Hash 'af85d512594fc84a5c65ec9970956ea5': l
Original Text for Hash 'ed108f6919ebadc8e809f8b86ef40b05': c
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash '3cfd436919bc3107d68b912ee647f341': m
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '65c162f7c43612ba1bdf4d0f2912bbc0': T
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '3cfd436919bc3107d68b912ee647f341': m
Original Text for Hash '557460d317ae874c924e9be336a83cbe': y
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '9203d8a26e241e63e4b35b3527440998': M
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash 'f91b2663febba8a884487f7de5e1d249': v
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash 'd7afde3e7059cd0a0fe09eec4b0008cd': a
Original Text for Hash '488c428cd4a8d916deee7c1613c8b2fd': n
Original Text for Hash '39abe4bca904bca5a11121955a2996bf': d
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '3cfd436919bc3107d68b912ee647f341': m
Original Text for Hash '39abe4bca904bca5a11121955a2996bf': d
Original Text for Hash '4e44f1ac85cd60e3caa56bfd4afb675e': 5
Original Text for Hash '45cf8ddfae1d78741d8f1c622689e4af': (
Original Text for Hash '3cfd436919bc3107d68b912ee647f341': m
Original Text for Hash '39abe4bca904bca5a11121955a2996bf': d
Original Text for Hash '4e44f1ac85cd60e3caa56bfd4afb675e': 5
Original Text for Hash '37327bb06c83cb29cefde1963ea588aa': )
Original Text for Hash 'a705e8280082f93f07e3486636f3827a': _
Original Text for Hash '23e65a679105b85c5dc7034fded4fb5f': w
Original Text for Hash '10e21da237a4a1491e769df6f4c3b419': o
Original Text for Hash '71b0438bf46aa26928c7f5a371d619e1': r
Original Text for Hash 'af85d512594fc84a5c65ec9970956ea5': l
Original Text for Hash '39abe4bca904bca5a11121955a2996bf': d
Hello_Ctfer_Velcom_To_my_Mov_and_md5(md5)_world
'''