JavaScript后门深层分析

最近,hFireF0X在逆向工程论坛kernelmode.info上发表了对Win32/Poweeliks恶意软件详细调查的文章。这个恶意软件的特别之处就是它存在于window注册表中并且使用rundll32.exe来执行JavaScript代码。

当我们第一次发现命令行执行JavaScript,我们很好奇它是如何工作的。

在接下来的文章中,我们会分析JavaScript代码时如何执以及为什么会在调用这样简单的命令行代码时执行:

rundll32.exe javascript:”\\..\\mshtml,RunHTMLApplication “;alert(‘foo’);

Rundll32介绍

关于rundll32.dll的使用在MSDN上有专门的文档;它往往被用来调用一个DLL文件的输出函数,可以通过以下的命令来实现:

RUNDLL32.EXE ,

entrypoint就是输出函数;它的函数原型应该是如下所示:

void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);

参数lpszCmdLine是由rundll32.exe命令语句中的值确定的。

我们会尝试指出rundll32.exe是如何能够调用被mshtml.dll输出的函数RunHTMLApplication,以及“Javascript”前缀是如何被用来执行实际的JavaScript代码的。

Rundll32.exe分析

a.参数

rundll32.exe做的第一件事就是使用内置的ParseCommand命令来对命令进行解析。这个函数会查找一个逗号(‘,’,0x2c)来定位dll的名称和一个空格(‘ ’,0x20)来定位入口点名称

当使用我们的样本命令时,ParseCommand会返回javascript:”\\..\\mshtml作为DLL名称,返回RunHTMLApplication作为入口点。

Dll loader

rundll32.exe会尝试几种方法来从最初的“JavaScript:”\\..\\mshtml”加载实际的DLL。

第一次测试使用了函数GetFileAttributes(“javascript:”\\..\\mshtml”)。这个函数最终会接近C:\\Windows\\system32\\mshtml。如果这个文件没有被发现,那么这个函数就会返回-1。

接下来SearchPath会被调用来确定DLL的名称。这个函数会读取注册表键值HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SafeProcessSearchMode。微软对于这个键值的定义是:

当这个REG_DWORD类型的注册表键值被设为1,SearchPath会首先搜索系统路径中指定的文件夹,然后会搜索当前工作的文件夹。当这个注册表键值被设为0时,电脑首先会搜索当前工作的文件夹,然后再去搜索系统路径中指定的文件夹。系统对于这个注册表键的默认值是0。

在默认情况下,这个注册表键值是不存在的(在win xp、7、8下),所以SearchPath会优先尝试在rundll32.dll的当前目录中加载文件mshtml,其次才会尝试在系统路径中进行定位。

如果所有的尝试都失败了,那么rundll32.exe就会进行下一步。GetFileAttribute将再次被调用来给模块查找manifest文件:javascript:”\\..\\mshtml.manifest。

若所有的之前的步骤都失败了,rundll32.exe最终会调用Loadlibrary(“javascript:”\\..\\mshtml”)。

LoadLibrary只是位于ntdll.dll中的一个对LdrLoadDLL的简单封装。在内部,LdrLoadDll会添加默认的扩展dll并且把结果字串(javascript:”\\..\\mshtml.dll)作为路径来解析。“..”代表再向上一层文件夹:它就解析成了mshtml.dll。

当mshtml.dll已经被确定了,LdrLoadDll就可以加载系统目录中的lib库了。

rundll32.exe接下来会使用之前提取的入口点名称RunHTMLApplication调用GetProcAddress。

这个时候我们可以发现,javascript:前缀看起来毫无用处:LoadLibrary(“foobar:\\”\\..\\mshtml”)工作的很好。所以,为什么要加这么一个前缀呢?

协议处理

一旦入口地址已经被解析出来,rundll32.dll会调用函数mshtml.dll!RunHTMLApplication。

即使没有被记录,实际的RunHTMLApplication也能从c:\\windows\\system32\\mshta.exe的调用中推断出来(这个应用专门来启动一个.hta文件)。

