- 第一部分: Introduction to Exploit Development
- 第二部分:Saved Return Pointer Overflows
- 第三部分:Structured Exception Handler (SEH)
- 第四部分:Egg Hunters
- 第五部分:Unicode 0x00410041
- 第六部分:WIN32 shellcode 编写
- 第七部分:返回导向编程(ROP)
- 第八部分:堆喷射第一节【覆写 EIP】
- 第九部分:堆喷射[第二章:UAF]
- 第十部分:内核利用程序之栈溢出
- 第十一部分:内核利用程序之任意位置任意写
- 第十二部分:内核利用程序之空指针引用
- 第十三部分:内核利用程序之未初始化栈变量
- 第十四部分:内核利用程序之整数溢出
- 第十五部分:内核利用程序之 UAF
- 第十六部分:内核利用程序之池溢出
- 第十七部分:内核利用程序之任意位置任意写
- 第十八篇:内核利用程序之 RS2 Bitmap 巫术
- 第十九篇:内核利用程序之 Razer
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
介绍
我想这个话题需要一些介绍,否则你会发现我们即将遇到的大部分障碍都不怎么熟悉。我不会非常详细的展开,因为那太过于耗时了。如果你对这里的一些话题不是很熟悉的话,我建议你先阅读本系列的第 7 部分(ROP)和第 8 部分(堆喷射[第一章:Vanilla EIP])以及上面的阅读材料。
在我们讨论 UAF 之前我们需要先理解虚表(vtable)是什么。C++语言允许基类去定义虚函数。而对于子类来说,它们可以重新去定义这些虚函数的实现体留为己用。也就是说虚函数允许子类去替换基类所提供的实现体。编译器确保被替换的函数永远会被调用,只要该对象实际上是一个子类的话。这些都发生在运行时。
译者注:这里实际上说的不是太理想,虚函数就是子类可以重新定义实现体,且会取代父类提供的实现体。C++用此实现多态,即运行时动态绑定。而所谓多态,简单理解就是——当用父类指针指向子类对象时,一旦调用到虚函数,最后执行的会是子类定义的那个实现体,即作者所说的那个 replacement。
虚表保存了基类中定义的各种虚函数实现体的指针。当一个函数在运行时需要被调用时,合适的指针会从对应的子类虚表中选择出来。我们可以看这样一张表示图。
UAF 漏洞往往较为复杂,引发的问题也变化多端。通常执行流会像这样:
- 在某个点上一个对象被创建并与一个虚表相关联。
- 此后对象由一个虚表指针所调用。如果我们在调用前释放了该对象那么程序会在后面调用该对象时崩溃(eg: 在释放后尝试重用对象——UAF)。
想要利用这个议题我们将通常执行这些操作:
- 在某个点一个对象被创建
- 触发该对象的释放操作
- 我们创建自己的对象,它的尺寸尽可能的和原始对象相仿
- 此后当虚表指针被调用时,我们的伪造对象就被用到并得以执行代码
通常这些听起来贼复杂,但是随着我们示例的展开,一切都会渐渐清晰。首先我们创建一个可信的堆喷射,此后我们再聚焦于 MS13-009!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论