image-20240601215658894

挺简单的reverse,主要注重新的知识点,两道base64换表一道rc4还有一个upx套壳

编码喵

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//main()
std::getline<char,std::char_traits<char>,std::allocator<char>>(refptr__ZSt3cin, v17);
v11 = operator new(0x20ui64);
text_72(v11);//换表abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/
v21 = v11;
LODWORD(v11) = std::string::length(v17);
v12 = (unsigned __int8 *)std::string::c_str(v17);
LitCTF_tanji_calculate::Encode[abi:cxx11]((__int64)v16, v21, v12, v11);//base64加密
std::allocator<char>::allocator(&v20);
std::string::basic_string(
(__int64)v15,
(__int64)"tgL0q1rgEZaZmdm0zwq4lweYzgeTngfHnI1ImMm5ltaXywnLowuYnJmWmx0=",
(__int64)&v20);
if ( (unsigned __int8)std::operator==<char>(v16, v15) )//比较
v13 = std::operator<<<std::char_traits<char>>((__int64)refptr__ZSt4cout, (__int64)&unk_405208);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import base64
import string

# 这是你的加密字符串和自定义的Base64字符集
a = 'tgL0q1rgEZaZmdm0zwq4lweYzgeTngfHnI1ImMm5ltaXywnLowuYnJmWmx0='
list1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/'
list2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
# 创建一个翻译表,将你的字符集映射到标准的Base64字符集
trans = str.maketrans(list1, list2)

# 使用这个翻译表将你的字符串转换为标准的Base64编码
standard_b64 = a.translate(trans)
# 现在你可以使用base64库来解码这个字符串了
decoded_bytes = base64.b64decode(standard_b64)

# 将解码后的字节串转换为字符串
decoded_str = decoded_bytes.decode('utf-8')

print(decoded_str)
#LitCTF{03034ed8-a2da-4aa6-b2c9-01ace9e26301}

hello_upx

查壳发现无法正常脱除,查找文章发现不是常规upx壳,需要修改hex值然后upx正常去壳即可查看完整的反编译,可参考下面的文章。

https://blog.csdn.net/hanxuer_/article/details/106549548

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
_main():
v4[0] = 0x707541504072684Ci64;
v4[1] = 0x655158612559632Bi64;
v4[2] = 0x4F5E4E601E5A4E20i64;
v5 = 101;
v7 = 1;
printf("welcome to LitCTF2024\nplease inputs you flag:");
scanf("%s", v6);
for ( i = 0; i <= 24; ++i )
v6[i] -= i;
for ( i = 0; i <= 24; ++i )
{
if ( *((unsigned __int8 *)v4 + i) != v6[i] )
v7 = 0;
}
1
2
3
4
5
6
7
8
a=[76, 104, 114, 64, 80, 65, 117, 112,
43, 99, 89, 37, 97, 88, 81, 101,
32, 78, 90, 30, 96, 78, 94, 79,101]
b=''
for i in range(25):
b+=chr(a[i]+i)
print(b)
#LitCTF{w3lc0me_t0_l1tctf}

ezpython!!!!!

使用 Pyinstaller Extractor 分离出pyc文件

1
python pyinstxtractor.py ezpy.exe

在线网站反编译

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
#ezpy.pyc
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.11

import Litctfbase64
flag = input('flag:')
flag = Litctfbase64.b64decode(flag)
if flag == 'X=3o4hx=0EZwf=mMv13gX=3o4hx=qje2ZjtgZQmEKXZog4==':
print('win')
return None
print('no')
#Litctfbase64
# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.11

import string
BASE64_ALPHABET = '8kuWYm=1JiUPs7DT4x+X5tcqZKfGvA0gFLB6y3QbV2rNOlRdMwnEohjzSe9/HIa-'

def b64decode(input_string):
pass
# WARNING: Decompyle incomplete


def from_base64(base64_string):
pass
# WARNING: Decompyle incomplete

虽然代码不能完全反编译但是能够大致猜到就是逆向换表base64,但有一点他最后四位需要去掉才能正常decode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import base64
import string

# 这是你的加密字符串和自定义的Base64字符集
a = 'X=3o4hx=0EZwf=mMv13gX=3o4hx=qje2ZjtgZQmEKXZo'
list1 = '8kuWYm=1JiUPs7DT4x+X5tcqZKfGvA0gFLB6y3QbV2rNOlRdMwnEohjzSe9/HIa-'
list2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
# 创建一个翻译表,将你的字符集映射到标准的Base64字符集
trans = str.maketrans(list1, list2)

# 使用这个翻译表将你的字符串转换为标准的Base64编码
standard_b64 = a.translate(trans)
# 现在你可以使用base64库来解码这个字符串了
decoded_bytes = base64.b64decode(standard_b64)

# 将解码后的字节串转换为字符串
decoded_str = decoded_bytes.decode('utf-8')

print(decoded_str)
#LitCTF{61happy_LitCTF_nice_base64}

ezrc4