HRESULT RunHTMLApplication(

HINSTANCE hinst,

HINSTANCE hPrevInst,

LPSTR szCmdLine,

int nCmdShow

);

这和期望的rundll32.exe的入口点地址很相似:

void CALLBACK EntryPoint(

HWND hwnd,

HINSTANCE hinst,

LPSTR lpszCmdLine,

int nCmdShow

);

RunHTMLApplication接受一个窗口的句柄而不是一个模块的句柄作为第一个参数。这个参数会在mshml登记一个窗口类或者为一个类创建窗口时被使用。传递一个同实际的实例并不相一致的值并不会给user32带来很大影响。

第二个参数完全没有被使用,所以这个不匹配并不重要。

最后一个参数,nCmdShow,被RunHTMLApplication函数用来展示代管这个HTML应用的主机窗口。rundll32经常使用值SW_SHOWDEFAULT来调用入口点函数来指示任何可能打开的窗口使用窗口默认配置。

在我们的例子中,可能更让人感兴趣的参数是 lpszCmdLine (“;alert(‘foo’))。

这显然会导致问题,因为这并不是一个有效的JavaScript语句(注意在语句末尾丢掉的双引号)。但是它仍然有效,因为RunHTMLApplication忽略给定的参数,并且更倾向于从windows API GetCommandLine中重新请求原始的命令(封装在GetCmdKLine函数的一个调用中)。

完整的命令包含了可执行文件和参数的名称:GetCmdLine通过整理可执行规范来提取参数。

在这之后,RunHTMLApplication会调用CreateURLMonitor:

这也是需要字符串“javascript”的地方。

CreateURLMonitor解析命令行来提取char”:”(0x3A)之前的字符串:“javascript”。

CreateUrlMoniker会爬取注册表键值HKCR\\SOFTWARE\\Classes\\PROTOCOLS\\Handler\\。这些键值和一个协议集以及它们的CLSID有关。

CreateUrlMoniker会发现一个合适的协议处理器来对Javascript的协议进行处理(HKCR\\SOFTWARE\\Classes\\PROTOCOLS\\Handler\\javascript):

CLSID{3050F3B2-98B5-11CF-BB82-00AA00BDCE0B}符合微软“Microsoft HTML Javascript Pluggable Protocol”规范。

这也是为什么字符串“javascript”必须在参数的开始部分的原因。

相同的机制在人们在IE的导航栏输入javascript:alert(‘alert’)时也会起作用。

位于“:”分隔符之后的字符串会被JavaScript URL moniker解释成JavaScript指令:

“\\..\\mshtml,RunHTMLApplication “;alert(‘foo’);

这是一个带有字符串”\\..\\mshtml,RunHTMLApplication “和函数(alert)的无效JavaScript语句(因为双引号会跳过所有之前的步骤!)。

最终RunHTMLApplication会调用CHTMLApp::Run,这条JavaScript语句也会被执行:

安全影响

从安全的角度来看,通过rundll32来执行JavaScript就像执行一个HTML应用。

换句话说,我们可以使用IE的全部权利。当区域安全被关闭,允许跨域脚本访问,我们就可以拥有读写客户端机器文件和注册表的权力。

通过这个技巧,JavaScript可以在IE外部被执行,并且脚本没有任何安全概念的约束,比如保护模式\\沙盒。

本文相关

http://www.kernelmode.info/forum/viewtopic.php?f=16&t=3377

http://support.microsoft.com/kb/164787/en

http://msdn.microsoft.com/enus/library/windows/desktop/aa365527%28v=vs.85%29.aspx

https://thisiscybersec.files.wordpress.com/2014/08/capture-d_c3a9cran-2014-08-20-c3a0-16-16-36.png

https://thisiscybersec.files.wordpress.com/2014/08/capture-d_c3a9cran-2014-08-20-c3a0-16-16-36.png

发表评论

邮箱地址不会被公开。 必填项已用*标注