ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

AfKayAs.2远控木马深度解析:从样本结构到检测规则

AfKayAs.2远控木马深度解析:从样本结构到检测规则 拿到这个样本的时候我习惯性地先看了一眼文件哈希然后在沙箱里丢了一把。AfKayAs.2这个名字在威胁情报社区里其实不算陌生它是某个远控木马家族的升级变种前一代AfKayAs.1曾经在不少攻防演练和真实攻击场景里出现过。但AfKayAs.2这个版本不一样它改了很多底层实现包括C2通信方式、加密算法、持久化逻辑甚至对沙箱检测和调试器的对抗都做了加强。这篇博文我就以实际分析过的样本为基础把这套远控的木马机制完整拆开从静态结构到动态行为从C2协议到检测规则完整走一遍。如果你是安全蓝队的成员、恶意代码分析方向的初学者或者正在做威胁狩猎和应急响应这篇内容对你应该会有实际帮助。我尽量不用教科书式的语言每一部分都结合具体的分析操作和踩坑经历来讲争取让看完的人能直接上手。1. 样本画像与功能定位1.1 先搞清楚它到底是什么AfKayAs.2是一个典型的远程访问木马也就是大家常说的RAT。这类木马的核心目的就一个字控。把受害机器的控制权拿到手然后执行攻击者下发的指令。和普通蠕虫、勒索软件不同RAT不追求自我复制和批量加密文件它更像个潜伏者安安静静地待在系统里随时听候指令。在我分析的这批样本里AfKayAs.2的主程序是一个32位的PE文件图标被伪装成PDF文档的样式。这个细节很有意思说明它的投放方式大概率是钓鱼邮件附件或者即时通讯软件的文件传输用社会工程学诱导目标手动打开。文件名也很有迷惑性常见的有“Invoice_20240621.exe”、“Details.scr”之类的乍一看就是个普通文档快捷方式。从编译时间戳来看样本似乎是在今年上半年打包的但说实话编译时间戳这东西根本不能信。修改PE头里的TimeDateStamp字段只需要一个十六进制编辑器几秒钟就能伪造完。在真正分析的时候我更倾向于看导入表、资源段和代码风格来判断样本的真实“年龄”。1.2 版本命名背后的信息AfKayAs.2这个名称中的“.2”代表了这是该RAT家族的第二代主要版本。根据我对前代样本的对比二代版本至少做了以下几个重要升级第一通信协议从简单的明文HTTP POST变成了自定义加密的二进制协议。一代版本抓包就能看到指令内容二代版本就算抓到了包看到的也是一堆密文。第二反分析能力全面增强加入了对沙箱主机名、CPU核心数、屏幕分辨率的检测甚至还会检测鼠标移动轨迹如果发现没有任何人工操作痕迹就会直接退出。第三插件系统重写从原来的静态编译功能变成了可动态加载的插件模块攻击者可以随时下发新插件扩展功能。这里要解释一下为什么RAT家族要频繁升级版本。根本原因是攻防双方的信息不对称在缩小。蓝队和杀毒厂商会从被捕获的样本中提取特征生成检测规则和查杀签名。木马作者要生存就必须不断改变实现方式、加密算法和行为特征始终保持对检测规则的领先。AfKayAs.2就是这个逻辑下的产物。2. 静态分析不用运行就能看出门道2.1 文件格式与加壳情况把样本丢进DIEDetect It Easy里先查一下壳结果显示是“UPX v0.90 - 1.24”。UPX是很老牌的压缩壳好处是上手简单、兼容性好坏处是特征太明显。几乎稍微有点经验的蓝队看到UPX标志就会警觉所以很多木马作者会先脱壳再重新加一个自定义壳或者直接做代码虚拟化。这个样本直接用了标准UPX有几种可能要么作者对自身技术有信心觉得靠通信加密和反沙箱就够用了要么就是开发团队里有新人参与图省事用了现成方案。从实际对抗角度来看标准UPX壳瞬间缩小的检出面其实有限因为杀毒引擎的静态扫描可以自动脱UPX壳真正的护城河还是壳下面的代码逻辑。我习惯的做法是先用upx -d尝试脱壳。这个样本可以直接脱掉脱壳之后文件体积从原来的180KB左右涨到了310KB左右多出来的就是被压缩的原始代码和数据段。如果UPX脱壳失败我就用x64dbg手动拉一下在入口点附近找到popad指令跟着跳转就能到原始入口点OEP。这次运气不错一步到位。2.2 导入表透露的关键线索脱壳后把样本拖进IDA Pro先不急着看反编译代码而是直接看导入表Import Table。导入函数就像一个人的生活习惯能一眼看出他大概干过什么。这个样本的导入表重点关注这几个APIInternetOpenA、InternetConnectA、HttpSendRequestA说明核心通信走的是WinINet库的HTTP接口。RegCreateKeyExA、RegSetValueExA大概率有注册表自启动项。CreateToolhelp32Snapshot、Process32FirstW、Process32NextW遍历进程用于检测杀软进程或者寻找特定目标进程。GetDC、GetSystemMetrics获取屏幕分辨率和DC句柄对应屏幕截图功能。SetWindowsHookExA安装键盘钩子对应键盘记录功能。这里有一个分析上的信息差这些API只是样本导入的函数不代表全部功能都是通过它们完成的。高级样本通常会用GetProcAddress动态加载API来隐藏真实意图所以导入表只能作为第一层线索真正的功能还要结合反汇编代码来确认。2.3 字符串与加解密逻辑用Strings工具扫描样本的字符串段能看到几类明显特征。第一部分是C2服务器地址看起来是个动态域名格式是http://update-api[.]dynamic-dns[.]net/panel.php。动态域名在RAT里非常常见因为攻击者可以随时更改DNS解析指向换服务器也不用重新编译样本。第二部分是加密相关的字符串其中有一组硬编码的密钥长度是16字节看起来是AES-128的密钥格式。还有一段Base64变种编码表和标准Base64的字母表顺序不一样。这种自定义Base64变体是木马界的主流手法因为标准Base64的字符集太明显用静态特征扫描一下就能识别。第三部分是配置信息包括分组名称、回连间隔时间、安装名称、互斥体名称等。互斥体名称是防止多开的关键机制木马在运行时创建互斥体如果互斥体已经存在说明系统里已经有实例在运行了就不再创建新进程避免多个实例互相干扰。回到IDA里追踪加密函数的调用关系发现样本用了LZMA解压算法来释放内嵌的载荷。LZMA的压缩率比Zlib更高主要用于压缩内嵌的DLL插件和执行配置。整个解压流程是在内存中完成的不会落盘这给AV的实时监控增加了难度因为杀毒软件默认更关注磁盘文件的新增和写入对纯内存操作检测能力相对有限。3. 动态行为分析运行之后它到底干了什么3.1 运行前准备与反沙箱逻辑静态分析只能看到骨架血肉还是得靠动态行为分析来填。我在VirtualBox里搭了一个Windows 10 x64的虚拟机用Procmon监控注册表和文件系统用Wireshark抓取网络流量再配合x64dbg做调试三管齐下。把样本放到虚拟机里双击运行等待几秒后进程出现了然后立刻消失了。第一次运行进程直接退出原因想都不用想就是反沙箱检测。重新启动样本这次我先把网络断开然后快速查看进程状态发现样本会先执行一系列检测函数检测逻辑顺序大概是这样的样本先调用GetSystemMetrics获取屏幕分辨率如果分辨率低于800x600直接退出。因为真的用户显示器分辨率一般不会这么低而很多自动沙箱的默认分辨率就是800x600或者更低。接着调用GlobalMemoryStatusEx检查物理内存大小如果小于2GB就退出这个阈值同样是卡沙箱的资源限制。然后获取CPU核心数少于2核就退出。最后枚举进程列表对比内置的黑名单如果发现vboxservice.exe、vmwaretray.exe、xenservice.exe这类虚拟机工具进程同样直接退出。最让我意外的是它还有一个鼠标轨迹检测。工具会读取GetCursorPos的位移记录如果启动后的5分钟内完全没有检测到鼠标移动事件就会把自己退出。这个技术在2018年之后的RAT里越来越多见因为大部分自动化分析沙箱不会模拟鼠标移动这个检测就能有效挡住一批沙箱。跑过一次之后我的做法是先改虚拟机配置让CPU核心数达到4核、内存调到4GB、屏幕分辨率改为1920x1080同时在宿主机上定期移动鼠标防止轨迹检测误判。绕过反沙箱之后样本开始正常释放行为。它会在%APPDATA%下创建隐藏目录MicrosoftMediaCache然后把自身复制到该目录下命名为MediaCacheService.exe。这个目录名字起得很“干净”看起来像是正常的软件缓存目录容易混在大量系统噪音里。3.2 持久化与自启动机制木马落盘之后紧接着就是注册表自启动。用Regshot对比运行前后的注册表快照能看到它在两个位置写入了启动项。第一个位置是HKCU\Software\Microsoft\Windows\CurrentVersion\Run值名是MediaCacheUpdate值指向%APPDATA%\MicrosoftMediaCache\MediaCacheService.exe。第二个位置是HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellFolders的某个子键这个手法相对隐蔽常用于辅助持久化。除了注册表它还创建了一个计划任务。计划任务名称叫\Microsoft\Windows\Maintenance\MediaCacheSync触发器是系统启动时操作是运行MediaCacheService.exe。通过计划任务做持久化的好处是当用户用Autoruns这类工具检查时计划任务列表比注册表启动项更容易忽略而且在系统日志中看起来像正常的Windows维护任务。这里科普一下为什么RAT普遍要写多个持久化点。单一持久化机制一旦被清理木马就失联了。多持久化点的设计能增加蓝队应急响应的成本删了注册表启动项计划任务还在重启机器后木马照样活过来。所以清理的时候必须系统性地排查所有持久化点漏一个都白干。3.3 进程注入与DLL模块加载继续观察进程列表发现MediaCacheService.exe运行一段时间后出现了一个奇怪现象它创建了一个新的子进程svchost.exe然后申请人把自己的一部分代码映射到了svchost.exe的地址空间里。这就是经典的进程注入目的是隐藏自身行踪因为安全人员通常更关注可疑进程而svchost.exe是系统必备进程不会被轻易怀疑。跟踪内存操作发现它使用了NtCreateThreadEx在目标进程中创建远程线程内存区域是用VirtualAllocEx分配并且设置了PAGE_EXECUTE_READWRITE权限。这种注入方式不算最先进但够用而且绕过了一大半基于Hook的EDR产品因为EDR的Hook点常常只关注CreateRemoteThread而NtCreateThreadEx是更底层的原生API很多产品没有监控到这一层。还有个值得记录的细节样本会定期枚举每个正在运行的进程检查模块列表里是否包含SbieDll.dll或者dbghelp.dll。前者是沙盒工具Sandboxie的标志性DLL后者经常被调试器依赖。一旦发现这些模块就说明自己可能正在被分析环境监控样本会毫不犹豫地退出并自我清理。3.4 网络通信与C2指令协议最后是这场戏的重头戏——网络通信。Wireshark的抓包里能看到样本在系统启动后大约15秒开始发起HTTP请求目标就是前面提到过的那个动态域名。请求类型是POSTUser-Agent伪装成了Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36走得是标准的HTTPS 443端口但在TLS握手之前还是会先通过HTTP协议做一次初始化握手获取服务端的时间戳和会话标识。真正让我花时间逆向的是它的数据编码层。流量内容看起来像Base64但直接用标准Base64解码出来全是乱码。后来我在二进制里定位到了那张自定义的Base64字母表替换解码之后看到了完整的加密载荷。载荷的前16字节是一个固定长度的随机IV剩下部分是AES-128-CBC加密后的密文。通信协议的整个流程是客户端先发送一个包含机器标识和分组的握手包服务端返回一个4字节的任务指令码客户端再根据指令码执行对应的动作。指令码的映射关系可以在样本里逐个对出来比较核心的几个包括0x0001收集系统信息并回传。0x0002下载并执行指定URL的文件。0x0003开启键盘记录。0x0004执行任意Shell命令并返回输出。0x0005结束指定进程。0x0006更新配置文件。0x0007卸载自身并清理持久化。值得注意的是它的所有配置更新都是增量式的服务器可以单独下发新的C2地址而不需要重启木马。这意味着在红队攻防中即使你封锁了已知的C2域名攻击者也可以远程切换到备用域名继续维持通信。这对蓝队来说是很头痛的封禁单个域名根本不彻底必须把整条攻击链路断掉。4. 检测规则与应急排查实践4.1 基于静态特征的YARA规则分析完这个样本之后我把提取到的关键特征写成了一组YARA规则。写YARA规则最重要的一点是选取特征的稳定性。不要选那些易变的字符串比如文件名、注册表键名因为攻击者改一版代码就能更换。要选那些改起来成本高的特征比如自定义Base64字母表、AES密钥硬编码、特定的PE节区名称。针对AfKayAs.2我在规则里用了一个相对独特的特征样本中有一处固定的16字节AES密钥该密钥通过异或运算被拆分成了两组8字节数组分别存储在.data段的两个不同位置。这种拆分方式在我的样本库里是独一份的兼容性差点没关系专杀率高才是关键。另外还匹配了导入表特征组合同时导入了InternetOpenA、HttpSendRequestA、SetWindowsHookExA和GetSystemMetrics。这个组合本身就很容易识别出屏幕监控网络通信键盘记录的类型。4.2 主机侧排查IOC清单应急响应的时候我建议按下面的清单逐一排查注册表检查HKCU\...\Run下的MediaCacheUpdate值路径指向%APPDATA%\MicrosoftMediaCache\MediaCacheService.exe。文件系统检查%APPDATA%\MicrosoftMediaCache目录是否存在正常系统不会有这个目录。计划任务查找名称包含MediaCacheSync的任务命令行中带有/Create /Sc OnStart这类参数。进程行为检查svchost.exe是否被注入了异常模块可以用Process Explorer查看每个svchost进程加载的DLL列表重点关注C:\Windows\System32之外的路径。网络连接使用netstat -ano查找指向update-api[.]dynamic-dns[.]net的ESTABLISHED连接。我在应急排查时还发现过一个有意思的事某个办公网里有两台机器中了AfKayAs.2但排查的时候只找到了一台的进程另一台重启过进程已经没了但注册表启动项还在说明样本是靠启动项复活机制拉起来的。所以说排查的时候不能只盯当前活跃进程所有持久化点都得摸一遍。4.3 流量侧检测思路流量侧的检测可以从三个层面来做。第一个层面是DNS层面监控对dynamic-dns[.]net域名的解析请求尤其是局域网内部突然出现多台机器同时查询同一个动态域名的情况这基本就是RAT的C2通信信号。第二个层面是TLS证书指纹。由于样本走的是HTTPS普通流量分析工具看不到明文内容但TLS握手阶段的证书信息是可以获取的。JA3/JA3S指纹可以识别出客户端使用的TLS实现特征。AfKayAs.2样本的JA3指纹经过计算后和主流浏览器的指纹差异明显可以作为IDS规则之一。第三个层面是流量周期性分析。RAT的C2心跳包具有非常规律的发送间隔我抓到的这个样本是每60秒发送一次握手包波动范围不超过2秒。正常的用户流量不会有这种精密的周期性一旦检测到这种规律性HTTP POST流量就需要当心了。流量侧检测真正难的是误报率控制尤其是内网环境有大量业务系统使用动态域名或者CDN域名只凭域名或周期特征很容易产生大量告警。我通常的做法是组合评分动态域名固定UA严格周期POST体长度稳定多个条件同时满足才触发告警。5. 常见问题与实操心得5.1 分析中容易踩的坑第一反沙箱检测的绕过顺序很重要。先改CPU核心数和内存再改屏幕分辨率最后处理鼠标轨迹检测。改完这些也不是万事大吉样本可能还检测当前进程的父进程名字如果是services.exe或其他非explorer的父进程它会认为自己在不自然的启动环境中。我的做法是手动以explorer为父进程来启动样本具体可以用explorer.exe结合命令行来完成。第二小心样本的“自我毁灭”机制。这个样本在检测到分析痕迹后除了退出还会尝试删除注册表启动项和自身文件。这意味着你本来想看它的持久化机制结果还没看到就自己清理了。所以在开始动态分析之前我先做了一个虚拟机的完整快照每次分析结束直接回滚快照保证样本状态是最新的、不会被自我清理破坏。第三网络抓包时一定要配置好HTTPS解密。样本的C2通信走的是HTTPS在Wireshark里直接看只能看到加密的TLS数据。两个解决方案一个是在系统里安装Fiddler的根证书并用系统代理接管所有流量另一个是用APOAPI Monitor直接API层面的钩子来捕获HTTP请求和响应内容。前者会暴露代理环境可能触发反分析逻辑后者更隐蔽我推荐用后者。5.2 一些实战中的体会分析AfKayAs.2这类RAT样本我发现最有价值的其实不是某一个具体的功能函数而是整个样本的设计哲学。它的作者很明显是个有丰富对抗经验的人从反沙箱检测到多持久化点从自定义加密到进程注入每一个功能都不是凭空想出来的而是针对蓝队常规分析手段的定向反制。如果你平时做应急响应比较多我建议复盘的时候不要只停留在清除木马的层面还要追问一句它是怎么进来的我在实际排查中最后都溯源到了钓鱼邮件附件附件是个压缩包解压出来是个快捷方式文件加一个隐藏的脚本文件。AfKayAs.2只是整个攻击链条的下游上游入口往往更值得关注。另外任何RAT分析做完之后我习惯把提取到的IOC整理成一个标准格式的JSON文件包含域名、IP、文件哈希、注册表路径、计划任务名、YARA规则。这个习惯帮了我很多忙因为几个月后蓝队复盘的时候只需要翻这个JSON就能快速定位当时的分析结论和处置建议不需要重新跑一遍逆向。5.3 给新入行分析师的建议如果你想深入学习RAT分析不要看到样本就直接上动态调试。先把静态分析做到位把入口点、导入表、字符串、加壳方式全部摸清楚再切换到动态分析整个过程的效率会高很多。我见过不少新手一上来就开x64dbg结果被反调试策略绕得晕头转向最后连样本的C2地址都没找到。在分析样本之前记得先做好三件事给虚拟机打快照、关闭Windows Defender实时保护、配置好独立的网络环境。这三件事看起来简单但能避免掉九成的坑。快照保证你能不断回滚重来关闭实时保护避免样本刚落地就被杀掉导致你什么都看不到独立网络环境防止样本真的连上C2去控制外部机器。最后再分享一个小技巧在IDA里定位加密函数时先找常量比较密集的区域然后把这些常量在Python脚本里枚举一遍常见的密钥派生算法比如MD5、SHA1、AES密钥扩展。AfKayAs.2的16字节密钥就是这么被我找到的。纯肉眼去看密文里的特征往往很费劲写个脚本辅助搜索效率能翻好几倍。
返回列表