劫持和应用包名

核心提示作者:0x7F@知道创宇404实验室1前言2020年12月,SolarWinds 攻击事件引发全球的关注,攻击团队在 2020年上旬通过对 SolarWinds Orion 产品实现供应链攻击,导致诸多厂商被攻击,造成了不可估量的损失。这种

作者:0x7F@了解于闯404实验室

一个

2020年12月,网络安全管理软件产品袭击事件引起全球关注。2020年初,攻击团队攻击了网络安全管理软件产品猎户座产品,导致多家厂商受到攻击,造成不可估量的损失。这种国与国之间的APT攻击包含了大量的技术细节,其中供应链攻击的实现,也就是旭日后门的植入,引起了我极大的兴趣。

2021年1月,旭日后门植入分析在网上公开,随后安全研究人员进一步优化了植入细节。根据这些内容,我开始了对dll劫持的学习和研究。详细介绍了dll劫持,并试图模仿旭日后门植入的方法,在C编译器上实施“供应链攻击”。

本文的测试环境是Windows7 x64 sp1,开发环境是MinGW-x64+Python3.6

2

后门植入和优化

先简单看一下旭日后门植入的过程:它是由一个名为taskhostsvc.exe的程序完成的,通过预定的任务设置,随主机启动运行。

在taskhostsvc.exe启动后,通过创建互斥体保证只有一个实例在运行,然后每秒从进程中搜索MsBuild.exe进程。找到它之后,通过读取MsBuild.exe的内存,从命令行参数中获得构建项目的目录路径。

然后,在项目目录中搜索猎户产品InventoryManager.cs的源代码文件,替换为包含恶意代码的源代码文件,等待MsBuild.exe编译完成,最后还原文件完成后门的植入;如下图:

[1.旭日后门植入过程]

当然,这个过程中需要大量的技术细节,保证后门与原项目代码的兼容性,以及植入过程的隐蔽性等。后来有安全研究人员表示,上述植入过程在APT攻击中并不完美。例如,通过规划任务和周期性的进程扫描,很容易暴露攻击行为。其次,监控MsBuild.exe到最终替换源文件的执行时间可能会影响后门植入的成功率。

安全研究人员提出利用dll劫持来优化后门植入过程。在研究过程中,他们发现指定目录中的dll会在MSBuild.exe启动时优先加载,如下所示:

[2.MSBuild优先加载的部分dll文件]

如果我们重命名恶意的dll并把它放在这些“load-not-found-dll”路径中,我们就可以劫持dll并执行我们的恶意代码。原作者就是按照这种方式写代码来演示的。与taskhostsvc.exe相比,这种方法不需要额外的进程来监控,dll在程序执行前加载,程序执行后释放,也非常适合控制和清理程序。

dll劫持概述

dll作为windows的函数库,有助于促进代码模块化、代码重用、有效内存使用、减少磁盘空;当一个应用程序运行时,可能需要依靠多个dll的函数来完成它的功能。如果控制了任何一个DLL,就可以控制应用程序的执行过程。

学习dll劫持,首先要知道dll的搜索顺序,这也是攻守双方兵家必争之地。微软近年来一直在加强这一块。对于桌面程序,当前默认的DLL搜索顺序是:

应用程序加载的目录

系统目录,使用GetSystemDirectory获取该路径。

16位系统目录

Windows目录,使用GetWindowsDirectory获取路径。

当前目录

PATH环境变量中列出的目录

默认情况下,HKEY _ local _ machine system current control set control session manager safedllsearchmode处于打开状态;如果手动设置为0,则关闭安全选项,搜索顺序为:在上述顺序的基础上,修改5。当前目录到2。系统目录,并将其他目录向前移动。

当应用程序加载dll时,如果只指定了dll名称,将按上述顺序搜索dll文件;但是,在加载前需要满足以下两个规格:

1.当内存中已经加载了一个具有相同模块名的dll时,系统会直接加载该dll而不进行搜索;除非设置了dll重定向选项。

2.如果要加载的dll模块属于已知的DLL,系统会直接在系统目录中加载DLL,而不会进行搜索;已知dll列表:HKEY _本地_机器系统当前控制集控制会话管理器已知dll