说是签到题结果到头来是解出人数最少的一道题,还被他绕了蛮久的

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
//main()  
Buf1[0] = 0x606EA290DC7CB2D5i64;
Buf1[1] = 0x3190B05971E41306i64;
printf("input flag:");
scanf("%s21", Str);
v3 = strlen(Str);
v4 = strlen(key);
rc4_init((__int64)v10, (__int64)key, v4); //key = 'fenkey?'但是发现有交叉引用需要解出正确的key
rc4_crypt((__int64)v10, Str, v3);
if ( !memcmp(Buf1, Str, 0x15ui64) )
//rc4_init()创建S盒
for ( i = 0i64; i != 256; ++i )
{
*(_BYTE *)(a1 + i) = i;
v11[i] = *(_BYTE *)(a2 + (int)i % a3);
}
v5 = 0i64;
v6 = 0;
do
{
v7 = *(_BYTE *)(a1 + v5);
v8 = v11[v5] + v6 + v7; // 下面这几步看起来很绕,实际上就是混淆用的,和正常创建效果一致
v9 = (unsigned int)(((unsigned __int8)v11[v5] + v6 + v7) >> 31) >> 24;
v6 = (unsigned __int8)(v9 + v8) - v9;
result = (unsigned __int8 *)(a1 + v6);
*(_BYTE *)(a1 + v5) = *result;
*result = v7;
++v5;
}
//re4_crypt()
if ( a3 > 0 )
{
v3 = a2;
v4 = &a2[a3 - 1 + 1];
v5 = 0;
v6 = 0;
do
{
v6 = (v6 + 1) % 256;
v7 = (unsigned __int8 *)(a1 + v6);
v8 = *v7;
v9 = v5 + *v7; // 一样也是正常rc4加密
v10 = (unsigned int)((v5 + *v7) >> 31) >> 24;
v5 = (unsigned __int8)(v10 + v9) - v10;
v11 = (unsigned __int8 *)(a1 + v5);
*v7 = *v11;
*v11 = v8;
result = *(unsigned __int8 *)(a1 + (unsigned __int8)(*v7 + v8));
*v3++ ^= result;
}
while ( v3 != v4 );
}
//X_X()
result = key;
v1 = &key1;
do
*result++ ^= *v1++;
while ( result != &key[7] );
return result;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#求解key并且创建S盒
a='fenkey?'
d=[10, 12, 26, 8, 17, 31, 30]
e=''
for i in range(len(a)):
e+=chr(ord(a[i])^d[i])
b=''
c=[]
j=0
for i in range(256):
c.append(i)
for i in range(256):
j = (j + c[i] + ord(e[i % len(a)])) % 256 # 这里把 C 实现中的 prc4->t_box[i] = key[i % keylen];和j=(j+prc4->s_box[i]+prc4->t_box[i])%256;合并在了一起。
c[i], c[j] = c[j], c[i]
print(c)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#rc4解码
a=[33, 214, 76, 178, 43, 149, 188, 179, 69, 9, 85, 77, 37, 169, 143, 27, 99, 147, 25, 146, 7, 72, 20, 91, 205, 133, 19, 157, 151, 11, 15, 35, 78, 41, 0, 210, 115, 123, 56, 48, 49, 196, 112, 42, 164, 158, 141, 107, 139, 2, 195, 106, 250, 241, 207, 28, 18, 54, 223, 167, 46, 74, 216, 60, 230, 62, 131, 113, 184, 160, 213, 51, 243, 159, 93, 198, 219, 45, 44, 168, 71, 220, 89, 232, 190, 36, 124, 142, 90, 130, 82, 233, 81, 154, 80, 126, 236, 118, 32, 129, 102, 181, 105, 165, 203, 251, 88, 127, 180, 40, 237, 249, 110, 248, 108, 23, 12, 109, 14, 201, 66, 94, 177, 152, 227, 185, 53, 128, 58, 104, 192, 103, 231, 65, 22, 182, 173, 120, 211, 70, 187, 95, 218, 34, 239, 97, 10, 55, 148, 26, 8, 21, 24, 194, 245, 242, 155, 156, 52, 206, 117, 162, 116, 191, 161, 125, 137, 183, 100, 3, 247, 208, 240, 132, 222, 200, 138, 96, 224, 6, 235, 255, 204, 193, 79, 170, 50, 59, 47, 145, 38, 1, 215, 144, 119, 87, 114, 92, 217, 176, 238, 134, 174, 31, 153, 150, 13, 226, 17, 252, 64, 98, 228, 186, 246, 166, 83, 16, 111, 57, 253, 84, 39, 136, 197, 172, 225, 212, 75, 101, 73, 202, 254, 61, 209, 86, 244, 68, 229, 5, 171, 163, 29, 63, 221, 121, 122, 189, 199, 67, 234, 4, 175, 135, 140, 30]
c=[213, 178, 124, 220, 144, 162, 110, 96, 6, 19, 228, 113, 89, 176, 144, 49, 178, 199, 29, 215, 127]
def rc4_decrypt(S, ciphertext):
j = 0
out = []
i = j = 0
for char in ciphertext:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
k = S[(S[i] + S[j]) % 256]
out.append(char ^ k)

return bytes(out)
# 解密
plaintext = rc4_decrypt(a, c)
print("解密后的明文:", plaintext.decode("utf-8"))
#解密后的明文: LitCTF{rc4_love_nice}

总结

还是有比较多的知识点不太熟悉,还得是多练题,多锻炼思维,才能做的又快有准