众所周知在非 Admin 用户模式下,是不允许加载驱动执行 RING 0 代码的。
本文提供了一种方法,通过修改系统 GDT,IDT 来添加自己的 CALLGATE 和
INTGATE 这样便在系统中设置了一个后门。我们就可以利用这个后门
在任意用户模式下执行 ring 0 代码了。为了保证我们添加的 CALLGATE 和 INT
GATE 永久性。可以在第一次安装时利用 SERVICE API 或 INF 文件设置成随
系统启动。不过此方法也有个缺陷,就是在第一次安装 CALLGATE 或 INTGATE
时仍然需要 ADMIN 权限。下面分别给出了添加 CALLGATE 与 INTGATE 的具体
代码。
一、通过添加调用门实现
为了可以让任意用户来调用我们的 CALLGATE 需要解决一个小问题。因为
需要知道 CALLGATE 的 SELECTOR 后才可以调用。而在 RING 3 下除了能
得到 GDT 的 BASE ADDRESS 和 LIMIT 外是无法访问 GDT 内容的。我本想
在 RING 0 把 SELECTOR 保存到文件里。在 RING 3 下读取出来再调用。
后经过跟 wowocock 探讨。他提出的思路是在 RING 0 下通过
ZwQuerySystemInformation 得到 NTDLL.DLL 的 MODULE BASE 然后根据
PE HEADER 中的空闲处存放 SELECTOR。这样在 RING 3 的任意用户模式下
就很容易得到了。在这里要特别感谢 wowocock。下面的代码为了演示
方便,用了在我机器上 GDT 中第一个空闲描述符的 SELECTOR 。
驱动程序:
二、通过添加中断门实现
添加中断门没有什么需要解决的问题。直接在 RING 3 利用 int x
即可切换。想想系统调用 INT 2E 就很容易理解了。