尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

银狐木马插件化更新机制分析:从下发链路到应急响应

银狐木马插件化更新机制分析:从下发链路到应急响应 前一阵处置了一台被控主机杀毒软件反复报“银狐”引擎清除后不到半小时EDR上又出现了新的外联请求。顺着连接追下去我发现一个很典型的循环主模块先从远端拿一份插件清单对比完版本号再把一个新模块拉回内存执行。那一刻我突然明白光靠“查杀单个恶意文件”打不赢它——真正让银狐难缠的是这套插件下发和更新机制。本文想以一个分析者的视角把银狐木马家族常见的插件化设计、下发链路、更新判断和持久化配合拆开讲清楚也会给出防守侧可以落地的检测与应急思路。这不是一篇教读者构造恶意程序的指南而是为了帮助做应急响应、恶意样本分析和EDR规则建设的人理解对手知道该从哪里打断它的节奏。1. 银狐的插件化改造从“一个大文件”到“下载器模块市场”1.1 单体木马时代的致命短板最早一批银狐样本其实没有现在这么复杂。攻击者把键盘记录、剪贴板替换、远程控制、信息窃取全部塞进同一个可执行文件里。这样做的好处是投递简单一个文件就能完成所有动作。但坏处也很明显文件体积动不动几MB甚至十几MB杀软引擎做静态扫描时特征非常明显一个高危特征命中整个样本就废了。更麻烦的是攻击者想要增加一个新功能必须重新编译整个程序、重新做免杀、重新走一遍钓鱼投递流程。只要有一个关键模块被安全厂商盯上前面投入的全部时间都会打水漂。早期的银狐变种在遭遇集中查杀后爆发力明显下降。负责运营这些木马的组织不是没感觉到所以他们很快走上了插件化路线。这个转变在安全人员眼里非常清晰样本落地体积从几MB降到几百KB主程序只保留下载器、加载器和最小化的信息收集代码更多功能模块变成按需从远端获取。这样一来就算功能模块被杀只要下载器还活着重新拉取一次就能恢复战斗力。换句话说银狐从“一次投递、全量作战”变成了“一次投递、持续更新”。1.2 插件清单本质上是一个远端“模块市场”很多人以为银狐的插件是像正常软件那样先创建一个文件夹再把插件文件静默下载到本地。实际分析中这种“直接落盘并等待下次启动”的情况只是其中一种。更常见的结构是主样本启动后会先请求一个远端接口获取当前可以加载的插件清单。这个清单类似于一个模块市场的商品列表里面写清楚有哪些插件、各自是什么版本、从哪个地址下载、下载后用什么方式校验、应该以什么方式启动。我在分析一个银狐变种时见过主程序内置了三条备选下载域名。第一条域名已经失效样本会依次尝试后两条。每一条返回的内容都经过简单加密解密后就是一个结构化文本里面包含插件配置。主程序拿到配置后并不急着把所有插件全部下载而是先跟本地已经缓存的模块信息做对比。如果版本相同就跳过如果版本更新或者本地缺失某个插件才去下载。这种设计让样本每次上线只做“最小必要传输”既降低流量暴露概率也减少重复下载带来的网络特征。单体文件时代安全人员把样本抓回来逆向后就能看到全部功能插件化之后样本相当于一个只有框架的浏览器页面你看到的是空壳真正的功能要在访问“服务器”之后才会像网页内容一样被动态填充。这也是为什么静态分析银狐样本时经常发现主样本看起来“很干净”几乎找不到恶意行为但一旦让它连接网络各种恶意模块就接踵而至。理解了这一点再看下面讲的下发与更新链路就会顺畅很多。2. 插件下发链路里的三个关键选择传输层、配置层、版本判断2.1 传输通道为什么偏爱HTTPS伪装与云存储银狐在插件传输方式上没有太多创新空间。它最大的诉求是稳定、难封、不引起安全设备注意。早期版本直接使用明文HTTP下载插件优点是代码简单、调试方便但流量审计设备很容易根据URL特征和返回包内容报警。后来大多数变种转向HTTPS甚至把下载地址挂到各类公共对象存储、网盘或看起来像静态资源服务的路径上。这类通道本质上是在“借用”可信域名的信誉。安全设备看到是知名云服务商域名、TLS流量默认会放行。攻击者还把插件下载路径伪装成/fonts/update.css、/assets/icon.png这类非常像正常网页资源的地址让分析人员在流量日志里一眼扫过去很难发现问题。值得注意的是直接落盘下载的插件往往会被改名成.tmp、.dat、.bin或者干脆没有扩展名内存加载的插件则根本不经过文件系统直接从网络响应流里解析出来。从防守角度不能只盯“下载文件”这个行为。插件下发是一个“先请求配置、再拉取内容”的过程如果网络层能把这两个步骤关联起来会比单个URL封禁有效得多。我在实际抓包时经常把重点放在两个请求的时间间隔和请求头的自定义字段上。许多变种为了让服务端识别自己的身份会在请求头里带一串固定的机器ID或分组标记这在正常业务流量里并不常见可以作为初步筛选线索。2.2 一份插件描述文件到底包含什么对插件配置做逆向提取是分析银狐更新机制最快的方法。我把一些样本返回的配置做过泛化整理去掉真正的地址和哈希后核心结构大致是这样的{ plugin_id: keylogger, version: 3.2, url: https://update.example.com/res/14f3a9c2, sha256: e3a2f4c6b7d8a9e0f1b2c3d4e5f6a7b8, load_type: mem, entry: start_hook }这个JSON结构可以从几个维度来看plugin_id用于标识插件名称version是版本号url指向插件本体sha256用来做完整性校验load_type决定插件是直接加载到内存还是先落盘entry则代表加载后要调用的导出函数或方法名。攻击者做版本判断时本质上就是在对比本地记录的插件号和版本号跟这个配置里的值是否一致。这里想多说一句看到sha256字段不要觉得攻击者很注重安全他们做这个主要是防止下发链路被劫持或替换。如果下载回来的插件哈希对不上主程序会直接丢弃避免把“别人的木马”加载进来。这个细节对防守方也有启发如果能在网络侧篡改或替换下发内容理论上可以干扰木马更新但这属于主动防御范畴需要结合合规要求评估不能擅自使用。2.3 更新频率不是越频繁越好插件更新的节奏设计真实样本里差异很大。有些银狐变种把更新时间设得很短主机上线后每隔30分钟到60分钟就请求一次插件列表这样的好处是控制端下发指令更及时但代价是会产生明显的周期性外联流量容易被流量分析模型识别。另一些变种会把时间拉长到6小时甚至24小时更强调隐蔽性但更新速度也会变慢。比较狡猾的设计是在更新间隔中加入随机抖动。比如基础时间是2小时再乘以一个0.75到1.25之间的随机数这样外联行为不是固定周期普通的“每N分钟一次”检测规则就没那么容易命中。还有一些样本会对接入网络的时机做判断发现网络断开时就进入等待一旦检测到网络恢复先立刻请求一次插件列表而不是傻等下一个周期。这意味着当你把一台中毒主机的网线拔掉再插回去它可能马上就会触发更新行为这反而是抓取最新下发域名的好时机。从应急角度如果一台机器已经确认中了银狐且你怀疑它还有控制端存活我会建议先抓取内存和网络流量再考虑断网。因为断网虽然能阻止进一步下载但也让你丢失了观察控制端新下发指令的机会。只有当你已经拿到足够证据、准备清理时才果断切断外联。3. 从样本里拆更新模块定位、调试与全流程还原3.1 静态定位更新代码的五种线索面对一个银狐主样本如果不想直接运行它更好的方式是从静态特征入手先圈定更新模块的位置。我在实际分析时通常依次找五类线索URL和域名相关的字符串、版本控制相关的数值常量、网络请求API的调用位置、能构造线程或定时器的函数以及负责解密配置的自定义函数。很多银狐样本会使用多层编码隐藏C2地址纯静态搜索域名不一定找得到。比较实用的是在反汇编视图里查找InternetOpenW、WinHttpOpen、URLDownloadToFileW这类API的引用位置。一旦定位到网络请求代码向上回溯就能找到处理响应数据的函数更新逻辑一般就藏在那附近。版本号在代码里常以十六进制呈现比如3.2可能被表示为硬编码的0x00030002这类数值没有对应的字符串需要结合功能上下文判断。至于定时器攻击者通常会调CreateThread或CreateTimerQueueTimer来启动一个独立的更新线程。这个线程的特点是先把当前配置发出去拿到响应后陷入一段等待再继续下一轮。通过动态调试你可以在这个线程里设置条件断点观察它解密后的配置内容比漫无目的地静态分析效率高得多。3.2 动态调试时盯哪些API如果分析环境允许动态调试是理解更新机制最直接的手段。我经常会在几个关键函数上设置断点分别是负责发起HTTP请求的WinHttpSendRequest和InternetReadFile负责创建本地文件的CreateFileW负责分配内存的VirtualAlloc以及负责创建远程线程或调用CreateThread的位置。这套断点组合可以覆盖“请求配置、接收数据、准备内存、进入执行”这条主干。遇到内存加载型插件时文件路径断点几乎不会触发。插件内容从网络流里读出来后会直接写进可执行内存页。所以在动态调试中如果发现VirtualAlloc申请的内存带PAGE_EXECUTE_READWRITE属性随后又有数据往这块内存里拷贝那基本可以判定进入了插件加载流程。此时保存这块内存的完整镜像可能比去磁盘里找插件文件更有价值。需要提醒的是动态分析恶意代码时要确保环境隔离、没有真实业务数据进联网。我自己习惯用快照环境分析完成后直接回滚避免样本二次传播。银狐不同变种之间差异不小一次分析只能代表一类情况不要轻易把某次观察到的URL结构推广到所有银狐样本上。3.3 一次插件更新全流程的逻辑还原把静态和动态分析的信息拼在一起我会用下面这种简化流程描述银狐的插件更新链路主样本启动先读取本地缓存文件或者注册表项得到当前插件状态。更新线程按预设的休眠时间醒来构造带有机器标识的请求访问远端配置接口。服务端返回经过编码的插件清单样本用内置密钥解密得到若干插件信息。样本遍历插件信息逐一与本地版本比较版本一致则跳过缺失或较旧则进入下载逻辑。下载完成后先校验哈希再根据load_type字段决定直接内存加载或释放到临时目录。新插件加载成功后如果旧模块仍在运行会先通知旧模块退出再释放新模块的入口调用。本轮更新结束记录最新版本状态线程继续休眠等待下一轮。这段流程并不需要什么高深技术但它恰恰解释了很多管理员遇到的怪现象明明把某个可疑DLL删了过一段时间同名DLL又出现了。因为删除动作只是处理了下发链路里的“消费者”并没有打断“生产者”。只要更新线程还在主控端还在插件就会像一个不断被拉取到本地的资源包一样删一次拉一次。4. 插件“更新成功”之后运行期替换和持久化是两条线4.1 正在运行的插件如何被替换一个容易被忽略的细节是插件更新不能像覆盖普通文件那样随意。键盘记录模块一旦创建了全局钩子剪贴板模块如果正在监听系统剪贴板直接释放文件或覆盖DLL会导致文件被占用更新失败。所以在更新流程里攻击者一般会先通过进程间通信或命令通道通知旧插件退出等待几秒钟再开始写入新版本文件也有的变种不做优雅退出直接结束整个主进程再重启让系统重新加载新模块。这种“退出再替换”的行为会在主机上留下清晰的痕迹。比如Sysmon日志里可能出现同一个进程ID短暂消失随后新的进程ID以相似命令行重新出现文件创建事件里同一路径的DLL会在短时间内被写入两次且第二次文件大小明显变化。对应急排查来说这些线索比单纯扫描恶意文件要有用得多。还有一种情况是插件不需要停旧就更新攻击者会把新模块的导出函数改名。比如旧版键盘钩子的入口叫StartHook新版改成NewHookWorker。由于旧模块已经注入其他进程更新逻辑只是让下载器加载一份新代码两代模块并行运行。这种设计虽然混乱但能保证在旧模块不退出时也不丢失功能切换阶段反而更长更有利于防守方抓取痕迹。4.2 持久化点为什么总是好几个插件更新解决的是“能力扩展”问题持久化解决的是“重启后还能跑”的问题。银狐运营者很清楚这两件事必须配合但实现上又是独立的两条线。一个典型样本会同时注册计划任务、服务项和启动项不是因为技术洁癖而是为了保险。任何单一持久化点被杀掉后其他入口仍然能在系统重启后重新激活下载器再通过更新机制把缺失的插件拉回来。我见过一台被银狐感染较深的主机删除计划任务后服务启动项又把它拉起来删除服务后WMI事件订阅又触发了PowerShell命令。这里想强调清理银狐不能只关注下载器和插件文件还要把持久化点视为更新机制能够持续运行的基础设施。只要有一个持久化入口漏掉整个处置结果都可能在下次重启后被翻盘。4.3 “反复复活”与更新机制的因果关系很多管理员一听到“清除后又出现”就认定是杀毒软件没用实际上问题出在处置顺序和覆盖面上。银狐的复活能力不完全来自插件更新本身而是因为更新机制与持久化机制形成了一个循环持久化让下载器在重启后运行下载器运行后请求插件清单插件清单把被杀掉的模块重新下载回来。如果你只杀模块文件等于是在这个循环的末端做阻断而循环依然在转。理解这个循环之后处置思路就清晰了要打断循环要么让下载器无法运行清理持久化结束进程要么让下载器无法联网网络隔离/封禁C2最好是两个动作同时做。顺序反过来也没问题关键是别只做其中一步。我处置银狐时通常会先把可疑外联IP和域名在防火墙上临时封禁再从持久化点里把下载器入口清掉最后才做文件清理和全盘扫描。这样一来即使有残留模块想更新也没有能力把新文件拉回本地。5. 把“更新机制”变成检测规则与应急抓手5.1 流量侧识别周期性外联与配置接口从流量里发现银狐插件下发不建议只盯着已知恶意域名。更可靠的方向是对“外联→响应→下载”三段式行为建模。比如一台工作站频繁请求一个近期新注册的域名且每次响应后都伴有文件下载或大流量数据传输这个行为本身就值得告警。哪怕域名信誉库还没收录它行为异常已经足够引起蓝队注意。实际运营中我会额外关注两类端点一类是路径包含api、update、list、version等词但归属不明的URL另一类是请求头里携带类似固定token或机器标识的接口。银狐为了区分受害者和下发策略经常会在配置接口上返回不一样的内容因此不同主机的响应体会有差异。安全分析时抓取两台已被控主机的配置响应做对比很快就能看出哪些字段是动态分配的控制端信息。5.2 主机侧用进程链和模块加载事件兜底主机侧检测的核心思路是“不要看单个文件是否恶意而要看进程行为和模块加载是否反常”。银狐下载器通常不会独立出现它的进程父级可能是一个Office文档、一个脚本宿主程序也可能被计划任务直接拉起。出现这类不常见父子链时需要结合模块加载事件进一步判断。比如一个低权限用户的进程突然加载了一个带网络请求功能并能申请可执行内存的DLL这就是明显的风险组合。下面是一张简化的检测关注点表供搭建规则时参考检测层具体事件重点关注信号网络层DNS请求高频解析新域名、随机子域名网络层HTTPS请求客户端特征头与业务不匹配主机层进程创建脚本宿主启动可疑PE主机层模块加载非常规路径DLL被rundll32或系统工具加载主机层文件创建临时目录多次出现相同哈希但不同版本文件主机层定时任务计划任务命令行为下载器路径这些信号单独看可能都不致命放在一起就会形成比较完整的检测面。我一直强调“用更新机制做检测”的价值在于攻击者很难在每次更新时都完全改变行为模式。他可能换域名、换文件内容但“先对比版本再下载”的逻辑总会保留而这一逻辑在主机行为上会体现为网络请求、版本比对、内存分配、线程创建等一串固定动作。5.3 清除顺序不对等于白杀先断外联再清持久化很多运维人员拿到查杀结果后习惯直接删除恶意文件这个动作本身没有错但在银狐场景下太早了。删除文件是循环末端的动作前面还有外联入口和持久化入口没处理。正确顺序需要“先刹车再拆引擎”第一步确认主机感染后尽快在网络侧封禁已发现的可疑域名和IP切断与C2的通信。第二步采集主机上的内存、进程列表、网络连接和计划任务信息保留供后续分析。第三步找到并删除计划任务、服务、启动项、WMI事件订阅等持久化入口。第四步结束仍在运行的可疑进程避免它们配合更新线程把模块重新拉起。第五步清理释放到本地的下载器、插件文件和缓存数据。第六步更新本地防病毒和EDR规则对同源域名、IP和文件哈希做全局排查确认内网中没有其他受害主机。这六步里最容易被跳过的就是第三步。很多人以为把样本文件删了就结束结果重启后计划任务又把某个残留的下载器启动带来新一轮更新。所以我在处置银狐类事件时宁可多花十分钟检查持久化入口也不愿意第二天再回来做二次处置。5.4 专杀工具与人工查杀的配合“银狐专杀”类工具在处理已知变种时确实能快速清掉大量已知文件但它的短板在于病毒库滞后。银狐4.0源代码在一些渠道流出后二开变种层出不穷每个二开者都可能修改下载域名、插件清单加密方式和更新间隔。专杀工具如果只覆盖上一代特征面对新一代样本往往会漏。人工查杀最大的价值不是替代专杀工具而是在专杀工具查完一轮后做验证。我喜欢从三个角度验证清理是否到位第一网络侧是否还有周期性外联第二进程树是否还出现来自可疑父进程的更新线程第三磁盘和注册表里是否存在与已知插件清单版本相关的残留。三者都干净才算真正处置完成。从处理这类事件的经验来看银狐能不能被清干净关键不在于你有没有最新专杀而在于你有没有从“下载器—配置接口—持久化”这条完整链路上同时下手。插件更新本事再大也经不起攻击面每层都被切断。至少我在前面提到的那台机器上完成断网和持久化清理后第二天没有再出现新外联这大概就是循环被打断的直接证明。后面再遇到类似样本我也会先把整个更新链路画出来再决定从哪个节点下手而不是追着被更新的插件文件来回折腾。
返回列表