应急行动-1

利用取证大师分析VM虚拟机镜像

分析Apache日志,发现多次访问了<font style="color:rgb(0, 0, 0);">AgentBoard.XGI</font>这个路径

搜了一下,发现是瑞友天翼应用虚拟化系统RCE漏洞

继续分析所有访问这个路径的IP

在第312行日志中发现写了一个一句话木马

所以flag为flag{192.168.56.128 21/04/2025}

应急行动-2(复现)

从取证大师中可以看到,攻击者下载了Edge浏览器,在下载历史可以看到下载了rclone

rclone可以挂载网盘,结合题目说的流量异常,很大可能为攻击者用来窃取数据用的(我居然没有留意该软件是干嘛的)

所以在rclone.conf的配置文件中找到flag

flag{oisienfpqwlmdouydrsbhuisjAUGEDW}

应急行动-3

在取证大师中查看该文件的朔源

C:\Program Files (x86)\RealFriend\Rap Server\WebRoot\casweb\Home\View\Index\index.html

2025-04-21 23:39:28发现变更

所以flag为flag{2025-04-21 23:39:28}

应急行动-4

flag1{zheshi}

flag2{yige}

flag{ni}

flag4{xiangbudaodeflag}

最终flag为flag{zheshiyigenixiangbudaodeflag}

应急行动-5(复现)

通过题目提示知道要找的是加密程序,在真实的应急响应中,寻找加密器主要通过加密文件的修改时间、加密器常见路径(启动项,music,temp,users等目录下)、常见的加密器名称等线索排查加密器,在这里我们可以上传一个everything方便查找,可以看到一个名为Encryptor123的程序,很明显这就是我们要找的目标。

flag{Encryptor123.exe}

可疑文件

直接把dll扔进IDA

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
__int64 __fastcall sub_18007ABE0(__int64 a1, __int64 a2)
{
char *v2; // rdi
__int64 i; // rcx
_BYTE v5[32]; // [rsp+0h] [rbp-20h] BYREF
char v6; // [rsp+20h] [rbp+0h] BYREF
int v7; // [rsp+30h] [rbp+10h] BYREF
_BYTE v8[4]; // [rsp+34h] [rbp+14h] BYREF
_BYTE v9[4]; // [rsp+38h] [rbp+18h] BYREF
_BYTE v10[4]; // [rsp+3Ch] [rbp+1Ch] BYREF
_BYTE v11[4]; // [rsp+40h] [rbp+20h] BYREF
_BYTE v12[4]; // [rsp+44h] [rbp+24h] BYREF
_BYTE v13[4]; // [rsp+48h] [rbp+28h] BYREF
_BYTE v14[4]; // [rsp+4Ch] [rbp+2Ch] BYREF
_BYTE v15[4]; // [rsp+50h] [rbp+30h] BYREF
_BYTE v16[4]; // [rsp+54h] [rbp+34h] BYREF
_BYTE v17[4]; // [rsp+58h] [rbp+38h] BYREF
_BYTE v18[4]; // [rsp+5Ch] [rbp+3Ch] BYREF
_BYTE v19[4]; // [rsp+60h] [rbp+40h] BYREF
_BYTE v20[4]; // [rsp+64h] [rbp+44h] BYREF
_BYTE v21[4]; // [rsp+68h] [rbp+48h] BYREF
_BYTE v22[24]; // [rsp+6Ch] [rbp+4Ch] BYREF
int j; // [rsp+84h] [rbp+64h]
int k; // [rsp+A4h] [rbp+84h]
int m; // [rsp+C4h] [rbp+A4h]
int *v26; // [rsp+198h] [rbp+178h]

v2 = &v6;
for ( i = 50LL; i; --i )
{
*(_DWORD *)v2 = -858993460;
v2 += 4;
}
sub_1800770F7((__int64)&unk_1801AD0A3);
sub_1800757E3((__int64)&v7, a1, 64LL);
for ( j = 0; j < 20; j += 2 )
{
v26 = &v7;
sub_18007B4B0(&v7, v11, v15, v19);
v26 = (int *)v8;
sub_18007B4B0(v8, v12, v16, v20);
v26 = (int *)v9;
sub_18007B4B0(v9, v13, v17, v21);
v26 = (int *)v10;
sub_18007B4B0(v10, v14, v18, v22);
v26 = &v7;
sub_18007B4B0(&v7, v12, v17, v22);
v26 = (int *)v8;
sub_18007B4B0(v8, v13, v18, v19);
v26 = (int *)v9;
sub_18007B4B0(v9, v14, v15, v20);
v26 = (int *)v10;
sub_18007B4B0(v10, v11, v16, v21);
}
for ( k = 0; k < 16; ++k )
*(_DWORD *)&v8[4 * k - 4] += *(_DWORD *)(a1 + 4LL * k);
for ( m = 0; m < 16; ++m )
{
*(_BYTE *)(a2 + 4 * m) = v8[4 * m - 4];
*(_BYTE *)(a2 + 4 * m + 1) = BYTE1(*(_DWORD *)&v8[4 * m - 4]);
*(_BYTE *)(a2 + 4 * m + 2) = BYTE2(*(unsigned int *)&v8[4 * m - 4]);
*(_BYTE *)(a2 + 4 * m + 3) = HIBYTE(*(unsigned int *)&v8[4 * m - 4]);
}
++*(_DWORD *)(a1 + 48);
return sub_180076850((__int64)v5, (__int64)&unk_180167C40);
}

