用户工具

站点工具


习科旧站:dll劫持

作者:rival@riseup.net | 译者:习科论坛 - Exploit

Abstract 简要

本文的目的是为了简要的讨论一下DLL劫持漏洞和修复技术。本文主要面向对动态链接库有一定了解并且知道怎么应用的读者,当然对其并无太多了解的读者,本文也包含了一定的必要的基础知识。

Introduction 导论

统计表明,Windows是如今应用最为广泛的操作系统,尤其是windows 7,更是拥有55%的使用者。然而的使用者多却并不表示着他安全。DLL劫持,有时也被称作DLL的预先载入(pre-loading),由H.D.Moore在2010年提出。
虽然人们普遍认为DLL劫持是一个很重要的话题,可是却没有太多的描述关于防御方法和它的效果的文档。DLL劫持漏洞影响了许许多多的商业应用,所以他对于渗透测试者和安全研究者来说,是一个不可忽略的重要研究方向。

举例来说,在Windows Movie Maker和Windows Address Book软件中就曾经有过DLL劫持漏洞。为了能够更好地了解DLL劫持,首先你必须知道如果在没有完整的路径的情况下,windows下的程序们是如何寻找到他们所需要的DLL文件的。

Windows DLL

动态链接库是一些可执行的代码和数据的一个集合,常被其他的DLL文件或是应用所调用。那为何要使用DLL文件而不是直接讲数据、函数之类的信息直接写入到exe文件本身中去呢?主要有两个原因。一者是因为可以使得exe程序本身被简化,并且更容易被更新。当需要更新的时候,不需要再要求用户重新下载整个exe文件而是只需要更新几个关键的小的DLL文件。可以遇见的到这对于游戏或是其他需要常常更新的软件来说,是多么曼妙的发明。其二,是通过允许不同的应用程序之间共享DLL的代码,可以减少不必要的内存使用。

Windows DLL Search Order 动态链接库查找顺序

普遍来说,程序猿不会将一个写死他们需要用的DLL文件的绝对路径。这个会经常导致DLL文件不能被找到或不能被使用。然而机智的微软退出了DLL Search Order这样的一个服务,他会在应用程序的载入时间(load time)运行,来解决这个问题。
一般来说,会优先使用第一个被找到的项目。查找的顺序如下:
Directory of the Application 应用程序的目录 → Current Directory 当前目录 → System Directory 系统目录 → 16-bit System Directory 16位系统目录 → Windows Directory Windows目录 → Directories in PATH variable 环境变量中的目录

上面就是windows动态链接库搜索的顺序。当然基于你的操作系统的设置不同上面的顺序也会略有改变。比如SetDllDirectory中的IpPathName就可以被用在最优先的位置,取代应用程序目录。

又比如SafeDllSearchMode被启用,整个的搜索程序也会被改变,当前目录这个的优先级就会被调至第五位。

Principe of DLL Hijacking 攻击原理

现在我们已经明白了windows怎么搜索DLL文件,我们可以开始了解劫持的过程了。我们不妨模拟一个真实情景举例来说,比如我们的应用软件需要function.dll文件,而在应用程序的代码中并没有明确的给出他的绝对路径,而正确的文件应该位于系统目录。于是机智的攻击者就可以把恶意的DLL文件放在优先级比System Directory高的文件夹里(例如应用程序的目录)。
当用户打开应用程序的时候,会发现程序运行了攻击者的DLL文件,这就意味着一切的恶意代码都将被运行。

Finding DLL Hijacking Vulnerabilities 寻找漏洞

在应用程序中找到漏洞永远是利用漏洞的第一步。有一个比较好的办法就是可以使用Process Monitor软件来研究程序运行的时候在查找那些DLL文件。
当Process Monitor运行起来的时候,你可以选择通过其他的DLL文件来触发一个函数或是等到一个函数触发。

在此之后,我们需要做的就是去Filter目录并加上我们的filter(过滤)。如下便是一些可以使得搜索过程更短的filter:

. Operation is QueryOpen then Include操作是QueryOpen然后包含
. Process Name is vuln.exe then Include进程名是vuln.exe然后包含
. Path contains .dll then Include路径包含.dll然后包含

如果你的确找到了,那么应该看起来如下:

PathResult
C:\Windows\System32\vuln.dllNAME NOTFOUND
C:\Windows\System\vuln.dllNAME NOTFOUND
C:\Windows\vuln.dllNAME NOTFOUND

然后,这很有可能就是一个可劫持的漏洞了。

Finding function names from a DLL 从DLL中查找函数名

