3.3 DLL注入:突破会话0强力注入
Session是Windows
系统的一个安全特性,该特性引入了针对用户体验提高的安全机制,即拆分Session 0和用户会话,这种拆分Session 0
和Session 1
的机制对于提高安全性非常有用,这是因为将桌面服务进程,驱动程序以及其他系统级服务取消了与用户会话的关联,从而限制了攻击者可用的攻击面。
由于DLL
注入在Session 0
中的注入机制不同于在用户会话中的注入机制,因此需要特别的考虑和处理。如果需要执行DLL注入,必须使用过度级别安全
机制解决Session 0
上下文问题,并且在设计安全方案时,必须考虑Session 0
和Session 1
之间的区别。
在之前的远程线程注入章节中,我们通过使用CreateRemoteThread()
这个函数来完成线程注入,此方式可以注入普通的进程,但却无法注入到系统进程中,因为系统进程是处在SESSION0
高权限级别的会话层,由于CreateRemoteThread()
底层会调用ZwCreateThreadEx()
这个未公开的内核函数,所以当我们调用该函数的底层函数时则可实现突破Session0的注入机制。
由于该内核函数并未被导出,所以我们必须找到该函数的原型定义,并通过GetProcAddress
获取到ntdll.dll
模块下的ZwCreateThreadEx
的函数地址,并通过ZwCreateThreadEx
函数指针直接调用模块;
|
当拿到ZwCreateThreadEx
函数指针时,则接下来就可以调用了,ZwCreateThreadEx 可以用于创建一个远程线程,即在目标进程中创建一个线程,并在这个线程中运行指定的代码。与CreateRemoteThread
不同,ZwCreateThreadEx
可以用于创建一个在指定进程的上下文之外的线程,即可以创建一个与指定进程无关的线程。
它的函数原型定义如下:
NTSYSAPI NTSTATUS NTAPI ZwCreateThreadEx( |
其参数说明如下:
- ThreadHandle 用于返回创建的线程句柄的指针。
- DesiredAccess 用于指定线程句柄的访问权限。
- ObjectAttributes 一个指向 OBJECT_ATTRIBUTES 结构的指针,指定线程对象的对象名和安全性属性。
- ProcessHandle 目标进程的句柄,即在哪个进程中创建新线程。
- StartRoutine 一个指向新线程的入口点的指针。
- Argument 第二个参数传递给新线程的指针。
- CreateFlags 指定创建线程的属性,如堆栈大小、创建标志、线程属性等。
- ZeroBits 保留参数,应该传递0。
- StackSize 线程堆栈大小。
- MaximumStackSize 线程堆栈的最大大小。
- AttributeList 指向结构 PS_ATTRIBUTE_LIST,该结构可以用于在线程创建时指定各种属性。
具备了上述基本条件那么注入代码的事项将变得非常容易,如下代码是这个注入程序的完整实现流程,读者可自行测试注入效果;
|