引入Session概念后,我们无法通过注入服务进程来实现可信任进程注入。当我们尝试注入session0当中的进程通常会失败,就是因为我们所处的session与系统服务进程不在同一个session当中。
概念
首先来解释一下Session隔离机制。在Windows XP、Windows Server 2003,以及更老版本的Windows操作系统中,服务和应用程序使用相同的会话(SESSION)来运行,而这个会话是由第一个登录到控制台的用户来启动的,该会话就称为SESSION 0。将服务和用户应用程序一起在SESSION 0中运行会导致安全风险,因为服务会使用提升后的权限来运行,而用户应用程序使用用户特权(大部分都是非管理员用户)运行,这会使得恶意软件把某个服务作为攻击目标,通过“劫持”该服务以达到提升自己权限级别的目的。
从Windows VISTA开始,只有服务可以托管到SESSION 0中,用户应用程序和服务之间会进行隔离,并需要运行在用户登录系统时创建的后续会话中。如第一个登录用户创建Session 1,第二个登录用户创建Session 2,以此类推。
我们使用CreatRemoteThread
在普通用户进程注入shellcode或者Dll没问题,但是想要更进一步注入到系统进程中,那么就一定会失败,就是由于Session 0隔离的缘故。我们接下来就要解决这个问题。
实现方法
引入Session隔离机制后,使用CreateRemoteThread创建远程线程时线程先挂起,然后判断是否运行在所属会话层后再决定是否恢复运行。
ZwCreateThreadEx
函数比CreateRemoteThread
函数更接近内核,CreateRemoteThread
最终也是调用ZwCreateThreadEx
函数来创建线程的,通过前人对CreateRemoteThread
逆向研究发现,在内部调ZwCreateThreadEx
会把第七个参数创建标识设置为1,这样会使在系统服务创建的线程挂起,这也是注入失败的原因。
只要你学过远程线程注入就明白这个技术的实现过程,只是将CreateRemoteThread
换成了ZwCreateThreadEx
。
代码
1 |
|