1.本文原文为K A, Monnappa. 2018年发表的《Learning Malware Analysis》,本文的相关内容均为笔者对相关内容的翻译及实践记录,仅供各位学术交流使用。另出于易读性考虑,对部分字句有所删改。
[序号]K A, Monnappa. LearningMalware Analysis[M]. 2018.06. Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
3.因文章整体内容较长,完整内容将会在本公众号拆分为多篇内容分别发出。本文为该系列的第四篇。
先前讲到的技术中,在写入DLL路径名后,CreateRemoteThread()被调用,以在目标进程中创建一个线程,而这个线程又调用LoadLibrary()来加载恶意的DLL。
APC注入技术类似于远程DLL注入,但恶意软件不是使用CreateRemoteThread(),而是利用异步过程调用(APC)来强迫目标进程的线程加载恶意DLL。
APC是一个在特定线程的上下文中异步执行的函数。每个线程都包含一个APC队列,当目标线程进入可警告状态时,APC将被执行。
根据微软的文档,如果一个线程调用了以下函数之一,它就进入了可预警状态:
SleepEx(),
SignalObjectAndWait()
MsgWaitForMultipleObjectsEx()
WaitForMultipleObjectsEx()
WaitForSingleObjectEx()
APC注入技术的工作方式是:恶意软件进程确定目标进程(将注入代码的进程)中的线程,该线程处于可警告状态,或可能进入可警告状态。然后通过使用QueueUserAPC()函数将自定义代码放入该线程的APC队列。排列自定义代码的想法是,当线程进入可警告状态时,自定义代码会从APC队列中被选中,并由目标进程的线程执行。
1.它使用OpenThread()API为目标进程的线程打开一个句柄。在下面的截图中,第3个参数,0xBEC(3052),是iexplore.exe进程的线程ID(TID)。OpenThread()的返回值是iexplore.exe的线程句柄。
2. 然后,恶意软件进程调用QueueUserAPC(),在Internet Explorer线程的APC队列中编排指定的APC函数。
在下面的截图中,QueueUserAPC()的第一个参数是指向恶意软件希望目标线程执行的APC函数的指针。
在这种情况下,APC函数是LoadLibrary(),其地址先前已经确定。第二个参数,0x22c,是iexplore.exe目标线程的句柄。第3个参数,0x2270000,是目标进程(iexplore.exe)内存中的地址,包含恶意DLL的完整路径;当线程执行时,这个参数将自动作为参数传递给APC函数(LoadLibrary())。
下面的截图显示了Internet Explorer进程内存中的地址0x2270000的内容(这是作为第3个参数传递给QueueUserAPC()的)这个地址包含了之前被恶意软件写入的DLL的完整路径。
此时,注入已经完成,当目标进程的线程进入可预警状态时,该线程从APC队列中执行LoadLibrary(),DLL的完整路径被作为参数传递给LoadLibrary()。结果,恶意的DLL被加载到目标进程的地址空间,而目标进程又调用了包含恶意代码的DLLMain()函数。
3.3 使用SetWindowsHookEx()进行DLL注入
要做到这一点,恶意软件首先将恶意DLL加载到自己的地址空间。然后,它为一个特定的事件(如键盘或鼠标事件)安装一个钩子程序(由恶意DLL导出的函数),并将该事件与目标进程的线程(或当前桌面中的所有线程)联系起来。
这个思路是,当一个特定的事件被触发时,为其安装的钩子,目标进程的线程将调用该钩子程序。为了调用DLL中定义的钩子程序,它必须将DLL(包含钩子程序)加载到目标进程的地址空间。
换句话说,攻击者创建了一个包含导出函数的DLL,包含恶意代码的导出函数被设置为特定事件的钩子程序。该钩子程序与目标进程的一个线程相关联,当事件被触发时,攻击者的DLL被加载到目标进程的地址空间,钩子程序被目标进程的线程调用,从而执行恶意代码。
恶意软件可以为任何类型的事件设置钩子,只要该事件有可能发生。这里的重点是,DLL被加载到目标进程的地址空间,并执行恶意的行为。
下面描述了恶意软件样本(Trojan Padador)执行的步骤,将其DLL加载到远程进程的地址空间,并执行恶意代码。
恶意软件的可执行程序在磁盘上投放了一个名为tckdll.dll的DLL。该DLL包含一个导入函数,和一个名为TRAINER的导出函数,如下所示。DLL的导入函数并没有做什么,而TRAINER函数包含恶意代码。这意味着,DLL只被加载时(其导入函数被调用),不会执行恶意代码;只有当TRAINER函数被调用时,才会执行恶意行为。
恶意软件使用LoadLibrary()API将DLL(tckdll.dll)加载到自己的地址空间。使用LoadLibrary()API将DLL(tckdll.dll)加载到自己的地址空间,但在这一点上没有恶意代码被执行。
LoadLibrary()的返回值是加载模块(tckdll.dll)的句柄。模块(tckdll.dll)的句柄。然后它通过使用GetProcAddress()确定TRAINER函数的地址。
恶意软件使用tckdll.dll的句柄和TRAINER函数的地址为键盘事件注册一个钩子程序。TRAINER函数的地址来为键盘事件注册一个钩子过程。
在下面的截图中,第1个参数WH_KEYBOARD(常量值2)指定了将调用钩子程序的事件类型。第2个参数是钩子程序的地址,也就是上一步确定的TRAINER函数的地址。第3个参数是指向tckdll.dll的句柄,它包含钩子程序。第四个参数,0,指定钩子程序必须与当前桌面上的所有线程相关联。恶意软件可以不把钩子程序与所有的桌面线程联系起来,而是通过提供线程ID来锁定一个特定的线程。
在执行了前面的步骤后,当键盘事件在一个应用程序中被触发时,该应用程序将加载恶意的DLL并调用TRAINER函数。例如,当你启动记事本并输入一些字符(触发了键盘事件)时,tckdll.dll将被加载到记事本的地址空间,TRAINER函数将被调用,迫使notepad.exe进程执行恶意代码。
安恒信息安全服务团队由九维安全能力专家构成,其职责分别为:红队持续突破、橙队擅于赋能、黄队致力建设、绿队跟踪改进、青队快速处置、蓝队实时防御,紫队不断优化、暗队专注情报和研究、白队运营管理,以体系化的安全人才及技术为客户赋能。
![九维团队-青队(处置)| 代码注入和钩子(四) 九维团队-青队(处置)| 代码注入和钩子(四)]()
原文始发于微信公众号(安恒信息安全服务):九维团队-青队(处置)| 代码注入和钩子(四)
评论