En

DLL劫持漏洞解析

作者:Gmxp & riusksk[TSRC]公布时间:2013-06-24阅读次数:18746评论:2

分享

黑客手中的全新武器


    艾瑞2012年初发布的中国2011年下半年个人网络安全报告中,包含这么一个数据:2011年下半年十大热点木马中,其中5个是利用DLL劫持漏洞来对系统进行破坏的。DLL劫持漏洞到底是何方神圣,竟然占领了木马技术的半壁江山?



                                          图1 艾瑞安全报告中利用DLL劫持技术的热门木马截图


    DLL(Dynamic Link Library),全称动态链接库,是Windows系统上程序正常运行必不可少的功能模块,是实现代码重用的具体形式。简单的说,可以把DLL理解成帮助程序完成各种功能的组件。


    DLL劫持漏洞(DLL Hijacking Exploit),这个名字缘起微软在2010年8月23日发布的2269637号安全公告。通俗点说,这个漏洞就像是去年炒的沸沸扬扬的深圳526车祸中总会提到的“掉包”;严格点说,它是通过一些手段来劫持或者替换正常的DLL,欺骗正常程序加载预先准备好的恶意DLL的一类漏洞的统称。利用DLL劫持漏洞,病毒木马可以随着文档的打开(或者其他一些程序正常行为)而激活自身,进而获得系统的控制权。


    我们来看看DLL劫持漏洞到底是何方神圣。

 

 

高危害利用形式的爆发


    DLL劫持漏洞伴随着Windows而存在,但是一直并未得到大家的足够重视。


    直到2010年8月份,有黑客在安全论坛上公布了一种危害极高的DLL劫持漏洞的利用形式,迅速引起强烈的反应。随后,著名安全组织exploit-db公布了一系列存在DLL劫持漏洞的软件列表,其中可以发现大家十分熟悉的应用软件,包括:AutoCAD 2007、Daemon Tools、Winamp、Media Player Classic、Mozilla Thunderbird、Microsoft Office、Adobe Photoshop、Adobe Dreamweaver CS5、Skype、Snagit10、Safari、WinDVD、Opera、Firefox等等。



                                                         图2 PCHOME针对DLL劫持漏洞的新闻截图


    简单的讲,安装了上述软件的电脑,当用户在打开一个图片、音乐、视频、BT种子、网页文件都有可能感染病毒。当攻击者利用DLL劫持漏洞构造一个特殊的DLL文件,将这个DLL文件和一些JPG、PPT、MP3、MPG、HTML文件共同打包,用户解压后双击打开这些文档,病毒即被立即触发。也就是说,不需要其他漏洞,不需要可执行文件,只需要鼠标双击打开别人发给你的音乐、视频或者图片文件,就可能感染病毒!难怪国外安全公司authentium在官方博客中描述DLL劫持漏洞时,甚至用"The world is going to end!"做标题。


    不过此次风波,随着网民们的关注和各个产品漏洞的逐步修复,逐渐平息下去。

 

演变和进化


    DLL劫持漏洞的生命力绝不仅限于打开文件这种触发这种形式。通过这种形式的启发,黑客们逐渐找到了DLL劫持漏洞的更大活力。二年之后的今天,当我们再看这个漏洞时,它已摇身一变更具威胁了。


    了解客户端安全的同学应该都知道,现在的安全软件大都会采取白名单机制,把一些大公司的程序放在安全软件的白名单中,白名单中的程序不会进行监控并默认信任,以减少误报率。


    都说安全性和易用性是相悖的。白名单这个特性是使安全软件和受信任程序的使用都方便了不少,但是,同时也更加方便了广大黑客。我们都知道,软件工作时都需要这样那样的DLL功能组件,那么在安全软件白名单信任策略支持下,即使“安全软件”要加载的DLL是被替换掉的恶意DLL,安全软件都会被认为是合法、正常的行为。因此,黑客们就开始利用各大公司软件中存在的DLL劫持漏洞,堂而皇之的在安全软件眼皮底下加载早已准备好的恶意代码,入侵用户的计算机。至此,更具“劫持”特性的广义DLL劫持漏洞正式诞生。


    本文开头艾瑞报告中提到的那5个DLL劫持木马,都属于这种漏洞形式。是的,你没有听错,就是它,占领木马激活技术的半壁江山。由于效果极好,是黑客们杀人放火,打家劫舍的必备大杀伤性武器。

 

