点个蓝字关注我们











分 析





payload自我修复





第一阶段shellcode解密


from binaryninja import *"""00000000001BCE2F | 49:C1EA 00 | shr r10,0 |00000000001BCE33 | 5B | pop rbx |00000000001BCE34 | EB 04 | jmp 1BCE3A |00000000001BCE36 | 48:C1EF 00 | shr rdi,0 |00000000001BCE3A | C143 04 D5 | rol dword ptr ds:[rbx+4],D5 |00000000001BCE3E | F753 08 | not dword ptr ds:[rbx+8] |00000000001BCE41 | F753 0C | not dword ptr ds:[rbx+C] |00000000001BCE44 | 4D:0F4BFF | cmovnp r15,r15 |00000000001BCE48 | C143 10 0C | rol dword ptr ds:[rbx+10],C | rbx+10:"-\v"00000000001BCE4C | FFE3 | jmp rbx |"""def rol(x, n):n %= 32return ((x << n) | (x >> (32 - n))) & 0xFFFFFFFFdef decrypt():bv = current_viewTARGET_VA = 0x140086f39DATA_SIZE = 0xCE4Edata = bytearray(bv.read(TARGET_VA, DATA_SIZE))print(f"[*] Read {len(data)} bytes from 0x{TARGET_VA:x}")with open("decrypted_before.bin", "wb") as f:f.write(data)# 指令修复d0 = int.from_bytes(data[0x05:0x09], 'little')d1 = int.from_bytes(data[0x09:0x0D], 'little')d2 = int.from_bytes(data[0x0D:0x11], 'little')d3 = int.from_bytes(data[0x11:0x15], 'little')d4 = int.from_bytes(data[0x15:0x19], 'little')d1 = rol(d1, 0xD5)d2 = ~d2 & 0xFFFFFFFFd3 = ~d3 & 0xFFFFFFFFd4 = rol(d4, 0xC)data[0x05:0x09] = d0.to_bytes(4, 'little')data[0x09:0x0D] = d1.to_bytes(4, 'little')data[0x0D:0x11] = d2.to_bytes(4, 'little')data[0x11:0x15] = d3.to_bytes(4, 'little')data[0x15:0x19] = d4.to_bytes(4, 'little')# xor 解密key = 0xD2DECRYPT_SIZE = 0xCE09DATA_OFFSET = 0x25for i in range(DECRYPT_SIZE - 1, -1, -1):idx = DATA_OFFSET + idata[idx] ^= (key & 0xFF)key = (key + data[idx]) & 0xFFprint(f"[+] Decrypted {DECRYPT_SIZE} bytes")with open("decrypted_after.bin", "wb") as f:f.write(data)print("[+] Done!")if __name__ == "__main__":decrypt()



第一阶段shellcode分析








第二阶段shellcode解密



def decrypt_data_2f():bv = current_viewdata = bv.read(0x2f, 0xAE05)with open("data_2f.bin", "wb") as f:f.write(data)key = b"4@e!c!bSL2AeimnwyD4x"decrypted = bytearray(data)for i in range(len(data)):decrypted[i] = data[i] ^ key[i % len(key)]with open("data_2f_decrypted.bin", "wb") as f:f.write(decrypted)print(f"[+] Decrypted {len(decrypted)} bytes")print("[+] Saved to data_2f_decrypted.bin")

第二阶段shellcode分析






下一步还是检测自身是否被模拟执行,遍历 ntdll.dll 中导出函数名哈希是否为下面三个其中之一
0x70CE7692
0xD4CE4554
0x7A99CFAE






sub_2c35
sub_27e5
sub_29b5
sub_2715
sub_23a5
sub_2d45
sub_2c35
先解密字串,获取 pid.dll 中 DllGetClassObject 地址并调用来检测是否被模拟执行,原理是为了加快分析速度、避免执行恶意代码或因为不完整的系统环境,一些沙箱或模拟器并不会完整实现复杂的 COM 查找和加载机制。它们可能会直接劫持对 DllGetClassObject 的调用,并总是返回错误码 CLASS_E_CLASSNOTAVAILABLE (即 0x80040111),表示这个类不可用








当虚拟环境检测完毕后,接着通过遍历进程的方式检测当前环境中是否运行以下进程
360tray.exe
360sd.exe
360safe.exe



sub_85f5










