前言

Hello, 欢迎来到windows-kernel-exploit第六篇, 这是从windows 7撸到windows 10的下篇, 这一篇我们主要讨论在RS1, RS2RS3(RS4和RS5有相应的思路, 我还没有去做验证)的利用 希望您能够喜欢 :)

回顾

在上一篇当中, 我们看到了利用write-what-wherewindows 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才能执行后面的操作. 所以我们来对比15031607来看一下我们前一篇的思路为什么失效了.

windows RS1的缓解措施

首先, 我们来看一下windows 1511GdiShreadHandleTable.

接着我们来看一下在window 1607GdiShreaddHandleTable.

我们可以看到在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版本上面, 微软把pvScan0pvBits(如果你仔细的看我以前截的图的话, 你会发现这两个是出奇的一致的)指向的对象放到了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的构造. 所以应该对我的学习帮助还是很大的.

关于缓解措施的探讨

缓解措施我不知道自己的结论是否正确, 如果你仔细的推论, 那么你会发现如果你学会了最新的版本的绕过, 那么好像也适用于前面的版本. 是不是前面的那些麻烦的结论就不用学习了呢. 我的结论是, 是的, 作为工业性的开发确实如此. 但是这种思想会有一种小小的问题. 感觉自己在乞食. 比如说现在, RS4RS5我自己并没有找到有效的paper, 那么我们只能选择等待么. 等待明年的blackhat介绍新的方法? 我个人的想法是不是的. 其实比起怎么利用, 我更在意的是, blakhat的原作者是怎么想到这里的. 总结一下绕过思路.

[+] 可以使用bitmap(GDISHAREDHANDLETABLE)
[+] 不可以使用GDISHAREDTABLE
    ==> 那我换一个gShredInfo
[+] 不可以使用gSharedInfo
    ==> 那我换一个 fengshui 预判
[+] 不可以使用bitmap
    ==> 那我换一个palatte

所以你可以看到它的你用思路其实说到底都是思维的逃逸. 如果我们能逃过微软的限制, 那么我们就能开发出新的思路. 但是, 没有旧的思路就没有新的思路, 所以我个人觉得这一部分的学习还是相当重要的.

关于RS4和RS5

HmValidateHanldle失去效果之后, 我失去了所有泄露GDI对象的思路. 就在前天睡觉的时候, 发现有一种新的思路可能具有可行性, Howerver, 这几天我一直在准备面试, 所以还没有来得及实验验证他. 在后期的学习道路上, 我会把失败(我觉得失败的可能性比较大)或者成功的结果同步更新到这里, 敬请期待.

后记

Anyway. 希望能够对您有所帮助.

最后, wjllz是人间大笨蛋.

相关链接

[+] 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

源链接

Hacking more

...