查看: 2802|回复: 1
收起左侧

[原创分析] 一例针对 QQ 的 DLL 注入式数据窃取木马样本深度剖析

[复制链接]
瞬犀安全
发表于 2026-6-26 18:14:28 | 显示全部楼层 |阅读模式
近期,瞬犀安全实验室在终端安全检测中发现,多地网吧场景频发 QQ 账号被盗事件,溯源后成功定位到一款技术成熟的定向数据窃取木马程序。

该样本可在用户登录阶段静默截获账号敏感信息与业务通信数据,加密后回传至木马远端服务器,具备极强的隐蔽性与环境适配能力。中毒后的QQ会自动拉群、艾特好友并发送黑灰产消息。

下文将对该木马样本的完整攻击链路与核心技术实现进行深度拆解。

注入QQ的时机

木马样本会在持续监控进程信息,如果是QQ被拉起则会对QQ进行DLL注入。在用户还没有登录的时候获取用户的信息。

DLL注入之后的恶意行为

在注入QQ之后该DLL会直接创建一个线程执行恶意代码的操作(这个初始函数记作 StartAddress)。

之后解密在代码中已经加密的字符串去寻找对应的模块的信息,解密算法很简单,如果是宽字符通过XOR 递增 0x83. 解密关键字符串和 API 名。ASCII则是减去0x7D。



解密出来的数据如下:

StartAddress 的主要流程

1. 清空栈上缓冲区并获取当前 PID。
2. 解密 %d_txv_%d ,使用 PID * 26 和 PID * 21 生成动态 mutex 名。
3. 调用 CreateMutexW ,若发现已有实例则退出。
4. 读取自身版本资源,并从 VS_FIXEDFILEINFO 中取版本号。
5. 解密并检查固定 mutex F11CCD2AEEC5ABEC6A51D68AE34579E0 。
6. 循环等待 wrapper.node 加载,最多约 40 次,每次 Sleep(600ms) 。
7. 调用 sub_180001218 从 wrapper.node 路径解析 versions\%u.%u.%u-%u 版本。
8. 检查宿主文件名是否为 qq.exe 、 tim.exe 、 wegame.exe 或 tgp_daemon.exe 。
9. 解密 ntdll.dll 和 ZwProtectVirtualMemory 并保存函数地址到 qword_18004DB98 。
10. 初始化 hook 管理堆。
11. 调用 sub_180002978(wrapper.node) 扫描 .text 并注册 hook。
12. 调用 sub_18000D390(..., 1) 应用 hook。
13. 如果某些数据未就绪,则调用 sub_180003020 等待运行时结构并触发上报。
14. 退出前调用 sub_180007040 ,通过网络发送状态或错误信息。

wrapper.node 版本解析

主要是针对系统内不同的QQ版本信息执行不同的HOOK操作。
  • GetModuleFileNameW(hModule, Filename, 0x104) 获取模块路径。

2. 解密 versions\ 。
3. 使用 wcsstr(Filename, L"versions\\") 定位版本目录。
4. 跳过 versions\ 后,用 swscanf 格式 %[^\\] 取目录名。
5. 再用 %u.%u.%u-%u 解析版本四元组。

6. 将四个字段打包为 64-bit 值: packed_version = (((major << 16) | minor) << 16 |
patch) << 16 | build
样本中可见的版本分支:

寻找wrapper.node里面的inline hook点位

该函数首先把 `wrapper.node` 当作 PE 文件映像解析,随后判断 OptionalHeader magic。遍历
节表,寻找节名 `.text`,后续全部签名扫描都限制在 `wrapper.node` 的 `.text` 范围内。


匹配逻辑:
先计算所有模式项的总长度,确保不超过扫描范围。
从 start_offset 开始逐字节滑动。
对每个模式项:
若 type == 0x3F ,跳过 len 字节,不比较内容。
否则比较 bytes[0:len] 。
所有模式项匹配后返回当前偏移。
未找到返回 -1 。

对QQ的hook操作

sub_18000D120函数是上面的操作找到了合适的HOOK点位。并对对应的函数进行内联HOOK。

sub_18000264C 函数

函数内部会对内联HOOK里面的RCX寄存器+0x78的位置进行取值。之后通过判断数据的长度是否在命中的

长度范围内,如果命中了得进入更深一层的数据筛选。

更进一步的筛选则是为了筛选出感兴趣的编号,然后进行处理。处理方式有点类似TLV的数据结构解析。

sub_180002614 函数

如果sub_18000264C是对类似TLV数据结构的信息感觉兴趣,那么sub_180002614则是对类似
Protobuf类型的数据感兴趣。

依旧是通过rcx+0x78获得对应的数据,之后对数据的长度进行判断,然后对感兴趣的数据进行下一步解析。


疑似解析protobuf varint 的解码
sub_1800072B4 函数

这个函数则是保存了数据对象的内存地址

数据上报

在收集到数据之后,会把数据进行加密发送。同样的链接也进行了字符串加密。

在发送数据的时候为了避免被直接发现,还使用CryptoAPI和RC4进行加密,防止抓包软件直接
看出端倪。
注入后查看QQ内存

查看QQ的模块内存,已经被挂上了钩子。
跳转到钩子代码的内存地址进行查看,很典型的hook之后保存当前寄存器环境的汇编代码,并把进入自己流程的函数传递给RAX寄存器之后调用。
进入函数之后可以看到上面描述的在指定偏移的地方取内容,之后对数据长度进行对比的操作。
结论

该样本针对 wrapper.node 做了版本适配型 inline hook。它不依赖导出符号,而是通过 .text字节签名定位内部业务函数。Hook 的核心目的包括:
1. 截获 类似protobuf 业务消息,按字段路径提取嵌套数据。
2. 截获 类似TLV 业务包,提取固定 tag 数据。
3. 捕获 wrapper.node 内部上下文对象,并主动调用内部函数。
4. 将采集字段缓存后,通过压缩、RC4-like 加密和 RSA 公钥加密发送到远端。
从行为看属于面向特定宿主和特定 native 模块的窃取/监控型恶意代码,具备较强的版本适配性。

loCs:
MD5 :531ade06fd0fa223dc10c7c8dcc43d5e
SHA1:39ec6af2dcc79c02faa58a0de05127f357d3389c SHA256:0d5629da07f452ea1970ecd1cda24438f77ecd86cf95b71977b4394bc14c2c9b


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?快速注册

x

评分

参与人数 1经验 +30 魅力 +1 收起 理由
QVM360 + 30 + 1 版区有你更精彩: )

查看全部评分

夜光星
发表于 2026-6-28 12:18:52 | 显示全部楼层
网吧确实是盗号病毒的重灾区,我以前遇到过修改版的steam客户端,幸好号没事
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|杀毒软件|软件论坛| 卡饭论坛

Copyright © KaFan  KaFan.cn All Rights Reserved.

Powered by Discuz! X3.4( 沪ICP备2020031077号-2 ) GMT+8, 2026-10-19 09:13 , Processed in 0.076719 second(s), 4 queries , Redis On.

卡饭网所发布的一切软件、样本、工具、文章等仅限用于学习和研究,不得将上述内容用于商业或者其他非法用途,否则产生的一切后果自负,本站信息来自网络,版权争议问题与本站无关,您必须在下载后的24小时之内从您的电脑中彻底删除上述信息,如有问题请通过邮件与我们联系。

快速回复 客服 返回顶部 返回列表