从解开的数据可以获取以下信息
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/a.gif
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/b.gif
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/c.gif
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/d.gif
install.exe
UxEnhance64.dll
msadox.tb
adoresd.dat
在 Public 创建一个隐藏目录,目录文件名为随机生成 6 位字符串

继续拼接,其中三个文件名固定,另以 .exe 结尾的同样也是随机生成的 6 位字符串

完成后又开始检测是否存火绒杀毒软件

当检测不到火绒杀毒软件时,继续检测其它杀毒软件,其中涵盖了
Bka*:一家越南安全公司开发的安全杀毒产品 Bkav (看来也针对东南亚地区)
cefutil、QHSafeTray:360
k*:金山



以下为对应关系
a.gif -> YzhYCq.exe
b.gif -> UxEnhance64.dll
c.gif -> msadox.tb
d.gif -> adoresd.dat
以上都是从 gif 文件偏移 0x3A0 处开始,逐字节异或,异或起始 key 为 0x45,每次异或后 key 自增 1








347acba74fdcbeac671521739f8a34ec0e378caf716c31f55616f9f843e4d0d3

第三阶段shllcode解密




第三阶段shellcode分析




VirtuOne 导出函数开始创建绑定字符串,包含
任务调度器 RPC 接口 UUID (86D35949-83C9-4044-B424-DB363231FD0C)
命名管道协议 ncacn_np
连接到本机 localhost
管道名 \pipe\atsvc

这是建立 RPC 绑定过程,接着构建任务 XML,将传递给 VirtuOne 的参数写入 XML 模板中

XML 中包含
登录触发器 (任何用户登录系统时)
时间触发器 (每隔 1 分钟执行一次)
最终以管理员执行
默认启用
不允许硬终止
执行文件 YzhYCq.exe
<?xml version="1.0" encoding="UTF-16"?><Taskversion="1.2"xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"><RegistrationInfo><Description/><URI>\</URI></RegistrationInfo><Triggers><LogonTrigger><Enabled>true</Enabled></LogonTrigger><TimeTrigger><Repetition><Interval>PT1M</Interval><StopAtDurationEnd>false</StopAtDurationEnd></Repetition><StartBoundary>2009-04-23T00:00:00</StartBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Principals><Principalid="Author"><GroupId>S-1-5-32-545</GroupId><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>true</StopIfGoingOnBatteries><AllowHardTerminate>false</AllowHardTerminate><StartWhenAvailable>true</StartWhenAvailable><RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable><IdleSettings><StopOnIdleEnd>true</StopOnIdleEnd><RestartOnIdle>false</RestartOnIdle></IdleSettings><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true</Enabled><Hidden>true</Hidden><RunOnlyIfIdle>false</RunOnlyIfIdle><WakeToRun>false</WakeToRun><ExecutionTimeLimit>PT0S</ExecutionTimeLimit><Priority>4</Priority></Settings><ActionsContext="Author"><Exec><Command>C:\Users\Public\vZaBEp\YzhYCq.exe</Command><WorkingDirectory>C:\Users\Public\vZaBEp\</WorkingDirectory><Arguments /></Exec></Actions></Task>
设置 QoS 标志,调用 RPC 方法 (NdrClientCall3 是 NDR 客户端 Stub 调用函数)


后续便是一顿清理操作,这就完了?不,以上这种情况是通过外在一个 arg1 参数控制,当为 0 时,才有以上这些行为,当不为 0 时,则会创建 vbs 脚本

sub_85f5 参数由 var_d0_1 控制,而这个变量一开始就为 0,当一开始检测到存在 360 相关软件时会将此值设为 1

假如一开始就检测到存在 360 相关进程,var_d0_1 被设置为 1,后续才会去创建这个 vbs 脚本,脚本名为 checktime.vbs

On Error Resume NextSet WShell = CreateObject("WScript.Shell")WShell.Run """arg2 = C:\Users\Public\vZaBEp\YzhYCq.exe""", 0, FalseSet WShell = NothingWScript.Quit
那后面计划任务就不是直接执行 YzhYCq.exe,而是执行此 vbs 脚本,再由它去执行 YzhYCq.exe。

另一种情况

若一开始就检测到 360 相关程序时,会先去创建一个线程,线程函数 sub_3525

在接下一个 while 循环中,也会创建相同线程,创建 3 次

这些操作针对性较强 (360),线程函数