刨根到底看原理


    DLL劫持漏洞之所以被称为漏洞,还要从负责加载DLL的系统API LoadLibrary来看。熟悉Windows代码的同学都知道,调用LoadLibrary时可以使用DLL的相对路径。这时,系统会按照特定的顺序搜索一些目录,以确定DLL的完整路径。根据MSDN文档的约定,在使用相对路径调用LoadLibrary(同样适用于其他同类DLL LoadLibraryEx,ShellExecuteEx等)时,系统会依次从以下6个位置去查找所需要的DLL文件(会根据SafeDllSearchMode配置而稍有不同)。


1. 程序所在目录;
2. 系统目录;
3. 16位系统目录;
4. Windows目录;
5. 当前目录;
6. PATH环境变量中的各个目录。


    而所谓的劫持的,就发生在系统按照顺序搜索这些特定目录时。只要黑客能够将恶意的DLL放在优先于正常DLL所在的目录,就能够欺骗系统优先加载恶意DLL,来实现“劫持”。

 

微软的“设计缺陷”?


 

    从上面的原理来看,LoadLibrary API并不会去检查即将要加载进来的DLL是好人还是坏人,不管是李逵还是李鬼都有酒喝、有肉吃。这点我们能理解,毕竟判断DLL是好是坏不是系统的事情,而是安全软件的事情。


    同时,当使用相对路径调用这个API加载DLL时,就会触发上一节所述的神奇的动态链接库搜索逻辑。由于系统搜索的位置非常多,而且其中的许多位置都能轻易被黑客劫持和控制,给了DLL劫持漏洞很大的利用空间。


    但是,微软认为以上这些属于系统特性,不属于安全漏洞而不做修改,微软官方的介绍及安全建议请参考这里:Dynamic-Link Library Search OrderDynamic-Link Library Security


    比较有意思的是,从Windows 7的KB2533623补丁开始,微软给我们带来了三个解决DLL劫持问题的新API:SetDefaultDllDirectories,AddDllDirectory,RemoveDllDirectory。这几个API配合使用,可以有效的规避DLL劫持问题。可惜的是,这些API只能在打了KB2533623补丁的Windows7,2008上使用。

 

Satellite DLL Hijacking


    微软从VS2003/MFC7.0开始就提供对Satellite DLL的增强支持,主要用于创建针对多种语言进行本地化的应用程序。Satellite DLL属于纯资源DLL,它包含应用程序针对特定语言进行本地化的资源。当应用程序开始执行时,MFC会自动加载最适合于当前运行环境的本地化资源,比如在中文系统上,应用程序会优先使用中文资源,若是英文系统,则使用英文资源。Satellite DLL的命名规范为ApplicationNameXXX.dll,其中ApplicationName是使用MFC的*.EXE或者*.DLL的名称,而XXX为由资源语言的三个字母组成,比如中文为CHS,英文为ENU。由于经MFC编译的应用程序会自动加载相应语言的本地化资源(即Satellite DLL),且对加载的资源文件的合法性未作有效检测,因此可能被恶意程序利用DLL劫持来实现任意代码执行。


    MFC主要按照以下顺序加载每种语言的资源DLL,找到一个后将停止加载下面的其它DLL:

 

