Windows Kernel Exploit Part 6
作者:wjllz
来源:先知安全技术社区
前言
Hello, 欢迎来到windows-kernel-exploit
第六篇, 这是从windows 7撸到windows 10
的下篇, 这一篇我们主要讨论在RS1
, RS2
和RS3
(RS4和RS5有相应的思路, 我还没有去做验证)的利用 希望您能够喜欢 :)
回顾
在上一篇当中, 我们看到了利用write-what-where
在windows 7, 8, 8.1 1503
的利用, 是不是感觉有些奇怪. 为什么我们的出的结论是这些操作版本呢. 让我们先来看下如果在上一篇当中利用bitmap
的思路.
[+] 泄露hmanager bitmap和 hworker bitmap地址[+] 从而泄露出hmanager bitmap和hworker bitmap的pvScan0地址
[+] 利用write-what-wher将hmanager的pvScan0改为hworker pvScan0的地址.
[+] readOOB:
==> 先对hmanager setbitmapbits使worker得pvScan0变为任意地址
==> 使用hworker getbitmapbits对任意地址进行读操作
[+] writeOOB:
==> 先对hmanager setbitmapbits使worker得pvScan0变为任意地址
==> 使用hworker getbitmapbits对任意地址进行写操作
第一点尤其重要, 我们必须要泄露出bitmap
才能执行后面的操作. 所以我们来对比1503
和1607
来看一下我们前一篇的思路为什么失效了.
windows RS1的缓解措施
首先, 我们来看一下windows 1511
的GdiShreadHandleTable
.
接着我们来看一下在window 1607
的GdiShreaddHandleTable
.
我们可以看到在RS1的版本下, GdiShreadHanldleTable
指向的已经不是一个真正的指针了. 所以我们无法完成后续的操作.
缓解措施(图片来源: blackhat):
在windows RS1上面实现利用
泄露bitmap地址
So, 众所周知, 有防范就一定有绕过. 我们先来看分代码.
这是它的运行结果:
先不管三七二十一, 是不是兴奋的想擦鼻血. 那种FFF
开头的, 总感觉有什么东西的内核地址被泄露了. 有内核泄露就很舒服. 让我们看看他是怎么泄露的.
gSharedInfo
调试器里面我们获取到了gSharedinfo
. 他有什么用呢.
标黄的指向ahelist
, 这是一张表. 存放一些与handle关联的信息. 其中的Entry是.
look, 其中指向了该handle的内核地址. 后面的代码计算内核地址我们的第四章的内容一样. 相信你一定可以理解.
如何泄露bitmap
通过这个方法, 我们可以通过句柄去泄露一些对象(user object)的地址. 能够泄露的对象(user object)在微软的官网上只有这些.
你会发现好像和我们的bitmap无关. 真的无关么. 先来看我写的一个小小的c++
代码.
我把结果dump到一个文件.
其中CreateAcceleratorTable
是创建一个pool
, Delete是释放一个DestroyAcceleratorTable
. 代码做的过程是不断地分配一个pool和不断地释放一个pool.
我们把看到我们dump出来的地址每次都是一样的, 可以看到我们的地址已经稳定了. Bingo!
让我们来看看这个对象的pool 信息. paged pool sesssion. 在第四章中我们总结bitmap的时侯我们的bitmap也是同样的大小. 那么. 如果我们分配同样大小的bitmap. 是不是就能够有机会把bitmap的地址泄露出来呢. 答案是肯定的. 所以有了下面的代码.
验证结果:
但是, 可能比较疑惑, 传入的参数为什么是700. 我的思路是用第四章的思路传入0x10
, 0x100
, 0x700
. 来验证重用的稳定性, 这里就不再赘述. 而abuse gdi里面的ppt有提到当分配到pool过大的时候, 会降低随机性.
泄露基地址
泄露基地址和在第四章不太一样, 原因起源于github的项目我是抱着学习的思路去做的. 所以写代码的过程是读paper+调试+copy别人代码
, 所以也获取了很多的额外的知识.
利用NtQuerySystemInformation
可以获取一些关于内核的信息. 重要的是第二个参数.
用数字来标明我们想查找的是有关内核模块的信息. 在这里你可以找到更详细的解释.
在windows RS2上面实现利用.
You know, 事情总会越来越难, 在RS2上面的时候, 发生了啥. 让我们运行一下原来我们用于泄露的代码.
可以发现一切都是好好的, 但是就是获取不到内核地址. 于是为了简单. 这是由于上面说的HADNLE_ENRTY结构体的pkernel被微软给禁掉了. 于是, 我们gShreadInfo
泄露bitmap的地址失效了.
所以前辈们他们又继续开动了他们的脑洞. 用了我在第四章中提到的tagCLS对象
及lpszMenuName
. 有兴趣的话你可以顺着第四章的思路和上面做同样的实验进行验证. 由于第四章的找tagCLS
讲的足够详细了, 在这里我就不再赘述. 详细的你可以在这里找到.
code
在windows RS3上面实现利用
好了, 微软终于意识到了bitmap的pvScan0是一个异常不安全的东西. 于是在RS3上面, 微软做了下面的事.
图片来源(blackhat):
可以看到在RS3版本上面, 微软把pvScan0
和pvBits
(如果你仔细的看我以前截的图的话, 你会发现这两个是出奇的一致的)指向的对象放到了heap
里面.(我曾经做过一个猜想, 上面使用的是pool, 堆喷如果可控的话是不是可以泄露呢. 但是HMvalidate函数在windows rs4版本失去了效果, 我暂时还没有找到其他的方案可以帮我泄露堆来验证这个观点, 所以这里就省去不提). 导致了我们的bitmap技术失效.
Howerver, 事情总是有曙光的, bitmap挂了的话, 我们的思路可以转换为其他的对象.
platte的闪亮登场
我们先来看个图, 接着再讨论其他的事:
我们可以看到有一个palatte的对象, 含有和bitmap
类似的结构. 即使在RS3
的版本上.
借助于此, 我们可以创建一个palatte对象, 我真心的希望是, 您可以映着第四章的思路. 完成自己的实验去探讨palatte
的分配pool大小关系. 在这里, 我并没有做这个工作, 一方面, 我给姐姐承诺的deadline是今晚. 调试截图会花费我很多的时间, 另外一方面. 调试器下见真章
是我在绕过了无数弯路之后的最大的收获, 也希望您能够学会他. 后续的利用思路就和bitmap及其的相似, 这里就不再赘述,让我们看code
.
code
总结
关于项目
bitmap的利用和我当时做DDCTF有关, 我一度陷入微软的各个API里面, 然后我开始陷入了深深的思考. 我自己做的方向是不是做错了. 因为我学习的过程中, 更在乎的是怎么利用. 碰到这个利用觉得哇, 这个思路(??????)??. nice那种, 但是分析呢. 所以我觉得分析的能力我很弱. 于是我当时选择了DDCTF放一放, 就在github上面做了这个项目. 我想保证我在windows 7 到 windows 10的各个版本都有可利用的方法和手段. 借助于阅读paper
+调试
+阅读源码
, 我完成了这个目标. 在做完了这个项目之后, 我后期的好几个利用编写都是直接COPY代码, 然后专注于WWW
的构造. 所以应该对我的学习帮助还是很大的.
关于缓解措施的探讨
缓解措施我不知道自己的结论是否正确, 如果你仔细的推论, 那么你会发现如果你学会了最新的版本的绕过, 那么好像也适用于前面的版本. 是不是前面的那些麻烦的结论就不用学习了呢. 我的结论是, 是的, 作为工业性的开发确实如此. 但是这种思想会有一种小小的问题. 感觉自己在乞食. 比如说现在, RS4
和RS5
我自己并没有找到有效的paper
, 那么我们只能选择等待么. 等待明年的blackhat
介绍新的方法? 我个人的想法是不是的. 其实比起怎么利用, 我更在意的是, blakhat的原作者是怎么想到这里的. 总结一下绕过思路.
[+] 可以使用bitmap(GDISHAREDHANDLETABLE)[+] 不可以使用GDISHAREDTABLE
==> 那我换一个gShredInfo
[+] 不可以使用gSharedInfo
==> 那我换一个 fengshui 预判
[+] 不可以使用bitmap
==> 那我换一个palatte
所以你可以看到它的你用思路其实说到底都是思维的逃逸. 如果我们能逃过微软的限制, 那么我们就能开发出新的思路. 但是, 没有旧的思路就没有新的思路, 所以我个人觉得这一部分的学习还是相当重要的.
关于RS4和RS5
在HmValidateHanldle
失去效果之后, 我失去了所有泄露GDI
对象的思路. 就在前天睡觉的时候, 发现有一种新的思路可能具有可行性, Howerver, 这几天我一直在准备面试, 所以还没有来得及实验验证他. 在后期的学习道路上, 我会把失败(我觉得失败的可能性比较大)或者成功的结果同步更新到这里, 敬请期待.
相关链接
- sakura师父博客: http://eternalsakura13.com/
- 小刀师傅博客: https://xiaodaozhi.com/
- 滥用GDI: https://sensepost.com/blog/2017/exploiting-ms16-098-rgnobj-integer-overflow-on-windows-8.1-x64-bit-by-abusing-gdi-objects/
- 我的个人博客: http://www.redog.me/
- 我的github地址: https://github.com/redogwu
- 本文相关的pdf下载: https://github.com/redogwu/study-pdf
- 本文的代码: https://github.com/redogwu/windows_kernel_exploit
以上是 Windows Kernel Exploit Part 6 的全部内容, 来源链接: utcz.com/p/199286.html