Reverse

sedRust_happyVm

比赛没做出来,贴几个wp,复现了再说
羊城杯 · 2024 WriteUp-WgpSec狼组安全团队
2024羊城杯sedRust_happyVm
再贴个exp

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

base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
k = [0x0, 0x82, 0x11, 0x92, 0xa8, 0x39, 0x82, 0x28, 0x9a, 0x61, 0x58, 0x8b, 0xA2, 0x43, 0x68, 0x89, 0x4, 0x8f, 0xB0,
0x43, 0x49, 0x3A, 0x18, 0x39, 0x72, 0xc, 0xBa, 0x76, 0x98, 0x13, 0x8b, 0x46, 0x33, 0x2B, 0x25, 0xA2, 0x8b, 0x27,
0xB7, 0x61, 0x7C, 0x3F, 0x58, 0x56]
c = [0x18, 0xB1, 0x09, 0xA4, 0xA6, 0x2A, 0x9E, 0x1B, 0x96, 0x57, 0x5D, 0xAd, 0xAE, 0x75, 0x65, 0xAC, 0x09, 0x8C, 0xA0,
0x76, 0x47, 0x2C, 0x10, 0x01, 0x7C, 0x0f, 0xBa, 0x47, 0x95, 0x30, 0x9b, 0x74, 0x3f, 0x2D, 0x2D, 0x9A, 0x87, 0x31,
0xBa, 0x43, 0x70, 0x2C, 0x4C, 0x56]
flag = ''
for i in range(len(c)):
index = k[i] ^ c[i]
flag += base[index]
print(b64decode(flag))
"""
import ida_dbg
RAX = ida_dbg.get_reg_val("RAX")
print(hex(RAX),hex(get_wide_byte(0x65F508))))
"""

pic

有个图片附件,010 editor打开是乱码,被修改过了
image.png
再看可执行文件,是个GO
看看汇编,有个反调试简单修改ZF标志绕过一下,
image.png
要求输入key,长度为5
image.png
加密应该是个 rc4
image.png
image.png
最后异或一下key[1]0x11就行,我们直接爆破5位key
image.png
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
import itertools
from tqdm import tqdm

# 初始化 S 数组,使用 RC4 密钥调度算法(KSA)
def initialize(key):
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + ord(key[i % len(key)])) % 256
S[i], S[j] = S[j], S[i]
return S

# 生成密钥流,使用伪随机生成算法(PRGA)
def generate_key_stream(S, length):
i = j = 0
key_stream = []
for _ in range(length):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
key_stream.append(S[(S[i] + S[j]) % 256])
return key_stream

# 解密函数,通过 RC4 密钥流与输入数据进行异或运算
def decrypt(data, key):
S = initialize(key)
key_stream = generate_key_stream(S, len(data))
flag = [(data[i] ^ key_stream[i] ^ 17 ^ ord(key[1])) for i in range(len(data))]
if flag == [137, 80, 78, 71]: # 检查是否匹配 PNG 文件头标识符
return key

# 生成所有可能的 5 字符 RC4 密钥
def generate_rc4_key():
chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
return (''.join(key_tuple) for key_tuple in itertools.product(chars, repeat=5))

# 主程序,尝试每一个密钥进行解密
data = [0x85, 0x43, 0x72, 0x78]
for key in tqdm(generate_rc4_key()):
decrypted_key = decrypt(data, key)
if decrypted_key:
print(f"Found key: {decrypted_key}")
break
#Found key: 0173d

最后运行一下可执行文件,还原出png
flag.png
DASCTF{good_y0u_get_the_ffffflag!}

docCrack

宏病毒,微步沙箱启动,拿到宏代码和释放的temp.exe(或者用olevba)

1
2
pip install oletools
olevba ./protected_secret.docm --decode