1. 当前用户的默认界面语言(UI Language)(适用于 Windows 2000 或更高版本),该语言从 GetUserDefaultUILanguage() Win32 API 返回;
2. 当前用户的默认界面语言(适用于Windows 2000 或更高版本),没有任何特定子语言(即 ENC [加拿大英语] 变成 ENU [美国英语]);
3.系统的默认界面语言(适用于Windows 2000 或更高版本),这是从 GetSystemDefaultUILanguage() API 返回的语言。 在其他平台上,这是操作系统本身的语言;
4. 系统的默认界面语言,没有任何特定的子语言;
5. 具有 3 个字母代码 LOC 的“虚设”语言。

 

    比如使用MFC的应用程序Example.exe,系统的用户界面语言是ENU(美国英语),而当前用户的用户界面语言为FRC(加拿大法语),那么MFC将按照以下顺序查找资源DLL文件:

 

1.   ExampleFRC.dll(当前用户的界面语言,此例为加拿大法语);
2.   ExampleFRA.dll(当前用户的界面语言,不包含子语言,此例为法语(法国));
3.   ExampleENU.dll(系统默认的用户界面语言,此例为美国英语);
4.   ExampleLOC.dll。

 

    如果未找到上面DLL中任何一个,则MFC会使用Example.exe自带的资源。当应用程序自带有界面语言资源DLL文件时,它也会按照上述顺序来加载。比如在Win7简体中文系统上,应用程序Example.exe拥有自己的UI资源文件MainUI.dll,那么就会首先去加载MainUICHS.dll。


    因此,恶意程序如果在程序相当目录下,比如上面MainUI.dll所在目录下,再放置一个包含恶意代码的MainUICHS.dll后,打开主程序Example.exe后,就会优先加载包含恶意代码的MainUICHS.dll,而非MainUI.dll,从而执行任意代码,如下图所示:


    由于多数MFC程序默认会动态链接mfc70.dll、mfc80.dll、mfc90.dll等dll文件(具体文件名与MFC版本号相关),因此在中文系统下,如果在相应的程序目录下放置mfc**chs.dll或者mfc**loc.dll都有可能达到DLL劫持的目的。

 

DLL加载安全之道


    首先,对于会打开图片、音乐等各种类型文件的程序,分为以下三种情况处理:


A. 对于外部第三方DLL和自己的DLL:


     1. 使用LoadLibrary API加载DLL时使用绝对路径,类似的情况还包括其他API如LoadLibraryEx, CreateProcess, ShellExecute等;
     2. 将所有需要使用到的DLL放在应用程序所在的目录,不放到系统目录或者其他目录

 

B. 对于系统共享的DLL(如user32.dll, mfc80loc.dll等),不能放到程序目录下时,应该:


     1. 使用绝对路径加载;
     2. 对于无法准确预测绝对路径的情况,可以使用相对路径加载。

 

C. 程序启动时调用API SetDllDirectory(L"")将当前目录从DLL加载顺序中移除.

 

    其次,对于广义DLL劫持漏洞,我们只有一种有效的处理办法:加载任何DLL前先校验文件的签名,签名没有问题的才能加载。

 

检测方案


    DLL劫持漏洞的检测比较简单,可以在虚拟环境将程序运行起来,对其中的DLL加载操作进行审计,找出加载顺序中可能被劫持的点;还可以为程序构建一个“劫持现场”(自己做一个劫持并转发给正常DLL的DLL文件看是否执行其中代码),并检查程序能否真正规避DLL劫持的威胁。

 

关于TSRC平台对DLL劫持的评分说明


    之前有若干白帽子提交“DLL劫持”漏洞被忽略,可能缺乏有效的沟通,导致一些不必要的误解,TSRC对此作下评分说明。对于微软的Satellite DLL Hijacking问题,以及替换正常dll文件来达到“劫持”的问题,若提交到TSRC平台均忽略不给分。大家对此若有意见或建议,也可通过TSRC平台(http://security.tencent.com)向我们反馈。

 

评论留言

提交评论 您输入的漏洞名称有误,请重新输入