前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >UAF Writeup - pwnable.kr

UAF Writeup - pwnable.kr

作者头像
xfkxfk
发布2018-03-29 15:25:29
9480
发布2018-03-29 15:25:29
举报

0x00 UAF

pwnable.kr是一个韩国的CTF练习的网站,有很多经典的CTF题目供爱好者练习。

UAF(Use After Free)释放后重用,其实是一种指针未置空造成的漏洞。在操作系统中,为了加快程序运行速度,如果释放一块n字节大小的内存空间,当申请一块同样大小的内存空间时,会将刚刚释放的内存空间重新分配。如果指向这块内存空间的指针没有置空,会造成一系列的问题。

0x01 Fastbin

fastbin顾名思义,fast就是要快。所以fastbin旨在加快操作系统的内存分配速度,fastbin仅使用fd形成单链表的形式,且遵循LIFO原则。

当操作系统分配一块较小的内存时(64字节),会首先从从fastbin中寻找未使用的chunk并分配。

0x02 分析

通过分析题目源代码,看到各个操作的含义

  1. 调用
  2. 分配内存
  3. 释放内存

大概的思路是通过3先释放内存,因为程序释放内存后没有将指针置空。故在重新分配时会出现UAF。

0x03 Solution

这个题目涉及C++程序的逆向,我们可以看一下C++中的继承是怎么体现的,以Man为例

先new了一个Human的类,在修改这个类的虚表(vptr)为Man类的虚表,最后给类的成员变量赋值。

可以看到这个对象m所占的内存空间为8(vptr) + 8(int[age]) + 8(ptr[name]) = 24字节。知道了m对象所占的内存空间,下面需要观察内存空间的布局。

m对象内存布局的示意图

在看一下在C++中,程序是如何调用虚函数的。

对应的C++代码

m->introduce();w->introduce();

可以看出是通过虚表的index来完成函数调用,所以要调用getshell函数需要把虚表指针的base - 8

看对方服务器上虚表的地址

可以看到,需要覆盖的虚表指针为0x401550 - 0x8 = 0x401548。只要将m对象的虚表指针覆盖为0x401548,再通过m -> introduce()即可完成invoke shell。通过UAF可以完成m对象指向的内存空间的修改。

但是,释放内存空间的过程是先释放m再释放w。

delete m;delete w;

通过一次UAF只能修改w指向的内存空间,而在引用的时候却先引用了m指向的内存空间。

m->introduce();w->introduce();

这是m指向的内存空间已经被释放,会造成段错误。

因为这块内存空间仅为24字节,所以属于fastbin。根据前面的知识,fastbin是一个LIFO的结构。所以我们只需要分配两次24字节的内存空间,第二次就会分配到之前被释放的m所指向的内存空间。所以需要运行两次分配空间的过程。

后话: 因为堆是8字节对齐的,只要重新分配的内存在9-24字节之间就可以分配到之前释放的m和w。所以,程序第一个参数为9-24都可以,不过没有测试。有兴趣的朋友可以测试一下。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-02-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 逢魔安全实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档