我们知道现在大多数网络游戏都是有游戏保护的,由于游戏保护的原因当我们使用第三方程序去操作(读写)游戏进程内存的时候,会提示没有读写权限。
这是因为,我们在打开游戏进程(OpenProcess)获取句柄(Handle)的时候,游戏的驱动保护注册有回调过滤我们的句柄权限。
然而在Windows下是有一些系统进程必须与其他进程进行交互的,所以这些系统进程会保存有被保护游戏进程的句柄,并且游戏保护是不容易对其做权限过滤的。例如:lsass.exe ,csrss.exe等。
所以文章标题的“借刀杀人”,指的就是直接利用系统交互进程中的句柄来操作游戏进程内存。这种方式是也是程序全部运行在Ring3层来读写的比较隐藏的方法。
首先查看lsass.exe进程中的句柄,发现它有打开受保护的游戏进程crossfire.exe,且权限为0x1478,具有查询、读写进程等功能。
上文我们是用了微软的procexp工具看到的句柄,那么我们自己怎么用代码自动获取这个句柄呢?
使用NtQuerySystemInformation的第16位功能号枚举系统句柄信息:
在高版本的Windows系统上注入例如lsass的系统程序有可能会失败,我们可以尝试提升权限或者内存加载。
在lsass和csrss等进程没办法绘制窗口或者使用弹窗想要显示我们的内容,因为它们运行在“Session 0”,我们的应用程序运行在其他Session。
“从Vista 开始Session 0 中只包含系统服务,其他应用程序则通过分离的Session 运行,将服务与应用程序隔离提高系统的安全性。如下图所示:
这样使得Session 0 与其他Session 之间无法进行交互,不能通过服务向桌面用户弹出信息窗口、UI 窗口等信息。”
实在要想用弹窗输出信息的话可以用WTSSendMessageA,如下图:
外部进程与注入的Dll交互就用到进程间的通讯技术了。可以网上搜索一下这方面的资料,一般的命名管道,套接字,共享内存,都可以用来作为通讯手段。
在这里使用了命名管道和共享内存,不过命名管道可能容易被检测。这里给出共享内存的代码:
游戏保护想要针对这种读写方式,可以Hook进程lsass.exe的读写函数,然后做控制验证。
根据Joel Noguera提供的资料来看EAC中是这么来做的。
从上边看到EAC游戏保护Hook了lsass.exe的读写函数之后,我们就不能正常调用系统读写函数了。但还是有骚操作的。
我们来看NtReadVirtualMemory的实现:
这个函数实现也是很简单:传参,把服务号放进eax中,判断是否支持快速调用(syscall),不支持就走int 2E,进入内核。
所以我们可以自己实现一个相同的函数来绕过游戏保护的Hook。上文中的测试图MsgType=ZwReadVirtualMemory就是如下图的实现方式。
因为Bypass Hooks技术的出现,使得游戏保护再次升级,这次直接将lsass.exe的游戏进程句柄降权,去掉了其读写权限。如下图:
因为游戏保护对于Ring3层获取进程权限的严格限制,外挂制作者们开始使用跟保护同级别的驱动程序来绕过权限过滤等。
在使用的这些驱动中,一部分是外挂制作者们自己实现的,有些虽然功能强大,但是获取正规签名比较困难也很容易进入游戏保护的黑名单中。
还有一部分是一些第三方正规厂家可受利用的驱动,如鼠标驱动,显卡驱动等,下边我们要讲的就是使用这类的驱动程序来让我们的程序更加隐蔽的获取高的权限。所以这里的“刀”就又变成了“容易被利用”的驱动。
CVE-2017-9769指的是雷蛇的一个设备驱动(Razer Synapse 2.20.15.1104),被发现可以通过控制码直接使用内核调用ZwOpenProcess获取高权限句柄。如下图:
经过测试,虽然获得了一个较高权限(0x1FFD85)的句柄(0x24),但是对于测试的这款游戏(只怪我的计算机上只有这个游戏),依然没有读写内存的权限。
当然这只是一个测试,感兴趣的安全工作者们经过授权也可以尝试使用这种办法测试其他游戏。(其他游戏也许有机会攻击成功)
由于上文中获取的权限没有达到我的要求,所以我想再来一次骚操作。
CVE-2017-15303指的是CPUIDCPU-Z1.43之前的版本中存在安全漏洞,该漏洞源于程序可以向内核模式驱动程序发送控制码(IOCTL 0x9C402430)调用功能,利用该漏洞写入任意内存,从而提升权限。
当然文章只是在讲一种提权的思路,你也可以使用其他的驱动程序:例如 GIGABYTE Driver (CVE-2018-19321),ATSZIO Driver,Intel Driver等。这里我用了CPUZ1.41驱动版本。
提权的思路就是,
1.通过驱动映射物理地址
2.遍历搜索我当前进程(OpenExp.exe)的EPROCESS
3.找到他的ObjectTable
4.找到PHANDLE_TABLE_ENTRY
5.通过驱动写物理地址,修改句柄HANDLE_TABLE_ENTRY中的访问权限为最高权限。
以下是主要的修改权限函数和ExpLookupHandleTableEntry函数
CVE-2018-19320是GIGABYTE Driver驱动级拷贝虚拟内存的漏洞,CVE-2018-19321是GIGABYTE Driver驱动级读写物理内存的漏洞,都是使用GIO这个设备发送控制码,更容易配合。使用方式与上文中的操作物理内存提权类似。不再写了。
使用提权技术也可以把被降权的如lsass.exe进程中的权限提升。不再写了。
又或者自己实现杀伤力更强的“刀”,也不再写了。不然检测与对抗写下去没得结束了。
1.“外挂”与“保护”你可以把它看作是“病毒”与“杀毒”,是对抗的过程。
2.双方的对抗现在都已经升级到了较高的技术,他们的防御与利用也已经需要一定的门槛了。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!