我们首先要知道在DLL中被使用的函数名,我们才能创建一个新的恶意DLL文件。在windows下,我们可以使用DUMPBIN来完成这项任务。我们可以利用它的/EXPORTS(导出)选项。如下是一个样例DLL文件的样例输出:

Dump of file C:\example.dllFile Type: DLL
Section contains the following exports for example00000000 characteristics
4FC31DEF time date stamp Mon Jun 05 18:32:49 2013

当然还有另一种选择,就是使用一个debugger。我们可以通过debugger看到明文存储的DLL调用信息。

Writing DLL Exploits 编写利用程序

我们已经在理论上了解的足够多,如今是时候进入实用的部分了。让我们假设一下,如果我们的程序是通过如下这样的语句来调用动态链接库的话:

DLL_FILE=LoadLibrary(“test.dll”);

如下的代码用于执行“output_text”函数:

output_text = (DLLPROC)
GetProcAddress(DLL_FILE,”output_text”);

而DLL中的部分代码如下:

void output_text()
{
cout << “All is going well ! \n”;
return ;
}

在这个样例下,我们将假设test.dll文件位于windows目录。当我们没有具体的路径的时候,搜索算法就开始发挥作用了。程序找到windows目录下的DLL文件并输出:All is Going well
我们可以创建一个新的dll文件有着相同的函数名,如下:

void output_text() {
cout << "All is Going well!\n";
return; }

如果我们将我们的新文件放在和目标程序相同的目录下。那么在运行程序的时候,算法会优先找到在相同目录下的我们的恶意文件而不是windows目录中的正确文件。你可以想象到这该会是多大的冲击和影响。对于受害者来说,他们不会太多的关注DLL文件,也没有理由去害怕、提防一个他们所想要的正确的程序所调用的DLL。可是这却恰恰使得攻击者的恶意代码被运行。

Attack a victim remotely 远程攻击

许许多多的人对DLL劫持的替换感到困惑。很多人会替换程序本身的文件来防御。然而对于劫持本身来说,这是并不必要的。因为对于劫持攻击而言,只是需要在攻击者的DLL文件目录下运行程序即可。而很好理解,就是当执行攻击的时候,必须要在用户的电脑上有你的DLL文件。而这似乎不太容易。然而这时候,有一种叫社会工程学的大杀器就可以派上用场。如下失恋个例子:

  1. 攻击者在一个text file viewer(文本浏览器)中发现漏洞。他创建了一个文件夹,其中有恶意的DLL和一个正常的文本文件。当被攻击者下载了文件夹并打开文本文件的时候,文件和DLL会被解压到同一个位置。此时如果通过那个有漏洞的文本浏览器打开文本文件,程序将会优先搜索被打开的文本文件所在的文件夹,也就是恶意的DLL所在文件夹。于是恶意的DLL被优先找到并执行。
  2. 攻击者找到公司的邮件浏览器的漏洞。他上传一个恶意的DLL,一些任意的文件和一个邮件到公司的共享目录(可以利用公司内部人的账号)。当被攻击者下载这些文件并打开email的时候,恶意的DLL文件就会替代正确的DLL,被执行。

Defending against DLL Hijacking 防御

解释一个漏洞的最重要的部分就是解释怎么去防御他。保护用户们的安全,这个沉重的担子终究还是要落在开发者们的肩上。因为windows的搜索顺序吸引了很多注意力,于是开发者们应该学习怎么样更少的依赖操作系统本身的技术辅助。在这个情况下,应当写入一个完整的路径来防御这整个问题。
另一个方案,就是把DLL文件放在最为优先被调用的地方,当然我本人不建议这样的方式。当然还有一个方法,就是加上校验。当DLL文件被找到,对他进行hash的校验,如果符合则执行,如果被更改,则不执行。使用一个强的hash娇艳的算法,或是加上salt或是公钥或密钥来加密和解密可以大大提升安全性。当然用户也可以通过注意一些注意事项来保护他们自己。他们应该注意一下,自己所打开的文件不和一些看似可疑的DLL文件在同一目录。

举例来说,如果一个DLL文件和你刚下载的图片在同一文件,那么在打开图片前删除DLL文件会是一个机智的决定。用户同样可以改变注册表的CWDIllegalInDllSearch。 用户可以设置如下两个键:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CWDIllegalInDllSearch
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\binaryname.exe\CWDIllegalInDllSearch

希望本文能够在一定程度上帮助你了解Windows系统下的DLL劫持。



你需要登录发表评论。
习科旧站/dll劫持.txt · 最后更改: 2020/05/16 19:19 (外部编辑)

页面工具