DLL 代理加载 shellcode

Andrew 2020-10-27
专栏 - 观点观察 发布于 2020-10-27 17:59:01 阅读 174 评论 0

DLL侧面加载或DLL代理加载允许攻击者滥用合法的和经过签名的可执行文件,以在受感染的系统上执行代码。自2017年以来,这种技术一直很流行。

代理加载与DLL劫持非常相似,但是,它不会破坏原始程序的执行流程或功能。除了将恶意活动隐藏在合法应用程序之后,它还可以用作持久性方法。

总览

为了了解DLL代理对攻击者的加载效果如何,我们首先需要了解当今的典型应用程序如何为第三方库加载外部函数。

使用上面的示例流程,将发生以下情况。

  1. 在启动时,应用程序(A )需要使用名为“ GetFunkyData()”(C)的第三方函数来获取数据,GetFunkyData()存在于名为“ DataFunctions.dll”(B)的动态链接库中,该库位于工作环境中。应用程序的目录。

  2. 应用程序(A)尝试按其名称加载库“ DataFunctions.dll”,以尝试执行“ GetFunkyData()”(C)。由于该函数存在于库(B)中,因此将执行该函数,并且应用程序将正常运行。

执行DLL代理加载攻击时,流程略有不同。

  1. 在启动时,应用程序(A)需要使用名为“ GetFunkyData()”(D)的第三方函数来获取数据,GetFunkyData()存在于动态链接库中,该动态链接库位于工作目录中,名为“ DataFunctions_Original.dll”(B)。应用程序的

  2. 应用程序(A )通过其名称加载库“ DataFunctions.dll”,以尝试执行“ GetFunkyData()”(C)。该DLL实际上是攻击者专门设计的“代理”库,代理DLL使用外部导出/链接器引用将功能调用重定向到原始DLL“ DataFunctions_Original.dll”(B)。该功能由应用程序找到并执行

  3. 此时,攻击者已经劫持了执行流程(C),并且可以代表运行中的进程(E)执行代码,而无需用户或应用程序的了解。

查找目标可执行文件

在寻找目标可执行文件时,应牢记以下几点:

  1. 大小,我们通常正在寻找小于10 MB(通常小于1 MB)的可执行文件。

  2. 签名,目标应该是经过数字签名的“合法”可执行文件。这越多越好。

  3. 在运行时不安全地加载少量DLL ,可执行流必须是可劫持的,但我们不希望将超过1-3个DLL放到目标上以使我们的攻击才能顺利进行。

  4. 根据我们的战术我们要如何绕过Defense

这里分享一个我的方法:

我的典型方法是前往Ninite这样的网站,从常见的软件供应商那里下载一些应用程序,然后开始在安装目录中四处浏览。对于此示例,让我们尝试FileZilla。默认情况下,FileZilla的x64位安装最终位于“ C:\ Program Files \ FileZilla FTP客户端”中。该文件夹包含几个可执行文件以及DLL。

我们接下来要找出哪个DLL是软件运行的必要DLL(也就是说如果没有哪个DLL,软件就运行不了),简便的方法是将一个可执行文件简单地复制到一个单独的文件夹中并运行它。

真好!看来fzsftp.exe需要“ libnettle-7.dll”来执行,那么我们们从之前的“ C:\ Program Files \ FileZilla FTP Client”文件夹中复制libnettle-7.dll文件,然后重试!

可以运行,没有任何没有错误。我们可以使用Process Hacker之类的工具来检查应用程序加载了哪些模块,并进一步确认该DLL确实已加载。

SharpDllProxy –制作代理有效负载

下一步是制作我们的代理DLL,以将合法函数调用重定向到原始DLL,以及在后台静默加载我们的shellcode。为了简化此步骤,我创建了一个名为“ SharpDllProxy”的简单Dotnet核心应用程序。SharpDllProxy(https://github.com/Flangvik/SharpDllProxy)基于导出的函数生成代理DLL源代码,该函数从原始DLL中提取。生成的源代码只需将文件读入内存,然后将其调用到新线程中即可。假设我们提供的文件是我们要部署的原始shellcode。

用法很不言自明(你懂的 绕过一下杀毒什么的)

我们把 libnettle-7.dll使用SharpDllProxy输出一个“ / output_libnettle-7”的新文件夹。

SharpDllProxy在原始的“ libnettle-7.dll” DLL中找到了总共441个函数调用,并生成了完整的代理DLL源代码,该函数将函数调用重定向到tmp8AA5.dll(这是原始“ libnettle-7.dll的副本” ”(刚刚重命名)。现在,我们只需要编译保存到“ D:\ SharpDllProxy \ output_libnettle-7 \ libnettle-7_pragma.c”中的源代码。

打开Visual Studio,单击“创建新项目”。

选择C ++作为您的语言,搜索“库”,然后单击“动态链接库(DLL)”模板。

名称应与原始DLL名称匹配,命名“ libnettle-7”,然后单击“创建”。默认情况下,我们将进入“ dllmain.cpp”,那么只需将“ D:\ SharpDllProxy \ output_libnettle-7 \ libnettle-7_pragma.c”的全部内容复制并粘贴到此文件中就行。

分析一下代码,我们看到一旦触发了DLL_PROCESS_ATTACH事件(L485-489),生成的源代码就会创建一个新线程。然后,“ DoMagic()”继续从本地文件“ shellcode.bin”(L455-465)中读取二进制数据到缓冲区中。我们使用SharpDllProxy生成源代码时定义了文件名“ shellcode.bin”。然后将该缓冲区复制到内存中并调用。

接下来我们要编译此文件,请选择对应的结构(x64 / x86),选择“release”,然后选择“Build” -> “Build Solution”.

根据我们Visual Studio保存的位置,这里我们保存在“ C:\ Users \ source \ repos \ libnettle-7 \ x64 \ Release”。

将DLL复制到由SharpDLLProxy创建的先前的输出文件夹中,添加目标可执行文件以及任何x64 shellcode作为名为“ shellcode.bin”的原始文件。我们现在也可以删除“ libnettle-7_pragma.c”文件。

我们可以从MSF或CS等等生成一些简单的shellcode。例如:

msfvenom -a x64 –platform windows -p windows/x64/messagebox TEXT=”Proxy Loading worked!” -f raw > shellcode.bin

把生成的shellcode命名为shellcode.bin,然后放进fzsftp.exe文件夹中。

接下来,我们只要运行fzsftp.exe,fzsftp.exe调用libnettle-7.dll,就会从磁盘读取我们的Shellcode.bin,然后执行它,并且不会破坏应用程序的功能。就这样悄悄的执行了。

原创:黑白天
原文链接:https://mp.weixin.qq.com/s/XFppenDlXcEp-FD...

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!