0x00前言
这一系列就快结束了 这次是未初始化栈变量 开始吧
0x01漏洞原理
未初始化的栈 会在调用的时候 随机填入值 我们可以将shellcode填入其中 从而去执行我们的shellcode
函数分析
如前面所说 这个函数漏洞版本中未初始化内存栈 导致UserValue != MagicValue 调用回调
1 | NTSTATUS |
0x02漏洞分析
先下断点
1 | bp HEVD!TriggerUninitializedMemoryStack |
啊这次只要在WinDbg上调试导入符号表就奇怪的无法提权 即使在没调试的情况下 也是会有几率失败的 所以我从TJ师傅那里的代码 进行验证 IO控制码还是从IDA中得到的哈
还有就是wjllz师傅说的方法
1 | #include<stdio.h> |
可以看到 对UserValue的值进行了正确的赋值
0x03漏洞利用
起初我以为是将回调函数的指针覆盖为shellcode的地址 在下断点查看之后发现并不是 看到TJ师傅讲的文章 里面提到了j00ru师傅的文章 进行栈喷射 在操作系统中 我们学到过关于用户栈和内核栈的皮毛 关于栈的结构 其实在ctfwiki上早已看到过 在j00ru师傅的文章中 也讲到过栈结构 再进一点的东西 我们需要知道下面函数
大致的先讲一下思路 我们先利用NtMapUserPhysicalPages进行栈喷射 将栈中的数据覆盖为我们shellcode 然后使用漏洞点 将其使用我们刚才我们控制的栈
1 | NTSTATUS |
我们也可以看到COPY_STACK_SIZE是缓冲区栈值的大小 所以它可以使用户传递1024*4=4096个字节的值
1 | #define COPY_STACK_SIZE 1024 |
即可以用来控制最多4096个字节的内核栈 我们将shellcode的位置传到此处 而我们使用的为
1 | NtMapUserPhysicalPages(NULL, 1024, StackSprayBuffer); |
看看exp的核心部分 首先申请内存进行栈喷射将shellcode的地址覆盖在栈中 然后再触发漏洞函数 进行提权
1 | __try { |
提权成功
0x04补丁分析
在安全版本中 我们将栈的初始值进行赋值
0x05经验总结
对于未初始化栈利用 在内核态需要更加注意 稍有不慎就会覆盖到重要数据导致宕机 还好有前人的经验总结 让我们的可以更好的利用这些 不足之处是 师傅们不仅专业能力强 而且对于英文能力也是毫不逊色 自己真是太菜了qaq。。。
0x06出了点问题?
对于shellcode的地址在原则上说是没有问题的 但下断点查看之后 发现并不是这样 还是一个跳转表 本以为和上次一样 但继续跟踪之后发现并不能跟到shellcode的地址 这就很疑惑的 主要是被覆盖的栈中 确实是大量相同的数据。。。。。不理解。。。。。但确实是提权成功了
对于提权成功也有点问题 每次恢复快照 有时候就可以100%提权成功 有时候就不可以 奇奇怪怪。。。