免责声明
合法使用原则:文中提及的技术、工具或案例,仅用于授权范围内的安全测试、防御研究或合规技术分享,未经授权的网络攻击、数据窃取等行为均属违法,需承担法律责任。
风险自担与责任豁免:文章内容基于公开信息整理,不保证技术的准确性、完整性或适用性。读者需自行评估技术应用风险,若因不当使用导致任何法律后果或损失,均由使用者自行承担,与本公众号及作者无关。
法律管辖与提示:本公众号坚决拥护相关法律法规,反对任何危害网络安全的行为,读者需严格遵守法律法规。
一、基本概念
- “白加黑”是一种利用合法、可信赖(“白”)的应用程序加载恶意(“黑”)的动态链接库(DLL)来执行恶意代码的技术,其核心在于利用操作系统和安全软件对带有有效数字签名的知名“白”文件的信任,来掩盖恶意“黑”DLL的活动,从而绕过静态签名检测和行为监控
- 白:指具有合法数字签名、来自可信发行者的应用程序(
.exe
文件) - 黑:指攻击者精心制作的、包含恶意功能的动态链接库(
.dll
文件) - 加:将恶意DLL与合法EXE“组合”在一起使用,利用EXE加载DLL的机制来执行恶意代码
二、核心原理
- 借壳隐身:利用带强数字签名的合法可信程序(白EXE)作为“壳”,加载并执行恶意代码(黑DLL)
- 信任转移:安全软件对“白EXE”的信任会部分转移到其加载的DLL上(尤其是同目录下的),降低对恶意DLL的警惕性
- 搜索劫持:利用目标白EXE存在的DLL搜索顺序漏洞,使其优先从自身目录加载攻击者放置的同名恶意DLL,而非系统目录下的合法DLL
三、DLL介绍
基本概念
- DLL(Dynamic Link Library,动态链接库)是Windows操作系统中实现模块化编程与资源共享的核心机制,其本质是一种PE格式的可执行文件(扩展名为
.dll
),与EXE文件结构相似,但是与EXE文件不同的是,DLL不能独立运行。 - DLL的核心价值在于封装了可以被多个程序共享调用的函数、数据、资源等等,当程序需要调用函数时就需要载入DLL,取得函数的地址,然后进行调用。
- 使用DLL文件的好处是程序不需要在运行之初加载所有代码,只有在程序需要某个函数的时候才从DLL中取出。
在VS中新建一个DLL
DLL文件结构
- 在VS新建完DLL以后,可以看到默认的文件结构主要包含两个头文件(framework.h、pch.h)和两个源文件(dllmain.cpp、pch.cpp)
framework.h
- 这个文件包含了整个DLL项目所有源文件(
.cpp
)都需要用到的头文件(Windows API、C/C++ 标准库等),通常它会被包含在pch.h
(预编译头文件)中 - 这个文件的主要目的是为了简化源文件中的包含语句,在这里集中管理所有必要的头文件包含,可以减少重复调用
pch.h
- 这个文件是预编译标头文件,它的核心作用是加速项目的编译过程,同时可以声明DLL导出接口(函数、类、变量)
- 预编译头文件机制会将
pch.h
及其所包含的所有头文件(比如framework.h
)预先编译成一个中间格式(.pch
文件),后续编译每个.cpp
文件时,编译器不需要再反复解析这些庞大的头文件 - 导出函数声明:在这里可以定义/声明导出函数,说明DLL对外提供了哪些函数,后续在源文件中就可调用该函数来实现具体的功能
dllmain.cpp
- 这个文件包含DLL的入口函数
DllMain
,操作系统在加载(LoadLibrary)或卸载(FreeLibrary)DLL 时会自动调用这个函数
pch.cpp
- 这个文件有两个主要作用:
- 生成预编译头文件(
.pch
): 它是预编译头文件机制的工作文件,编译器通过编译这个文件(它只包含pch.h
)来生成.pch
文件,供其他源文件使用 - 实现导出功能: 在
pch.h
中声明的导出函数后,导出函数具体实现代码就在这个文件中编写,当然也可以创建新的.cpp
文件来实现
加载器编写
- shellcode加载器的代码与exe格式下的一样,只不过在DLL项目里放置的位置有所差异
- 有两种方式编写黑DLL
- 可以将导出函数放在dllmain.cpp中,shellcode加载器的代码可以直接放置在程序执行时会调用的导出函数中
- 也可以在pch.h中先定义导出函数,然后在pch.cpp中调用导出函数来运行shellcode加载器的代码
四、实现白加黑
第一步:寻找白程序
- 由于我们自己编写的程序是没有合法的数字签名的,所以需要寻找拥有合法数字签名的白程序,挖掘出这个白程序调用的dll文件名叫什么,相应的dll定义了哪些导出函数
- 可以使用SkyShadow工具进行挖掘
- 要将该工具包中Tools文件夹的路径加入到环境变量(Path)
- 使用方法如下,运行后会扫描指定路径下的所有程序,检测出哪些程序有数字签名、对应程序调用的dll文件名叫什么,dll对应使用了什么导出函数
python SkyShadow.py D:日常软件
D:日常软件:这个路径下包含了我们平时安装的一些exe程序(按照实际情况来指定该路径)
- 运行完以后,来到工具包的Payload文件夹,就能看到结果,每个文件夹中都会包含一个exe程序和一个txt,这个txt文件的内容就包含了这个exe调用的dll文件名叫什么,使用了什么导出函数
- 注意:在选择白程序的时候,可以先点击运行一下这个exe,看只弹框一次,显示找不到xxxx.dll,如果有多个弹框,说明后续需要编写的dll文件就有多个,就会导致在钓鱼的时候总体的文件数量过多,反而效果不好,所以尽量选择只弹一次框的作为白程序
第二步:编写黑DLL
- 找到白程序调用的dll所需的导出函数后,可以将这些导出函数全部复制到dllmain.cpp中,然后编译
- 注意,txt中apixxxx.dll相关的内容不用复制
- 此时将编译好的dll重命名为白程序需要调用的dll文件名,并复制到刚刚检测出来的白程序所在目录,然后点击这个白程序,此时依然会弹框,弹框的内容会显示调用了哪些导出函数(函数名)
- 知道调用了哪些导出函数以后,此时选择其中一个导出函数,将原来用于弹框的代码(
MessageBoxA()
)替换为shellcode加载器的代码,对于其它的导出函数,只需要删除用于弹框的代码(MessageBoxA()
)并保留return 0;
,完成后重新编译,将编译好的dll重命名为白程序需要调用的dll文件名,当用户点击exe时就会调用这个dll上线
拓展
- 可以将shellcode注入到正常运行的进程的内存空间中,然后修改进程线程的指令指针使其跳转到注入的shellcode地址,实现恶意代码在目标进程中的执行,从而上线目标主机
原文始发于微信公众号(AegisGuard):《白加黑:当恶意代码披上 “合法” 外衣》
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论