最终逆向脚本

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

def chacha20_quarter_round(a, b, c, d):
"""ChaCha20四分之一轮实现"""
a = (a + b) & 0xFFFFFFFF
d ^= a
d = ((d << 16) | (d >> 16)) & 0xFFFFFFFF # ROL16
c = (c + d) & 0xFFFFFFFF
b ^= c
b = ((b << 12) | (b >> 20)) & 0xFFFFFFFF # ROL12
a = (a + b) & 0xFFFFFFFF
d ^= a
d = ((d << 8) | (d >> 24)) & 0xFFFFFFFF # ROL8
c = (c + d) & 0xFFFFFFFF
b ^= c
b = ((b << 7) | (b >> 25)) & 0xFFFFFFFF # ROL7
return a, b, c, d

def chacha20_block(key, counter, nonce):
"""生成64字节密钥流(修正状态矩阵)"""
constants = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]
key_words = list(struct.unpack('<8I', key))

# 确保状态矩阵有16个元素
state = [
constants[0], constants[1], constants[2], constants[3],
*key_words[:4], # 密钥前4字
*key_words[4:8], # 密钥后4字
counter, # 块计数器(32位)
nonce[0], nonce[1], nonce[2] # Nonce为3个32位字
]

initial_state = state.copy()

# 20轮混淆处理
for _ in range(10):
# 列处理
state[0], state[4], state[8], state[12] = chacha20_quarter_round(state[0], state[4], state[8], state[12])
state[1], state[5], state[9], state[13] = chacha20_quarter_round(state[1], state[5], state[9], state[13])
state[2], state[6], state[10], state[14] = chacha20_quarter_round(state[2], state[6], state[10], state[14])
state[3], state[7], state[11], state[15] = chacha20_quarter_round(state[3], state[7], state[11], state[15])
# 行处理
state[0], state[5], state[10], state[15] = chacha20_quarter_round(state[0], state[5], state[10], state[15])
state[1], state[6], state[11], state[12] = chacha20_quarter_round(state[1], state[6], state[11], state[12])
state[2], state[7], state[8], state[13] = chacha20_quarter_round(state[2], state[7], state[8], state[13])
state[3], state[4], state[9], state[14] = chacha20_quarter_round(state[3], state[4], state[9], state[14])

# 叠加初始状态并序列化
block = [(state[i] + initial_state[i]) & 0xFFFFFFFF for i in range(16)]
return struct.pack('<16I', *block)

def decrypt_file(enc_path, password):
"""解密主函数(修正Nonce)"""
key = password.encode().ljust(32, b'\x00')[:32]
counter = 0
nonce = (0, 0, 0) # Nonce扩展为3个32位字

with open(enc_path, 'rb') as fin:
while True:
key_stream = chacha20_block(key, counter, nonce)
counter += 1
chunk = fin.read(64)
if not chunk:
break
decrypted = bytes( ((c - 1) % 0x100) ^ key_stream[i] for i, c in enumerate(chunk) )
print(decrypted)

if __name__ == '__main__':
decrypt_file('flag.enc', 'qewuri')
# flag{sierting_666_fpdsajf[psdfljnwqrlqwhperhqwoeiurhqweourhp}