image.png
image.png
image.png
看看宏代码关键的几处,这里当时没注意到异或了7
image.png
image.png
flag就是使temp.exe输出good的参数
可以尝试删除1173行,用修改过的宏代码获取temp.exe
新建一个文档,alt+F11把宏代码粘贴进去
调试获取到文件生成的位置
image.png
拿到文件
image.png
这里偷懒直接从微步拿到temp.exe
看看temp.exe
image.png
简单逆一下,但是不对得到CFTDSA|QefX6tXcfibuhrt&&&XE6pfubX7aXJfdu7XQ6ur2bt&&&z`
cyberchef魔棒启动
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#import Z3
#key = Z3.BitVec('ihakf`', 32)
#flag中的元素
v7 = [0] * 54
v7[0] = 4288
v7[1] = 4480
v7[2] = 5376
v7[3] = 4352
v7[4] = 5312
v7[5] = 4160
v7[6] = 7936
v7[7] = 5184
v7[8] = 6464
v7[9] = 6528
v7[10] = 5632
v7[11] = 3456
v7[12] = 7424
v7[13] = 5632
v7[14] = 6336
v7[15] = 6528
v7[16] = 6720
v7[17] = 6144
v7[18] = 6272
v7[19] = 7488
v7[20] = 6656
v7[21] = 7296
v7[22] = 7424
v7[23] = 2432
v7[24] = 2432
v7[25] = 2432
v7[26] = 5632
v7[27] = 4416
v7[28] = 3456
v7[29] = 7168
v7[30] = 6528
v7[31] = 7488
v7[32] = 6272
v7[33] = 5632
v7[34] = 3520
v7[35] = 6208
v7[36] = 5632
v7[37] = 4736
v7[38] = 6528
v7[39] = 6400
v7[40] = 7488
v7[41] = 3520
v7[42] = 5632
v7[43] = 5184
v7[44] = 3456
v7[45] = 7488
v7[46] = 7296
v7[47] = 3200
v7[48] = 6272
v7[49] = 7424
v7[50] = 2432
v7[51] = 2432
v7[52] = 2432
v7[53] = 7808
for i in range(54):
v7[i] = v7[i] >> 6
flag = ''.join([chr(i ^ 7) for i in v7])
print(flag)
#DASCTF{Vba_1s_dangerous!!!_B1ware_0f_Macr0_V1ru5es!!!}

DASCTF{Vba_1s_dangerous!!!_B1ware_0f_Macr0_V1ru5es!!!}

你这主函数保真么

主函数没有东西,但是看到了一个encrypt函数
一路交叉应用
image.png
先看看密文
image.png
check明显是类型分析错误了
image.png
全选之后按*转换成数组
image.png
看看ROT13和离散余弦变换
image.png
image.png
都没有魔改
直接np库一把梭了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
from scipy.fftpack import idct #导入idct函数用于离散余弦逆变换
import codecs
def idct_to_int(enc):
restored = idct(enc, norm='ortho') #使用idct函数进行离散余弦逆变换
ROT13_int = np.round(restored).astype(int) #将浮点数转换为整数
return ROT13_int
enc = [513.3551, -37.7985, 8.7317, -10.783100000000001, -1.3096, -20.5778, 6.98651, -29.2988, 15.9423, 21.413899999999998, 29.4755, -2.7715099999999997, -6.58784, -4.22322, -7.20761, 8.83516, -4.38128, -19.3897, 18.3454, 6.88269, -14.7651, 14.6103, 24.7415, -11.6221, -9.75466, 12.2425, 13.4344, -34.9306, -35.734899999999996, -20.0847, 39.6891, 21.8791, 26.8297]

ROT13_int = idct_to_int(enc) #调用idct_to_int函数
print(ROT13_int) #输出解密后的整数列表
#[81, 78, 70, 80, 71, 83, 123, 74, 117, 48, 95, 49, 102, 95, 90, 110, 49, 97, 95, 64, 97, 113, 95, 83, 104, 97, 97, 76, 95, 81, 112, 103, 125]

tmp = ''.join(chr(i) for i in ROT13_int)
flag = codecs.encode(tmp, 'rot_13') #使用rot_13编码
print(flag)
#DASCTF{Wh0_1s_Ma1n_@nd_FunnY_Dct}

DASCTF{Wh0_1s_Ma1n_@nd_FunnY_Dct}