由于dll迭代更新的不兼容性,微软提出了dll重定向的解决方案,让应用程序可以自行选择加载dll。

了解以上基本内容后,替换dll搜索路径上的文件,就可以实现dll劫持了。

请参考https://docs . Microsoft . com/en-us/windows/Win32/DLL/dynamic-link-library-security了解微软DLL中安全加固的详细信息。

Dll函数转发

通过用恶意dll替换原文件,应用程序可以加载我们的dll并执行恶意代码,但是应用程序的运行依赖于dll提供的函数,而恶意dll必须提供相同的函数才能保证应用程序的正常运行。所以我们先来了解一下dll函数转发。

1.手动转发当dll的导出函数较少时,我们可以按照正常的dll开发流程逐个定义函数名,然后使用函数内部的LoadLibrary函数调用原dll的对应函数来完成函数,如下:

[3.加载库转发功能]

2.def文件当dll的导出函数过多时,我们无法手动转发。用模块定义文件写导出函数的信息,链接器会自动转发函数。详情请参考https://docs . Microsoft . com/en-us/CPP/build/reference/module-definition-dot-def-files view = msvc-160。

我们尝试生成version.dll的恶意dll:在test.c文件中编写恶意代码,插入到DllMain的执行过程中,在test.def中编写函数转发规则:

[4.使用dll模块定义的函数转发]

然后编译生成dll文件。gcc编译如下:

gcc-墙-共享测试. c测试. def-o version.dll

在。def文件,我们将原始文件命名为version_origin.dll应用运行时,我们的恶意version.dll会被加载,调用函数时,恶意version.dll会转发函数:

something.exe = > version.dll = >版本_起源. dll

这里我写了一个Python脚本,可以根据DLL自动生成模块定义文件dllProxy _ def _ generate.py,使用方法如下:

[5.自动生成模块定义文件]

有些dll导出函数没有导出名称,只有导出序列号。Gcc和Tcc不支持通过序列号导出的函数的转发。读者遇到可以用VisualStdio。

3.pragma预处理除了上述模块定义文件实现函数转发,还可以使用pragma实现。详见https://docs . Microsoft . com/en-us/CPP/preprocessor/comment-c-CPP view = msvc-160。也以version.dll为例。函数转发的源代码如下:

[6.pragma实现dll函数转发]

但是,pragma关键字仅由Microsoft编译器提供。

路径劫持

根据以上知识,我们可以自由生成恶意dll文件,并通过函数转发使其调用原dll函数,根本不会影响应用程序的正常运行。此外,恶意代码一般可以添加到DllMain中,使代码在加载dll时被触发,或者添加到指定函数中准确劫持程序进程,具体要看实际场景。这里我们的恶意dll已经准备好了。

根据dll的类型,我们大致可以将劫持分为两种方式:

1.自定义dll有些应用程序使用自定义dll,它是该应用程序独有的,并且只由该程序加载和使用。dll可以放在与应用程序相同的目录中,也可以放在PATH环境变量中,或者由LoadLibrary加载一个特定的目录。

这样我们用恶意的dll替换目标文件,然后把原来的dll重新命名,放在应用程序的同一个目录下。当应用程序启动时,我们可以加载我们的恶意dll。

2.公共dll

当然,我们可以劫持公共dll背景:rgb边框半径:0.3毫米;white-space:pre-wrap " > user 32 . dll),但公共dll一般是由其他进程提前加载的。当需要加载一个新的应用程序时,将直接从内存中加载和调用它。如果我们用恶意dll替换公共dll,需要重启才能生效。

例如,下面是我们如何使用恶意dll来替换msvcrt.dll。恶意dll在加载时输出应用程序路径,重启后可以看到:

[7.劫持系统dll的示例]

因为是公共dll,所以所有程序都会加载恶意dll。该方法可用于监控、蜜罐等场景。

1.替换系统dll。可以使用普通用户作为所有者修改文件,然后设置读写权限,这样就可以修改和替换文件了。2.你不能劫持非常低级的dll比如ntdll.dll/kernel32.dll,,因为这些dll实现了程序加载和函数转发的功能。

Dll重定向劫持

