初看木马
一题:socks_proxy
SOCKS 5 是一种网络代理协议,全称是 Socket Secure 5。它工作在 OSI 模型的第 5 层(会话层),能够在客户端和服务端之间透明地中继 TCP(以及 UDP)流量。与传统的 HTTP 代理不同,SOCKS 5 不关心具体应用层协议是什么,只要基于 TCP 或 UDP 的数据流,它都可以代为转发,因此常被用作通用代理或反向代理工具的基础协议。
SOCKS 5 的核心特性
-
认证支持
SOCKS 5 在握手阶段支持多种认证方式,最常见的包括:-
0x00:无须认证 -
0x02:用户名/密码认证
代码中出现了VER=0x05 METHOD=0x00,正是表示 SOCKS 5 协议版本为 5,认证方式为“无认证”。
-
-
支持多种地址类型
SOCKS 5 可以代理 IPv 4、IPv 6 和域名连接(域名会自动解析),这使得它能灵活转发各种目标地址的流量。 -
传输层无关性
不管被代理的数据是 HTTP、FTP、SMTP 甚至二进制自定义协议,SOCKS 5 都不解析内容,只负责维持客户端和目标之间的原始数据流。
样本中,socks_proxy.exe 是一个SOCKS 5 反向代理木马。它的工作原理大致是:
-
内网穿透
受害主机主动向外网攻击者的 C 2 服务器发起 TCP 连接(反向连接)。 -
建立 SOCKS 5 通道
成功连接后,在受害主机上启动一个 SOCKS 5 代理服务。 -
流量中继
攻击者通过 C 2 服务器将 SOCKS 5 请求转发到受害内网,受害主机再把请求代理到内部其他目标,并把响应回传。这样攻击者就像“进入了内网”一样,可以访问原本无法直接触及的内部资源(数据库、文件共享、内网网站等)。
代码中的模拟片段完美还原了这一过程:
-
反向 TCP 到 C 2 地址(
off_1400A6000)的 8443 端口; -
日志
"[SIM] SOCKS5 VER=0x05 METHOD=0x00"模拟握手; -
日志
"[SIM] Client->Target %d bytes"和"[SIM] Target->Client %d bytes"模拟双向数据中继; -
心跳包则用来保持连接存活,防止被网络设备超时断开。
因此,题中虽然标了 [SIM](模拟),但攻击者的真实意图就是把受害机器变成到达内网的跳板,而 SOCKS 5 协议因其简洁、通用和高隐蔽性,成为这类远控木马的首选代理协议之一。
在代码中的具体体现

-
使用
CreateMutexA创建一个命名的互斥体(名称存储在全局变量lpName中)。 -
GetLastError() == 183对应ERROR_ALREADY_EXISTS,表示已有同名互斥体存在,说明程序已在运行。 -
如果是重复实例,输出日志后释放句柄并退出;否则继续执行,保证系统内只有一个木马实例运行。

-
使用 Windows CNG API (
BCrypt*) 进行解密。 -
算法:AES-256-CBC,密钥为
"DarkProxy_AES256Key!@2024_Cfg!~!"(正好 32 字节)。 -
IV:数据段中的 128 位变量
xmmword_14008F068(实际值为"Pr0xy!IV!2024!!!",注意第三个字符是数字 0)。 -
密文:位于
byte_1400A6040,共 64 字节(0 x 40)。 -
解密后的明文(去除 PKCS #7 填充)存入缓冲区
v51,并记录实际长度。成功则置v10=1。 -
随后根据
v10输出不同日志,表明解密成功或失败。
结果:v51 中得到一个数据库连接字符串,这是后续“模拟数据库连接”步骤中的目标地址。

-
通过 WinAPI 获取真实的主机名和用户名。
-
操作系统和 IP 地址完全是硬编码的假信息,说明目前是模拟环境。
-
所有信息拼接为日志输出,模拟木马的“侦查”行为。

-
off_1400A6008和off_1400A6010是硬编码的字符串指针,通常对应于某个注册表项和值名。 -
模拟木马将自己添加到
HKEY_CURRENT_USER\...\Run下,值名为svchost.exe,实现开机自启动。 -
同样是日志模拟,未真正修改注册表。

-
重连尝试:变量
v3从 0 开始,每次循环++v3,循环条件为v3 < 3,所以实际只执行 2 次(v3=1,2)。但日志打印显示Attempt %d/50,暗示真实木马可能尝试 50 次,这里只是模拟。 -
反向 TCP 连接:C 2 地址取自
off_1400A6000[0],端口8443。连接后输出[SIM] Connected。 -
SOCKS 5 握手:版本
0x05,认证方式0x00(无认证)。 -
数据中继循环:用递增的
i和v31模拟不同大小的数据包在客户端和目标之间转发,代表木马在受害内网与其他主机之间代理流量。 -
心跳包:向 C 2 发送心跳,间隔 30 秒,保持连接活跃。
-
循环结束后没有额外清理,如果互斥体句柄有效则关闭,程序正常返回 0。
回到这道题:
swprintf(v49, "[SIM] Connecting to: %s", v51) —— 说明 v51 就是数据库连接字符串。所以只要解密得到 v51,即可获得 Flag。
四项要素:
|要素|值|来源|
|---|---|---|
|算法|AES-256-CBC|`BCryptOpenAlgorithmProvider(L"AES")` + `ChainingModeCBC`|
|密钥|`DarkProxy_AES256Key!@2024_Cfg!~!`|硬编码字符串,32字节|
|IV|`xmmword_14008F068`|位于 `.rdata` 的 128 位数据|
|密文|`byte_1400A6040`|位于 `.data` 的 64 字节数据|
写出脚本即可
key = b"DarkProxy_AES256Key!@2024_Cfg!~!"
iv = b"Pr0xy!IV!2024!!!"
ciphertext = bytes.fromhex("CDAB5FAB...245D") # 64字节
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext)
# 去除PKCS#7填充
pad_len = plaintext[-1]
db_conn = plaintext[:-pad_len].decode()
print(f"flag{{{db_conn}}}")
所以这题比较简单,只要理解代码的处理逻辑就可以了

浙公网安备 33010602011771号