news 2026/9/25 6:43:54

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 文件格式与加壳情况

把样本丢进DIE(Detect 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)。导入函数就像一个人的生活习惯,能一眼看出他大概干过什么。这个样本的导入表重点关注这几个API:

  • InternetOpenA、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请求,目标就是前面提到过的那个动态域名。请求类型是POST,User-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的根证书并用系统代理接管所有流量,另一个是用APO(API 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字节密钥就是这么被我找到的。纯肉眼去看密文里的特征往往很费劲,写个脚本辅助搜索,效率能翻好几倍。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 6:43:28

STM32驱动AD5522 SMU芯片的五大实战经验:从SPI配置到电源与PCB布局

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 6:42:01

Nginx 403错误排查全攻略:从权限到SELinux的根因分析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 6:41:49

专业焊接套筒源头厂家哪家好?衡水万泉生产厂家口碑公司汇总

衡水万泉建筑机械有限公司,是一家专注研发生产建筑机械及配套产品的重点民营企业,依托深厚的行业积淀打造建筑钢筋机械连接领域的可靠供应商,主营各类可焊套筒、焊接套筒、焊式套筒、可焊型直螺纹套筒及配套钢筋连接设备、配件,以…

作者头像 李华
网站建设 2026/9/25 6:41:08

R与RStudio版本更新全攻略:跨平台操作与包迁移技巧

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华