session0注入
前言
当我们使用远程线程注入将dll注入至系统服务进程中往往会失败,这是因为大多数系统服务都是在Session0中运行的
"Session 0"是Windows操作系统中的一个特殊的会话,专门用于运行系统服务和其他在用户登录之前就需要运行的程序。从Windows Vista和Windows Server 2008开始,为了提高安全性,Windows将用户和系统服务分隔在不同的会话中。具体来说,所有的服务和系统任务都在Session 0中运行,而所有用户交互任务都在其他会话中运行
"Session 0注入"一般指的是把一个程序(通常是一个恶意程序)注入到Session 0的过程。因为Session 0有许多特权,所以如果恶意程序能够成功注入到Session 0,就可以获得比正常用户更高的权限,从而进行更多的恶意操作
然而,由于Windows Vista和后续版本的Windows的安全性提高,使得Session 0注入变得更加困难。尤其是,Session 0是隔离的,不能直接与用户的图形会话进行交互

远程线程注入函数调用流程
1.CreateRemoteThreadStub
CreateRemoteThreadStub是在kernel32.dll中,用于对CreateRemoteThread函数的封装,对CreateRemoteThread的参数进行处理,由原来的7个参数扩展到8个参数,并对dwCreationFlags参数进行安全处理

2.CreateRemoteThread
CreateRemoteThread函数位于KernelBase.dll中,最终调用了NtCreateThreadEx函数

3.NtCreateThread
NtCreateThread是内核级别的函数,它是属于NTDLL库中的一部分。NTDLL库中的函数主要是由操作系统的内核(即内核模式)使用的,而用户模式的程序一般不直接调用这些函数

mov eax, 0C7h:将值0c7h移动至eax寄存器,表示执行编号为0c7h的系统调用
syscall:这是执行系统调用的指令。系统调用编号和参数应在此之前已被设置好(在这种情况下,通过将 0xC7 和 rcx 的内容移动到 eax 和 r10)
这段代码表示执行编号为 0xC7 的系统调用,如果 ds:7FFE0308h 的最低位被设置,那么在系统调用前会先跳转到另一段代码(位于 loc_1800A0525,使用int 2Eh中断进入内核)。如果该位未被设置,那么直接执行系统调用

总结
以下是CreateRemoteThread函数的调用流程图
应用程序调用
CreateRemoteThread,这是一个由kernel32.dll提供的 Win32 API,用于在另一个进程的地址空间中创建新线程。CreateRemoteThread内部调用CreateRemoteThreadEx,这是一个由KernelBase.dll提供的更底层的 API,提供了更多的选项,比如可以指定安全描述符,可以控制新线程是否立即开始运行等CreateRemoteThreadEx内部调用NtCreateThreadEx,这是由ntdll.dll提供的 Native API,也是用户空间可以直接调用的最底层的 API。NtCreateThreadEx函数设置好系统调用的参数后,执行syscall指令,切换到内核模式。在内核模式下,根据
syscall提供的系统调用编号,在 SSDT 表中查找对应的内核函数。执行 SSDT 表中找到的函数,完成线程的创建。

普通线程和远程线程的区别
可以看到普通线程函数CreateThread也调用了CreateRemoteThread函数,只不过其线程句柄参数的值为-1,而远程线程的句柄参数为一个具体的值

代码实现思路
1.ZwCreateThread函数的声明及定义
ZwCreateThread函数的声明及定义当我们使用DLL注入系统服务的进程时会失败,失败的原因在于,当CreateRemoteThread函数尝试在Session 0隔离的系统服务进程中注入DLL时,它通过调用ZwCreateThread函数创建远程线程,其中第七个参数CreateThreadFlags被设置为1。这意味着创建的线程在完成后将被挂起,无法被恢复,因此导致注入失败。为了成功注入,需通过调用ZwCreateThreadEx函数将此参数修改为0。
以下是对ZwCreateThreadEx函数的描述:
由于ZwCreateThread函数未在官方文档中说明,所以我们需对ZwCreateThread函数进行声明:
然后通过GetProcAddress函数来获取这个函数
2.提升进程权限
如果要将dll注入至系统服务进程,还需提升当前进程的权限,以下是提权函数的代码:
3.Session0注入函数
此函数的主要作用是在Session0中注入指定的DLL。其步骤包括提权、打开目标进程、在目标进程中分配内存并写入DLL路径、获取LoadLibraryA函数地址、获取ZwCreateThreadEx函数地址、在目标进程中创建线程运行LoadLibraryA函数,最后释放资源
完整代码
运行测试
首先获取lsass进程的PID,此处为696

以管理员权限运行cmd,使用session0注入将dll注入至lsass进程中

Cobalt Strike成功上线

在火绒剑可以看到lsass进程注入的dll

项目地址
https://github.com/xf555er/Session0_Inject
最后更新于