UAF Writeup - pwnable.kr

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都可以,不过没有测试。有兴趣的朋友可以测试一下。

原文发布于微信公众号 - 逢魔安全实验室(FormSec)

原文发表时间:2018-02-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python爬虫与数据挖掘

Python正则表达式初识(八)

继续分享Python正则表达式的基础知识,今天给大家分享的特殊字符是“\w”和“\W”,具体的教程如下。

10820
来自专栏我是攻城师

理解Java8的数据类型和运行时数据区域

Java虚拟机包含对对象的显式支持,对象要么是动态分配的类实例,要么是静态数组,对对象的引用我们可以叫做指针或者引用,一个对象可以有多个引用,对象总是通过引用的...

17030
来自专栏老九学堂

这是谁做的作业!C语言编码太不规范了...

1) 程序应采用缩进风格编写,每层缩进使用一个制表位(TAB),类定义、方法都应顶格书写;

18020
来自专栏数据分析

char varchar nchar nvarcharar到底有多大区别

首先说明下,ASP.NET MVC系列还在龟速翻译中。 工作好多年,基础知识甚是薄弱,决定以后在coding(cv操作)的时候尽量多google下,然后总结下来...

32260
来自专栏北京马哥教育

Python 面试问答 Top 25

Python 是一种解释型,交互式,面向对象的高级编程语言。和别的一些使用标点符号的语言不同,Python使用了大量的英语单词作为关键字,因而具有很好的可读性...

35660
来自专栏决胜机器学习

《Redis设计与实现》读书笔记(三十三) ——Redis排序命令sort的实现

《Redis设计与实现》读书笔记(三十三) ——Redis排序命令sort的实现 (原创内容,转载请注明来源,谢谢) 一、基本功能 redis的sort命令,可...

42450
来自专栏aCloudDeveloper

C++primer笔记之关联容器

在这一章中,有以下的几点收获: 1、pair类型的使用相当频繁,如果需要定义多个相同的pair类型对象,可考虑利用typedef简化其声明: typedef p...

21090
来自专栏北京马哥教育

Python 面试问答 Top 25

Python 是一种解释型,交互式,面向对象的高级编程语言。和别的一些使用标点符号的语言不同,Python使用了大量的英语单词作为关键字,因而具有很好的可读性。...

13730
来自专栏向治洪

Promise机制详解

Javascript 采用回调函数(callback)来处理异步编程。从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的...

36470
来自专栏程序员互动联盟

【答疑解惑第六讲】数组与指针区别在哪?

存在问题: 小伙伴都说指针和数组不好学,总是搞不太清楚?两者到底有啥区别? 解决方案: 很多初学者朋友总是对数组和指针模模糊糊,搞不清楚。对他们之间的联系与区...

354110

扫码关注云+社区

领取腾讯云代金券