我们在学习的过程中发现,有些应用程序仅仅依赖于系统dll,而这些dll已经被其他程序加载了。例如,kernel32.dll和msvcrt.dll是MinGW唯一的依靠。除了以上公开的DLL劫持,还有没有更好的办法?

在对0x02 dll劫持的总结中,我们还提到了一个特例:dll重定向。当其他应用程序将具有相同模块名称的dll加载到内存中时,可以使用此方法强制加载指定的dll文件。这样也可以实现dll劫持。

dll重定向的默认状态是关闭。我们在注册表中的HKLM 软件微软 Windows NT 当前版本镜像文件执行选项中添加DevOverrideEnable字段并设置为1来开启该功能,重启后生效。

[8.注册表打开dll重定向]

我们有两种使用dll重定向的方法:

1.。当地的

在与应用程序相同的目录下,创建AppName.exe.local目录当应用程序启动时,将首先从该目录加载dll文件。

我们编写了一个HelloWorld的C程序来生成恶意msvcrt.dll进行演示。目录结构是:

。test.exe├──test . exe . local│├──msvcrt . dll│└──msvcrt_origin.dll├──helloworld.c└──

运行演示如下:

[9.本地重定向的示例]

2.manifest也可以使用清单配置文件,它的优先级高于。本地的。详情请参考https://docs . Microsoft . com/en-us/windows/win32/sbscs/application-manifest。目录结构如下:

。├──helloworld.c├──msvcrt_origin.dll├──msvcrt.dll├──msvcrt.dll.manifest├──test.exe└──测试

清单文件的内容包括:

[10 .清单内容示例]

您还可以加载恶意的dll文件。

Tcc劫持实现

Tcc是一个相当小的C编译器。我们从一个简单的对C编译器的“供应链攻击”开始。

我这里用的是TCC 0 . 9 . 27版本。结合逆向分析,可以确定tcc.exe依赖的是同一个目录下的libtcc.dll文件,所以直接替换dll文件即可。

我们模仿旭日后门植入的方法,编写如下恶意代码演示:

[11.Tcc劫持代码演示]

编译后,恶意dll被用来替换libtcc.dll,原文件被重命名为libtcc_origin.dll运行演示如下:

[12.Tcc劫持演示]

可以看到Tcc编译的程序在执行时触发了恶意代码后门。

Gcc劫持实施

我们再试试Gcc。通过分析发现,它只取决于kernel32.dll和msvcrt.dll。所以在这里,我们劫持msvcrt.dll文件,并使用dll重定向方法,使Gcc加载恶意的dll文件。

用Tcc中的测试代码进行编译,然后在Gcc目录中添加Gcc.exe.local文件夹,将msvcrt.dll/msvcrt _ origin.dll放入该文件夹,如下所示:

[13.gcc目录中的dll重定向文件夹]

运行演示如下:

[14.Gcc劫持演示]

摘要

在此,感谢大午@知乎于闯404实验室伙伴对我学习和研究的帮助。在dll劫持的基础上,一步步讲解和演示dll劫持,讲解dll劫持的一些场景和利用,最后模仿旭日后门植入的方法,实现对C编译器的“供应链攻击”。

其实文中提到的“供应链攻击”对编译器的方法还可以进一步优化,因为我们的方法会重写文件,会修改文件的写入时间,可能暴露攻击行为;我们还可以逆向分析编译器的执行过程,更准确地劫持读取文件的功能,在内存中植入恶意代码,读者可以自己尝试。

但是dll劫持的攻防对抗已经发展了很久,微软在保证功能的前提下提供了相对完善的防御措施;对于上面描述的劫持方式和场景,可以根据文中的技术细节进行防御,比如路径、注册表、文件等。

10

参考

https://us-cert . cisa . gov/ncas/alerts/aa20-352 a https://www . crowd strike . com/blog/黑子-malware-technical-analysis/https://www . a12d 404 . net/ranting/2021/01/17/msbuild-back door . html https://en . Wikipedia . org/wiki/2020 _ United _ States _ federal _ government _ data _ breake https://docs . Microsoft . com/en-us/windows

 
友情链接
鄂ICP备19019357号-22