Windows加载DLL的规则:首先会尝试从当前程序所在的目录加载DLL,如果没找到则在Windows系统目录中查找,如果还是没有则会去环境变量中列出的各个目录下查找。
动态链接库(DLL)劫持原理:攻击者能够利用Windows加载DLL的规则,将需要劫持程序目录下的合法DLL替换成恶意DLL。
DLL劫持技术已经存在了多年,早在2010年就被发现,那为什么我们还要不停的炒剩饭呢?因为它仍然是一种可行的方法,并且在在野的APT攻击样本中仍然占有一席之地!当越来越多的APT组织逐渐暴露在大家的视野中,它们使用的攻击载荷随之曝光,经过长期分析与研究我们发现能够挖掘或使用0day攻击的APT组织凤毛麟角,绝对部分是使用现有技术与冷门技术来进行攻击。目前大部分的软件开发者仍然没有安全意识或者是说不具备相关安全相关的技能,市面上仍然有许多经过签名的可执行文件容易受到此技术的攻击,那么作为红队我们可以将DLL劫持技术武器化,即使DLL劫持技术不是新技术也不是尖端技术,但本文章仍然会分享一些如何找到可以利用程序和应该如何构造劫持的DLL。
大部情况下,程序开发者使用LoadLibrary API动态加载DLL,该可执行程序首先将在当前目录中查找需要的DLL。只需要将合法的PE文件复制到攻击者具有读写的目录中即可,如果攻击者创建了一个恶意载荷的DLL,则合法的应用程序将加载该DLL并执行攻击者的代码,而且该PE可能已签名并且被安全软件所信任,由此可能绕过白名单机制。
接下来我们分析一个示例,我们使用一个被微软签名过的二进制软件WinWord.exe。
那么我们为什么使用这个模块呢?
1.该模块为Word的主模块,用于钓鱼邮件迷惑性非常大。(那么我选用白文件时优先考虑这类型的模块,可以根据具体渗透场景去选定)
2.该模块有微软的数字签名。(数字签名也是分三六九等,一般微软签名的数字证书的程序会相对一般的数字证书更安全)
我们可以使用IDA将该PE文件拖入分析,首先找到该PE文件的函数导入表,找到LoadLibraryWInAPI然后使用IDA交叉引用功能,找到所有引用该函数的具体代码。
我们可以看到该模块有6个地方调用该API,那么我找到其中一处具体分析。
我们可以看到第一个LoadLibrary加载了wwlib.dll,而且经过分析发现并没有相关的验校代码。
由下图可见,在Load后就获取了FMain,随后就调用该导出函数。
如果无法使用IDA静态分析我们可以使用API监控软件来观察,如火绒剑或API Monitor,当然也可以使用OD下断点来分析。(这里和使用IDA没什么区别,不同的PE文件用不同的方式来达到最好的效果)
接下来我们就要确定WinWord.exe调用了wwlib.dll的那些导出函数。
一般劫持方法有两种,一种是劫持DLL的导出函数,第二种是在DLLMain中劫持,但是第二种劫持方式仅限于C/C++对于.NET的DLL是没用的,因为.NET的DLL是没有DLLMain这个初始函数的。由以上代码可知,如果我们使用第一种方法劫持,则在加载了wwlib后会调用FMain,但是在调用前会判断其他两个函数是否获取成功所以还需要导出另外两个函数。
新建一个DLL的工程,并写出3个导出函数,并将DLL命名为wwlib。
编写完成后放在同目录下即可,我们开到该exe成功加载了我们自定义的DLL,并且是由word.exe加载的。
上面提到了还要一种方式更为简便更为通用一些,但仅限于C/C++编写的PE文件,那就是劫持DllMain中的控制流。
如果选择这种方式,就没有必要枚举并满足所有需要的导出。在某些情况下,DLL没有任何导出,只能通过DllMain入口点进行劫持。
将代码稍微改一改就可以了,在DllMain中DLL_PROCESS_ATTACH选项下调用下FMain,并注释掉退出代码,接下来会看到两次弹窗,第一次弹窗是在调用LoadLibrary加载wwlib模块时由DllMain加载的,第二则是由导出函数调用的。(DLL_PROCESS_ATTACH当DLL被初次映射到进程的地址空间中时执行)
其实网络世界中存在大把存在DLL劫持漏洞的应用程序,那么我们该如何选择对应的可执行文件呢?
1.独立的EXE文件来调用恶意DLL。(独立EXE必须为合法的白文件)
2.独立的EXE文件必须具有数字签名,并且该数字证书不会在短期内过期。
3.数字签名最好包括微软的数字签名。
4.独立的EXE必须使用Load来加载DLL且没有验证DLL。
通过以上方法可以在System32目录中容易受到DLL劫持的EXE,例如Dism.exe.
这是一个部署映像服务和管理的程序,对该系统程序进行动态分析,观察到它正在尝试在当前目录中加载DismCore.dll文件,如下图所示:
接下来,我们从其正常路径(C:\Windows\System32)将DISM系统程序加载到API Monitor中可以看到,如下图所示:
然后我们用之前的模块修改一下名称可以看到以及成功弹出了我们劫持的代码。
首先对该类型的攻击有以下几个比较好的方法去防御。
1.可以检查网络连接异常的进程:首先我们可以将正常的网络通信进程链进行记录,当发现该进程的网络活动与记录的进程链不符时,则可能受到了DLL劫持攻击。
2.在加载DLL时,先将文件读入内存中验证其数字签名或是哈希值,发现不匹配则不加载该DLL。
这些检测方法难以大规模实施,但在理论上可以利用。而这也正是这种旧技术时至今日仍然有效,并且还在被红方团队和恶意组织利用的原因。之所以这些漏洞持续存在,实质上是与软件发行商有关。软件发布者需要了解DLL劫持技术,并掌握如何在开发的产品中规避此类漏洞风险则可以减少攻击者绕过现代化检测技术的DLL滥用行为的可能性。
另外将威胁情报与网络攻防研究相互结合,在真实的网络环境中捕获攻击者的恶意攻击样本并进行分析找出其中使用的对抗方法并使用攻击者真实利用的攻击方式开展红蓝对抗,并且可以通过跟踪真实攻击者的技术方向为红蓝对抗提供指路的明灯,从蓝队的角度来看,我们可以更好的知道那些恶意的技术会被攻击者大范围应用于真实的网络攻击,以更好的去防御该类型的攻击。
*本文作者:木星安全实验室,转载请注明来自FreeBuf.COM