ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

恶意样本分析实战:msng样本隔离、动态捕获与反分析对抗

恶意样本分析实战:msng样本隔离、动态捕获与反分析对抗 恶意样本分析这件事圈外人听着像拆弹圈内人知道它更像法医——你不能让尸体再动起来咬人但你又必须把它每一处伤口、每一根断骨都还原清楚。我最近手上就过了一个被标记为msng的样本来源是朋友转过来的一句帮忙看看这玩意儿是干嘛的。这类请求很常见真正难的不是打开它而是在打开之前想清楚我要回答什么问题、我需要多深的结论、我的机器会不会变成下一个案发现场。这篇就把我处理这个样本的完整思路和操作记录摊开讲从环境隔离、静态侦察、动态行为捕获到反分析对抗和踩过的坑都在里面。不管你是刚入行的安全运营同学还是写检测规则写得手酸的蓝队工程师或者只是对恶意样本分析流程好奇的技术爱好者都能从里面抄到能直接用的东西。我不会给你一个三分钟定性的结论因为那种结论在真实应急里往往是要背锅的。1. 动手之前先把分析目标和安全边界钉死很多人拿到样本的第一反应是双击看反应这个习惯非常危险。真实的应急场景里样本分析的第一产出不是它是什么病毒而是它在我的环境里干了什么、有没有横向、我现在要做哪些阻断。目标不同投入的资源差着数量级。所以我在动 msng 之前先在纸上写了三行字这次要回答的核心问题是什么、我允许样本触达的边界在哪、什么情况下我立刻中止分析。1.1 分析目标决定了你要挖多深分析目标大致分三档档位不同工作量和结论精度完全不同。第一档是快速定性通常发生在应急响应的前半小时你只需要知道它是下载器、勒索前置、还是远控客户端能回答要不要全网查杀、要不要断网就够。第二档是情报提取你要落地完整的 IOC、行为特征、通信协议特征供后续的威胁狩猎和规则编写使用这一档必须做动态分析加网络抓包。第三档是深度逆向要还原加密算法、配置结构、C2 协议格式用于写解密工具或做溯源这一档动辄几天甚至几周。我给 msng 定的档位是第二档偏上。理由很实在朋友那边已经把机器格了没有第二现场可对比所以我不需要做应急取证但我需要给他一份能落地的 IOC 清单方便他排查同网段其他机器。这意味着我必须让它跑起来而且必须抓网络流量。这个决定直接影响后面环境搭建的复杂度——纯静态分析可以在一块断网的虚拟机里做完动态分析就必须构造一个看起来像真的、但实际上什么也连不上的受控网络。注意在没弄清楚样本能力之前永远假设它具备自我传播、加密勒索和反分析三种能力。这个假设会让你在环境隔离上多花二十分钟但能省掉后面重装系统的两天。目标定下来之后还有一个容易被忽略的问题你要不要保留样本的原始样本文件。我的习惯是原始样本只读挂载所有操作都在副本上进行并且副本在每次实验结束后销毁重建。因为有些样本会自我改写、会释放子样本覆盖自身你操作一次原始文件等你回头想验证某个结论时手里的样本已经不是原来那个了哈希都对不上。1.2 隔离环境不是断个网就完事隔离这件事新手和老人的差距最大。新手理解的隔离是虚拟机 拔网线老手理解的是虚拟机 快照 受控网络 只读共享 无痕还原。为什么差这么多因为样本的反分析能力越来越强单纯的断网环境很容易被它识别出来——很多样本会先探测网络连通性发现完全没有出网就进入休眠什么也不干让你以为它是干净文件。我实际用的隔离方案是这样的宿主用一台专门的旧笔记本物理上不接任何办公网只通过一块独立网卡接一个脏网段。宿主机上跑虚拟化软件样本虚拟机配两块虚拟网卡一块走 Host-Only 和我的分析主机通信一块走 NAT 但不给真实出口而是指向我本地起的模拟服务用来响应样本的 HTTP 请求和 DNS 查询。这样样本觉得我能上网但它发出的每一个请求都落在我自己的日志里。快照是必须的而且要在样本落地之前做干净快照。我的操作顺序是装系统、装分析工具、打快照标记为 clean、再拷入样本。这样每次实验结束回滚到 clean 快照几十秒就恢复现场。共享文件夹一定要设成只读我见过样本会遍历共享目录往宿主机写文件的情况虽然概率低但后果不可控。虚拟机里的反检测细节也得处理。默认安装的虚拟机有几个特征特别明显用户名是安装时设的、主机名很规律、磁盘型号显示为虚拟磁盘、内存大小是 2G/4G 这类整数、屏幕分辨率固定、没有真实的使用痕迹浏览器历史、文档、回收站。我会在 clean 快照里预先造一批像人用过的痕迹改掉主机名和用户名装几个常用软件放一些无关文档把分辨率调到不规律的数值。这些动作看着琐碎但实测下来能让相当一部分样本从静默切换到正常工作状态。2. 静态侦察在不动它一根汗毛的前提下摸底静态分析的价值在于零风险获取信息。样本躺着不动的时候最安全这时候能拿到的结论也最多。我在做 msng 静态分析时按文件层 → 结构层 → 内容层三层递进每层都有明确的判断目标。2.1 文件层哈希、类型与元数据第一件事是算哈希而且要算完整。MD5 用来快速比对公开情报库SHA256 作为唯一标识存档SHA1 很多平台还在用也一并算。Windows 上最省事的办法是 PowerShell 一行搞定Get-FileHash -Algorithm SHA256 .\msng_sample.bin如果样本被重命名成看似正常的文件比如伪装成 .jpg、.doc哈希能帮你第一时间确认它到底是新样本还是已收录的老家伙。我把 SHA256 丢进公开情报平台跑了一遍没有任何命中说明这是个没被广泛收录的变种或者小众样本这就意味着后面必须靠自己分析不能指望抄答案。接着看真实文件类型。很多样本会把扩展名改成图片或文档但文件头的魔数骗不了人。用十六进制工具打开看前几个字节4D 5A就是 PE 可执行文件50 4B 03 04是 ZIP 压缩包有些样本是自解压结构。我手上这个 msng 开头是标准的 MZ 头确认是 Windows 可执行文件。文件大小也是个有用的信息。几百 KB 的程序如果是 C 写的可能功能比较简单如果是 Go 或者 Rust 编译的那基本上什么也判断不出来因为这两个语言的运行时会把二进制撑得很大一个 Hello World 都能到 2MB。我手上这个样本大概 1.2MB这个体积有点尴尬两种可能都存在必须继续往下看。2.2 结构层PE 头部藏着大量线索PE 结构分析我一般关注几个点编译时间戳、区段信息、导入表、节区熵值、以及有没有 PDB 路径残留。编译时间戳在 PE 头里是个 4 字节的 Unix 时间戳转成可读时间就能知道样本大概什么时候被编译的。这个信息不一定准因为可以被伪造但如果它显示的是 1990 年或者 2077 年这种明显不合理的值那基本可以确认是被人为改过说明作者有反取证意识。我这个样本的时间戳落在合理区间和情报平台上同类样本的时间分布也能对上。区段信息值得多花点时间。正常编译的程序区段名一般是.text、.data、.rdata、.rsrc如果出现.UPX0、.UPX1这种那就是 UPX 加壳如果区段名是乱码或者单字符多半是自定义壳或者加密器。节区熵值是判断是否加密/压缩的硬指标熵值越接近 8.0 说明数据随机性越高越可能是加密或压缩过的内容。我看了下 msng 的区段有一段的熵值明显偏高差不多在 7.9 左右其余区段正常这个特征通常意味着存在一段被加密的数据块可能是配置信息也可能是后续要解密的载荷。导入表能告诉你程序会调用哪些系统 API这是判断功能最直接的依据之一。不过要注意很多样本会做导入表混淆也就是不直接导入函数而是运行时通过LoadLibraryGetProcAddress动态解析。这种情况下导入表看起来会很干净只有寥寥几个函数这本身就是个这货有问题的强烈信号。msng 的导入表数量偏少而且里面出现了动态加载相关的函数我基本可以判断它有运行时解析行为。2.3 内容层字符串和资源提取字符串提取是个廉价但高效的手段。ASCII 字符串和 Unicode 字符串都要提因为很多程序内部用的是宽字符。工具上选择很多命令行工具、图形化工具、或者干脆用十六进制编辑器手动翻都行。我关注的目标有几类URL 和域名、IP 地址、文件路径、注册表路径、命令行参数、以及可能的互斥体名称。互斥体Mutex名称是特别有意思的东西。很多样本会创建一个唯一命名的互斥体用来保证同一台机器上只运行一份防止重复感染导致系统异常。这个互斥体名称往往在整个家族里保持稳定是个非常好的检测特征。我提取 msng 的字符串时就重点找了看起来像 GUID 或者有规律的字符串。资源段也别放过。PE 的资源段里可能藏着图片、图标也可能藏着额外的二进制数据。有些样本会把真正的载荷以资源形式打包进主程序运行时释放到临时目录再执行。我看资源段的时候如果看到一个资源的大小远大于普通图标就要怀疑里面是不是裹了一层东西。提示字符串提取一定要分两轮做。第一轮在未脱壳状态下做能拿到壳本身暴露的提示第二轮在脱壳后做能拿到真正的功能字符串。两轮的差异本身就是重要情报。3. 动态分析让它跑起来看真实行为静态分析给出的是它可能做什么动态分析给出的是它实际做了什么。两者的结论经常不一致因为样本会根据环境条件走不同的分支。我在受控环境里让 msng 跑了三轮每轮观察重点不同第一轮看主机行为第二轮看网络行为第三轮看持久化行为。3.1 主机行为进程、文件、注册表三件套主机行为监控的工具组合我用了很多年核心是进程监控 文件监控 注册表监控。进程监控看的是进程树样本启动后有没有创建子进程、子进程是谁、命令行参数是什么。文件监控看的是落地文件样本往哪些目录写了东西、写的是什么类型。注册表监控看的是配置修改尤其是自启动项相关的键。我把样本跑起来之后观察到的第一波行为是进程层面的主进程启动后没多久出现了一个新的子进程而且子进程的可执行文件路径指向了系统目录。这是一个非常典型的信号——很多样本会把自身复制到系统目录或者用户目录然后用副本重新启动主进程退出。这么做的好处是可以绕过原文件被删除后无法运行的问题也让安全人员追踪时容易找错目标。文件监控这一段我注意到样本在用户临时目录下落地了文件。落地文件的类型很重要如果是可执行文件说明是多阶段载荷如果是配置文件或者数据文件说明是配置落地。我把落地文件单独揪出来算哈希和主样本对比发现不是同一个文件说明这是释放出来的新东西需要单独分析。这一步很多人会漏以为落地文件只是缓存其实它往往是真正的核心逻辑所在。注册表监控里重点关注几个位置Run 键、RunOnce 键、服务项、以及一些不常见的 COM 劫持位置。样本如果修改了这些位置就有持久化意图意味着重启之后它还会回来。我在这一轮监控里看到样本动了自启动相关的位置具体键值这里就不细说了但结论是明确的它具有持久化能力清理时必须把这个位置一起处理否则重启就复活。3.2 网络行为流量比任何日志都诚实网络行为分析是动态分析里信息密度最高的部分。我的做法是在样本虚拟机的网关位置做流量镜像同时在本地的模拟服务上响应它的请求这样既能拿到真实流量又能让样本以为通信成功从而继续暴露后续行为。观察的重点分成几层。第一层是 DNS 查询样本尝试解析了哪些域名。哪怕这个域名解析失败光是它想解析什么这个信息就极有价值因为这说明代码里硬编码了这个域名可以直接用作阻断规则。第二层是连接尝试样本尝试连接的 IP 和端口包括 HTTP 和 HTTPS 的区别。第三层是应用层协议如果样本用的是自定义协议就要看它的报文结构如果用的是标准 HTTP就要看 URL 路径、请求头、User-Agent、以及请求体的编码方式。我这一轮抓到的流量里样本发起了一次 HTTP 请求请求特征有明显的自动化痕迹——User-Agent 是硬编码的非常见字符串请求路径带着一串看起来像机器指纹的参数。这个参数结构很有意思通常包含主机名、用户名、系统版本、甚至屏幕分辨率作用是让服务端知道这个受害者是谁。服务端的响应被我本地模拟了样本收到响应后没有立刻执行下一步而是在一段时间后发起了第二个请求这个间隔很可能就是它内置的心跳周期。心跳周期是很关键的情报。如果你知道样本每 60 秒回连一次那你在做流量检测时就可以围绕这个周期做基线如果你知道它只在启动时回连一次然后进入长间隔那检测窗口就要提前。我在抓包记录里数了请求的时间戳估算出的间隔确实落在分钟级别。3.3 持久化与提权它到底想活多久持久化手段的复杂度直接反映样本作者的投入程度。最简单的做法是写一个自启动项稍微复杂一点的是注册服务、创建计划任务更复杂的会用 WMI 事件订阅或者 COM 劫持。我见过时间戳被做成只在下个月某天之后才激活的那本质上是让沙箱在有限观察期内看不到行为。除了持久化还要看提权意图。样本如果尝试获取高权限通常会调用和权限相关的系统调用或者尝试提升自身进程的权限。这一块在沙箱里不一定能观察到成功结果但尝试本身就是重要信息因为说明它有能力区分权限级别并据此走不同路径。我把 msng 的持久化和提权行为梳理了一遍结论是持久化有提权动作也存在痕迹但因为运行环境权限有限没有观察到完整的提权链。这种半截结论在真实分析里非常常见你不可能在每一个样本上都拿到完整链条重点是把你确认到的部分记录清楚把没确认的部分标为待验证而不是强行编一个完整故事。4. 反分析对抗样本为什么装死如果你跑出来的样本行为特别少先别急着下这个样本很干净的结论八成是它发现环境不对切到了休眠分支。反分析手段这几年进化得很快从最基础的检测虚拟机到检测调试器、检测沙箱、检测分析工具的进程名花样很多。4.1 环境检测的几种常见套路虚拟机检测的经典方式是查注册表里的虚拟化痕迹或者查设备的硬件信息。有些做法更直接枚举当前进程列表看看有没有分析工具的进程在跑。还有一种很隐蔽的做法是检测用户交互痕迹比如鼠标多久没动过、屏幕上的窗口数量、回收站是不是空的一个刚装好、什么都没干过的系统在这些指标上会显得非常异常。时间差检测是另一个大招。样本会先记录一个时间做一堆无意义的计算再记录一个时间如果两个时间的差值远小于正常程序的执行时间就说明自己正在被快速执行也就是被自动化分析工具跑。或者反过来它会故意插入一段长时间的延时等你分析工具的超时时间到了自动关掉它才开始干活。调试器检测用的是系统自带的调试 API通过判断自身是否处于被调试状态来走不同分支。对付这一类的办法是做反反调试或者干脆用更底层的分析方式绕过检测点。4.2 我的应对思路先改环境再改行为应对反分析我一般分两步走。第一步是改环境把虚拟机改造得更像真实机器前面提到的改主机名、造使用痕迹、调整分辨率都属于这一步。第二步是改行为让分析过程更接近真人操作——鼠标定期动一动、偶尔打开几个程序、不要在几分钟内完成所有操作。有个小技巧特别管用给分析过程注入随机的无聊时间。也就是说不要一直盯着屏幕猛操作而是让虚拟机自己静置一段时间甚至模拟一下挂机。很多样本的延时逻辑就是等着看这台机器像不像有人在用你给它足够的静置时间它反而会主动开始工作。还有一招是多环境对照。同一份样本在不同的虚拟机配置下各跑一次对比行为的差异。如果某个配置下它动得特别勤那说明这个配置触发了它的某个分支这个分支条件本身就是情报——它意味着样本在主动筛选目标环境。注意如果你怀疑样本在做反分析绝对不要为了让它动起来而在宿主机上直接运行它。所有的环境伪装和交互模拟都必须限制在虚拟机内部完成。5. 常见问题与排查技巧实录这一节是我这些年踩坑攒下来的也是最值钱的部分。很多问题文档里不会写但你没踩过就一定会中招。5.1 样本跑不起来怎么办样本跑不起来表现很多进程瞬间消失、进程常驻但毫无行为、程序直接报错退出、或者干脆没有任何反应。原因和对策我整理成了表方便对照排查。现象可能原因排查动作处理办法进程双击后瞬退检测到虚拟机或沙箱查看是否有环境检测分支改造虚拟机环境增加使用痕迹进程常驻但无行为等待条件触发或心跳未到延长观察时间到十分钟以上模拟交互注入静置时间直接弹错误框缺少依赖库或需要特定参数查看错误信息与命令行需求补装运行库尝试带参数启动有行为但不落地载荷直接在内存中执行检查进程内存区域采用内存取证方式抓取网络无任何请求DNS 或出口被完全阻断检查模拟服务是否响应补上 DNS 模拟让解析成功这张表里最容易误判的是进程常驻但无行为。我遇到过样本在里面嵌了一个长达几十分钟的延时你如果按常规观察五分钟就收工结论就是这个样本无害实际上它只是在等。延长观察时间是成本最低、收益最高的一步操作我现在的标准是样本至少观察半小时特殊样本会挂一整晚。5.2 内存取证当样本不上磁盘时现代样本越来越倾向于无文件落地也就是把载荷直接加载到内存里执行磁盘上你什么都看不到。这种情况下常规的文件监控就失效了必须转向内存取证。内存取证的思路是在样本运行状态下把进程的内存空间 dump 出来然后在里面搜索可执行特征、配置字符串、以及解密后的明文。具体怎么 dump、用什么工具公开资料很多这里要强调的是时间点的选择。dump 太早载荷还没解密dump 太晚载荷可能已经执行完并擦除。我的做法是并行开好几个 dump 窗口每隔一段时间抓一次回头对比哪一次的内容最完整。这个笨办法实测比任何智能时机判断都靠谱。另外要提醒一点内存 dump 出来的内容可能包含真实环境的敏感数据如果有的话归档时要注意脱敏不要把这些东西随手传到公开平台。5.3 Navigator 的几点心得第一结论要分级。我会把结论分成已确认和高度怀疑两类已确认的是我亲眼观察到的行为高度怀疑的是根据特征推断的。这样别人引用你的报告时知道哪些能当铁证哪些需要自己复核。第二IOC 要及时失效标记。样本的域名和 IP 变化很快你今天提取的 IOC可能一周后就失效了。所以我在交付 IOC 时一定会标注提取时间并说明该 IOC 的有效期取决于样本的基础设施轮换频率。第三清理方案要和 IOC 一一对应。光是告诉别人你中招了没有意义要给到可执行的动作哪个注册表键要删、哪个目录要清、哪个域名要阻断、哪个哈希要加入黑名单。我在整理 msng 的清理方案时就是按行为 → 痕迹 → 清理动作的顺序一条条对应写的。6. 一点个人体会这一轮 msng 分析下来最大的感受不是样本本身有多复杂而是流程的价值远大于工具的价值。我用的工具全是公开的、谁都能下载的真正拉开差距的是操作顺序和判断标准什么时候该停下静态分析转动态什么时候该怀疑没行为是假象什么时候该果断放弃深挖保住时效。这些判断没有标准答案只能靠一次次实操积累。另外想说的是做恶意样本分析这件事一定要给自己留够余地。不要在没做快照的环境里跑样本不要在连接着办公网的机器上解压样本不要在凌晨三点头脑不清醒的时候做动态分析——我见过太多为了赶时间结果重装系统的案例。慢一点稳一点样本永远都在那里不急这一时半会儿。最后再分享一个我一直在用的习惯每次分析完把这次用到的命令、遇到的坑、最后的结论写一份属于自己的分析笔记不用给别人看只给自己。半年后你再遇到同类样本翻出这份笔记效率能翻倍。工具会更新样本会进化但你踩过的坑和总结出的判断逻辑是真正属于你自己的东西。
返回列表