ARTICLE DETAIL

资讯详情

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

RwDrv.sys双面人生:从硬件调试利器到UEFI Rootkit跳板

RwDrv.sys双面人生:从硬件调试利器到UEFI Rootkit跳板 1. UEFI时代的“幽灵”恶意代码为什么要住进固件里第一次认真研究RwDrv.sys是我用RWEverything调一台老工作站BIOS隐藏选项的时候。当时只觉得这是个“绿色小工具”哪能想到后来在固件安全样本里又见到它并且扮演的角色完全不同。RWEverything是个老牌的Windows底层硬件访问工具核心驱动就是RwDrv.sys它可以读写物理内存、I/O端口、PCI配置空间、MSR甚至能操作SPI Flash。对硬件调试者来说这是宝具对一个UEFI Rootkit的攻击链来说这同样是宝具。这篇内容我打算把它这两副面孔都摊开聊一聊。1.1 传统Rootkit和UEFI Rootkit的本质区别传统意义上的Rootkit多藏在内核驱动、引导管理器或者系统服务的缝隙里破坏或劫持操作系统本身。这类东西有个共性——它的运行依赖操作系统所以格式化C盘、重装Windows、用杀毒软件全盘扫描基本能把它按在地上摩擦。哪怕藏得再深只要把引导扇区重写、把驱动服务清干净系统还能恢复到一个相对可信状态。UEFI Rootkit不是这个套路。它把恶意代码放进SPI Flash芯片里的固件镜像也就是BIOS/UEFI固件本体。CPU在加电后的第一件事是从固件执行指令从SEC阶段一路走到PEI、DXE、BDS最后才把控制权交给操作系统引导程序。恶意代码如果在这个链条的早期获得执行那它在操作系统眼里就是一个“合法存在的祖先”它可以在启动早期把系统调用、内存管理、驱动加载路径全部安排妥当再放一个看起来干干净净的Windows给你用。这种差异最好用物业来类比传统Rootkit是租客在你家墙壁里加了个暗格你换锁、搬家就能甩掉UEFI Rootkit是有人在物业的钥匙总系统里做了手脚你把自己家锁全换一遍它照样能用备用钥匙进屋而且你根本不会去怀疑钥匙系统本身。这也是为什么安全圈把固件级攻击列为“重装系统解决不了的问题”。我见过不少运维同事处理可疑机器第一反应是“格式化重装”但面对UEFI Rootkit这个操作等于把家具全换一遍却不换门锁。1.2 UEFI启动链上RwDrv.sys为什么会被相中UEFI固件平时躺在主板上一颗SPI Flash芯片里容量一般8MB到32MB不等里面不只是BIOS代码还划分了描述符区、Management Engine固件区、Gigabit Ethernet配置区等区域。你要把一段恶意代码写进去不能像编辑文本文件一样直接改得先和主板上的SPI控制器打交道。这个控制器通常挂在某个PCI设备下通过I/O端口或内存映射寄存器暴露出来。写固件前还要处理两个关键位BIOSWE和BLE。一个负责打开写门一个负责封锁防止系统运行期间固件被随意改写。问题在于这些控制位本质上就是一组寄存器而对寄存器做读写恰恰是RwDrv.sys这类工具最擅长的事情。换个角度说恶意代码哪怕写得再精巧最终也需要一个抓手去物理访问SPI控制器。没有现成驱动的情况下攻击者得自己找一个能进Ring0的漏洞或自己写一个能通过签名的内核驱动成本都不低。而RwDrv.sys自带合法签名、接口现成、文档也公开只要想办法把它装进系统就等于拿到了一双可以摸到硬件的“手”。这正是它被选中进入固件攻击链的根本原因。1.3 一个真实样本复盘固件里的“房客”是怎么住进去的比较出名的一次事件是安全公司ESET在2018年披露的样本代号LoJax也是当时少见的在野UEFI Rootkit之一。我不想去复述过多背景只看技术路径攻击者先通过常规手段控制系统然后加载RwDrv.sys借助它读写物理内存和I/O端口定位到SPI控制器的寄存器接着操作BIOSWE等写保护位把恶意模块写入固件镜像的空闲区域。这个模块随后在系统启动的早期运行操作系统重装、硬盘更换都不影响它的“住所”。ESET在分析时发现受害者即使重新部署系统恶意固件模块仍会随着下一次开机重新落地形成一个非常顽固的持久化机制。LoJax最值得琢磨的一点是它不依赖什么0day内核漏洞用的驱动是公开下载来的、厂商签名过、安全软件一般不敢拦的合法驱动。整个过程你说它是“漏洞利用”也行说它是“合规工具误用”更准确。这个案例之后安全社区对带物理内存访问能力的驱动态度明显从“研究工具”转向了“攻击面”。2. 白帽面孔硬件调试者手里的“物理内存显微镜”先放下恶意场景。你要是做过板卡调试、固件分析、内核驱动开发应该能体会那种痛苦想看一眼某颗PCIe设备的配置空间Windows下没有现成命令想确认某个MSR是否生效写个驱动又得配环境加签名。RWEverything这类工具能活这么多年正因为它在这些场景里足够好使。2.1 功能全景这个驱动能碰到底层哪些东西我把RwDrv.sys在合法调试中常用的能力整理成一张表方便你对照自己的需求能力能做什么典型调试场景物理内存读写直接访问RAM物理地址内核结构实验、内存取证分析、驱动验证I/O端口访问读写x86外设寄存器老式设备调试、电源管理寄存器检查PCI/PCIe配置空间枚举设备、读取BAR和Capability网卡/NVMe/显卡识别问题排查MSR读写访问CPU模型特定寄存器确认系统调用入口、调试虚拟化特性ACPI/SMBIOS/DMI查看系统描述表固件兼容性分析、主板信息核对SPI Flash/Flash Descriptor读取/写入BIOS芯片固件备份、BIOS修改和救援这些功能单个拆开看都有专业软件或硬件编程器能替代但RW把它们集成在一起驱动加载后立马能用不用买调试工具也不用写内核代码。对维修工程师来说这就是一个数字万用表加逻辑分析仪的“穷人版组合”。2.2 一个最常见的调试场景查看PCIe设备的配置空间举个例子。朋友拿来一块拆机万兆网卡插上后系统识别不到。最有效的排查就是看PCIe总线上有没有这个设备它的Vendor ID、Device ID是否正确BAR有没有分配链路状态是否正常。在RW的PCI/PCIe Devices页面你能按总线、设备、功能号浏览整棵PCIe树。选中目标设备后右侧会列出配置空间原始内容和解析结果Vendor ID、Class Code、Capability甚至PCIe Link Status。以前这些信息要么靠Linux下的lspci/setpci要么靠写一个枚举驱动在Windows里非常不方便。RW把这条路缩短到了“打开软件、选设备、看寄存器”。如果你做固件开发或超频调试还能在配置空间里临时修改某些标准未公开的Capability位做对照实验。但我要强调一句这里面的每个位都对应硬件行为乱改轻则功能异常重则直接让设备从总线消失。动手前一定先去查对应设备的Datasheet或者先截图留底。2.3 MSR和内核态研究直接看透CPU的内部台账CPU有些寄存器不在普通应用程序可见的地址空间里叫MSR每种型号的CPU定义还不完全一样。做内核调试的人经常会读IA32_LSTAR也就是地址0xC0000082它保存着SYSCALL指令跳转的系统调用入口地址。在RW的MSR选项卡里输入地址就能直接读出来对照符号表判断当前系统调用表是否被hook。再比如说研究虚拟化的时候要确认虚拟化特性是否启用、查看VMX控制寄存器这些在RW里都能快速得到结果。以前要干这种事你得自己写一个带MSR读写功能的驱动处理完驱动签名还得处理蓝屏研究门槛高得多。RW把门槛降下来对学习底层的人来说是好事但也意味着能滥用它的人的门槛也降下来了这就是“双面”的来源。2.4 固件提取与BIOS修改UEFI社区里的常见用法不少玩固件的人都知道官方BIOS里的隐藏菜单可能被屏蔽或者某个老平台官方并不提供UEFI支持于是社区通过修改BIOS镜像、解锁隐藏选项或补齐模块来达到目的。这类工作流里RW常常负责最前一步把SPI Flash里的原始固件完整读出来再用UEFITool这类工具解包、修改、重组最后写回去。网上流传的一些“解锁版BIOS”很多就是用类似流程做出来的还包括某些老款笔记本型号的UEFI启动解锁。如果你也想做这类实验我劝你至少准备一个编程器夹子和一颗可拔插的SPI芯片把原固件备份好再动刀。不是每次写回都能成功尤其涉及到Flash Descriptor区域时写错可能连ME固件都跟着坏结果是开机直接黑屏只能拆机用编程器硬刷。3. 暗面被恶意加载的RwDrv.sys是怎么变成“特洛伊木马之手”的前面那些调试功能放到攻击者手里会有完全不同的叙事。攻击者根本不需要把RwDrv.sys当作普通工具打开他们要的是它底层那些读写能力。近几年的安全事件里针对带有签名的底层驱动实施攻击已经有了固定名字BYOVD自带易受攻击驱动。3.1 BYOVD自己带一个“有漏洞的司机”Windows 64位系统默认要求内核驱动有签名否则拒绝加载。这个机制拦住了一大批“野生驱动”却没拦住另一条路攻击者找一个已经拿到厂商数字签名的驱动比如RwDrv.sys、某些主板监控软件的自带驱动、某些远程管理工具的驱动直接把这个合法驱动的完整文件丢进目标系统然后创建服务加载它。系统签名校验看到“合法厂商”就放行了但它查验的是介质不是意图。打个比方机场安检确认你拿的是一个知名品牌的行李箱箱子的锁也是原装的但箱子里装的到底是什么它没打开看。RwDrv.sys这个名字本身就是原装锁恶意代码拿它来装武器谁都没觉得有问题。很多EDR产品会维护自己的驱动黑名单把已知可被滥用的驱动哈希或文件名加进去。但这类名单有一个天然滞后问题同一类驱动有不同版本、不同哈希厂商还可能发新版本。所以BYOVD到现在仍然是Windows平台上一个治理难度很高的问题。3.2 从用户态到Ring0抽象流程并不复杂我不打算在这里贴具体的利用代码没意义也危险但把步骤讲清楚有助于理解风险面攻击者拿到管理员权限后把RwDrv.sys放到磁盘创建同名内核服务。服务启动后驱动创建设备对象用户态程序可以打开这个设备并发送IOCTL请求。驱动根据请求完成物理内存读写或I/O端口访问。攻击者通过物理内存读取找到关键的内核结构地址再通过写入修改进程令牌、禁用安全监控或篡改内核数据。如果目标指向固件驻留就通过I/O端口或物理内存映射去访问SPI控制器关闭写保护把恶意模块写入固件。之所以说它危险不只是因为“功能多”而是驱动设备缺少细粒度的调用者限制。设计目标就是给调试者提供万能通道所以它像一个被锁在机房里的工具箱但机房大门长期没锁。任何能跑代码的进程理论上都可以试着敲门。3.3 恶意软件为什么会“点单式”使用这种驱动勒索病毒用这类驱动主要是为了关掉安全软件、干扰系统恢复甚至把副本备份删干净挖矿和僵尸网络要长期隐蔽运行一个签名驱动比漏洞利用更稳蓝屏概率低间谍软件则看重固件驻留能把主模块藏到重装也找不到的地方。这些行为没有一个是RwDrv.sys独有的。任何能够读写物理内存、又有有效签名的驱动都可能被滥用只是RwDrv.sys的接口文档公开、案例多、检测特征也被研究透了。安全系统把它拉黑不冤合法用户被误伤也很常见。这种矛盾本身就是底层调试工具发展过程中的一个缩影。3.4 固件驻留为什么难清如果恶意代码真的进了固件清除就不是“卸载驱动”这么简单了。杀毒软件运行在操作系统上层对启动前运行的代码缺乏可视性重装系统和更换硬盘都不会擦到SPI Flash普通用户也很少有能力拆机、用编程器或CHIPSEC去重刷整个固件。更麻烦的是现在很多主板固件里还有独立于CPU运行的Management Engine或类似组件它们的固件区域通常在Flash Descriptor中被锁定。即使你想把固件恢复官方版本刷新工具也可能因为平台保护拒绝操作。所以现实中的处理流程普遍是备份资料使用厂商提供的完整固件恢复工具再不济只能换主板。这也解释了为什么防御重点要放在“别让它第一次写进去”。4. 检测与防御怎么确认自己的电脑没有被“双面人”盯上说了这么多风险回到实际问题我该怎么知道自己机器里有没有RwDrv.sys发现它又该怎么办我的建议是先别慌按下面这套顺序来排查。4.1 在系统里快速定位驱动加载情况RwDrv.sys作为一种内核驱动加载后通常会在系统里留下服务项。最容易的办法是管理员身份打开命令提示符运行driverquery /v这里能看到当前加载的驱动列表包括服务名、路径、状态。看到和RW相关的服务名再用注册表编辑器确认一下HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services在这里搜索RW或RwDrv关键字能看到驱动映像路径和启动类型。Sysinternals的Autoruns打开后切到Drivers页签更容易发现那些加载时间、路径、描述都不正常的驱动项。System Informer的内核模块视图也可以辅助确认。要说例外情况如果加载驱动的恶意代码已经具备很强的隐蔽能力会在这些常规列表里把自己摘出去。真要做严谨排查应该把磁盘拆下来挂到另一台干净机器上取证或者用包含CHIPSEC等工具的启动U盘做离线检查。对绝大多数普通用户来说能在服务列表里发现一个不明来源的RwDrv已经是一个值得追查的线索。4.2 固件层面的“体检”CHIPSEC使用入门经常碰固件的人建议装一个CHIPSEC它本身是开源的固件安全分析框架不依赖操作系统版本在物理机上以管理员身份运行就能检查主板固件的安全状态。检查SPI写保护是否开启用这条命令chipsec_main -m common.bios_wp想看当前固件内容备份一份出来做哈希对比chipsec_util spi dump -o backup.bin把backup.bin的SHA256和主板官网下载的BIOS镜像做对比。如果差异明显且不是厂商自己的工具或配置区域造成的那就要高度警惕。需要注意chipsec_util还支持spi flash命令做擦写这个操作风险极高不熟悉平台的情况下不要乱试写坏SPI芯片只能靠编程器硬救。4.3 Windows现有防御机制能挡住多少面对BYOVDWindows也不是全无准备。Windows 10 1903之后系统会通过更新维护一份“易受攻击驱动屏蔽列表”名字带RW或被安全社区标记过的驱动版本加载时可能被直接拦下。玩底层调试的人如果发现驱动加载失败先想想是不是被这个列表开了刀。其次是内存完整性也就是HVCI它用虚拟化技术把内核代码完整性检查隔离起来。即使攻击者加载了能读物理内存的驱动篡改内核关键数据的难度也会明显提高。企业环境里还可以用WDAC这类应用控制策略从启动阶段就制定“只允许指定签名的驱动加载”白色名单比黑色名单可靠得多。Secure Boot则主要负责启动链路的早期校验能挡住未签名的引导程序但对“固件中已经植入恶意模块、整体仍符合校验流程”的情况它就无能为力了。合理的姿势是Secure Boot、HVCI、驱动黑名单、固件写保护一起配合而不是指望某一道墙独揽所有安全问题。4.4 日常维护里的几个“反惯性”动作有几个操作习惯是这些年在实际维护里总结出来的。更新BIOS只从品牌官网下载下载之后顺手核对SHA256别用搜索引擎结果页里来源不明的“解锁版”开机进BIOS查看有没有Flash Write Protection类似选项有就打开重要设备要保存一份“出厂固件备份”恢复的时候心里才有底。如果电脑送修过拿回来后最好做一次固件校验和驱动列表对比。维修环境下偶尔会有人用RW这类工具测试硬件走的时候驱动没清干净这种情况不算恶意但也不清不楚事后发现总比不知道强。5. 关于RwDrv.sys我踩过的坑和现在的操作习惯最后这部分讲点零零碎碎但实战里经常用得到的经验。5.1 合法调试时最容易翻车的两个操作我在调试时踩过最狠的坑一次是没备份就写SPI以为只是改一个启动Logo结果把Flash Descriptor区域带走主板直接不亮另一次是想验证某个CPU隐藏特性随手写了一个保留MSR系统当场就Hang住最后靠抠电池、清CMOS才救回来。从那以后我给自己定了三条规矩改动任何寄存器之前先记录当前值只动在官方Datasheet或SDM里明确查过的位SPI相关的操作第一次必须在带编程器夹子的条件下做。这不算胆小底层硬件的很多状态是不可逆的多一份准备就少一次变砖。5.2 研究时的隔离实验习惯现在我在主力机上不会轻易加载这类驱动。涉及物理内存读写、MSR和SPI的实验全部挪到一台专门的测试机上跑要做恶意样本分析就在虚拟机里加载驱动、打开监控观察它到底访问了哪些设备和内存区域。隔离环境还有一个好处你可以大胆把驱动“折腾”崩溃不用心疼开发机。如果你在安全研究里遇到可疑样本伪装成RwDrv.sys记得先抓它的加载行为、文件释放和网络回连这些证据比杀软提示更有说服力。5.3 应急响应时的判断顺序看到系统里出现RwDrv.sys时不要立刻下“中毒”的结论。我会按这个顺序判断先看文件路径和签名正常安装的RW通常带有GUI程序和安装包路径应该在Program Files或用户目录下再看时间线驱动创建、服务创建、恶意行为发生的时间是否吻合最后查调用者是哪个进程加载或调用了它它的父进程链又是什么。如果确认是恶意加载那就别在系统里反复折腾了第一时间保留内存镜像、驱动文件、服务注册表项和日志再走标准的事件响应流程。排查经验多了之后你会发现这类驱动出现的场景五花八门有维修师傅忘记清理的有超频软件自动装的也有真正的攻击者塞进来的。判断的关键永远是上下文而不是文件名本身。接触底层系统越久我越觉得RwDrv.sys就像一个没有安装说明书的工具箱放在硬件调试的桌面上是趁手工具被塞进恶意代码的手里就是越狱钥匙。工具本身没有立场立场永远来自使用它的人。能做的无非是让自己既有能力看清它也有机制防止它被不该用的手拿走。
返回列表