sub_2f95 是一个破坏性函数,它会获取系统所有的 TCP 连接,然后筛选属于 360safe.exe 的连接,强制将这些连接状态设置为 CLOSE_WAIT (0xC),从而终止 360 的网络通信,避免云查杀,无法上报可疑行为,无法更新病毒库


YzhYCq.exe

母体文件曲曲折折到头来就是为了将 YzhYCq.exe 执行,该文件带有有效的腾讯签名


UxEnhance64.dll

YzhYCq.exe 运行后会加载同目录下的 UxEnhance64.dll 文件





msadox.tb解密





msadox.tb分析






adoresd.dat




执行后,在 C:\Program Files (x86) 目录下生成 LKeZ3k 的目录,并在其释放以下文件
LKeZ3k.exe
image.png
thumbs.db
XPSPLOG.dll
添加一项计划任务,用于启动 LKeZ3k.exe

LKeZ3k.exe

LKeZ3K 是一个带有有效签名的程序


XPSPLOG.DLL




thums.db解密



thums.db分析




image.png









连接
https[:]//new2027.oss-cn-hongkong.aliyuncs.com/dsb-hr1.png -> xxx.exe
https[:]//new2027.oss-cn-hongkong.aliyuncs.com/dsb-hr2.png -> xxx.dat
https[:]//new2027.oss-cn-hongkong.aliyuncs.com/dsb-hr3.png -> xxx.png








9XWMuT53.exe


9XWMuT53.dat


C:\Users\[username]\AppData\Local\Temp\_ir_tu2_temp_x



线程函数首先通过函数哈希方式获取以下 API
CreateFileW
GetFileSize
ReadFile
CloseHandle
VirtualAlloc
GetModuleFileNameW
读取同目录下 9XWMuT53.png



9XWMuT53.png

50 40 73 73 77 30 33 64 00 DE 9C AB FE CC D0 12

接着通过函数哈希方式获取以下 API 地址
VirtualFree
VirtualProtect
LoadLibraryA
GetProcAddress
最后反射加载解密后的 PE (DLL) 数据,执行 PluginMe 导出函数 (这个名称有点熟悉)









远程连接并将数据保存为文件,但因失效,无法获取其内容,在这里猜测下应该是后门模块。在线程 sub_100024e0 中,会去连接一个 IP (104[.]224.159.87),目标失效,强行修改条件成立












sVG0NLPh.exe








总 结


参 考

[1] https://research.checkpoint.com/2025/large-scale-exploitation-of-legacy-driver/

IoCs

Hash:
d8e92d3ddab6bb66a96febfbe400255b
af87b4b30fc786c7eb4f0c7c01f86154
9ec587911e501b73b7cf09f05d0ae17d
2e8bf1a995fadc6c0f663f4cb76f174f
817b1e5490fa19fb9f55d085109cfbe7
a827170abe2db4eb602b1dfe1c602b98
9cf1b3962ab8b8707103c8d27a2ab3a2
db8510d6a45a657dd46e8cd31cabbb22
9ba2c9ad95b35d9fe9ed7f2428aae19c
f12fac7501404eee0e6b630633f59d56
6700e68521100873a339688902a5547f
7e6a9f404d81ea85bbfd1f118211b680
URL:
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/a.gif
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/b.gif
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/c.gif
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/d.gif
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/s.dat
https[:]//0nbay3.oss-cn-beijing.aliyuncs.com/s.jpg
https[:]//2026mn.oss-cn-hongkong.aliyuncs.com/qd.dat
https[:]//new2027.oss-cn-hongkong.aliyuncs.com/extra-task2.png
https[:]//new2027.oss-cn-hongkong.aliyuncs.com/dsb-hr1.png
https[:]//new2027.oss-cn-hongkong.aliyuncs.com/dsb-hr2.png
https[:]//new2027.oss-cn-hongkong.aliyuncs.com/dsb-hr3.png
http[:]//new2027.oss-cn-hongkong.aliyuncs.com/page-404.png
http[:]//cinskw.net:6090/license
qcpcui[.]net
IP:
104[.]224.159.87
118[.]107.32.216:8050 (疑似挖矿)
C2:
8[.]218.35.71
8[.]218.125.215
47[.]243.218.255
Mutex:
26f3475fc22
48c47662941
E2D0491F7A75AE94FCCD983BDDFDOLED
218650560-777617685-4287762684-137415000
夜雨聆风