Hack The Box: Spectra


Jump Ahead: EnumGetting Initial AccessUserRootResources

TL;DR;

To solve this machine, we begin by enumerating open services – finding ports 22, 80, and 3306 open. From a webserver, we discover a testing directory with index listing enabled. From the index, we find a backup copy of a WordPress configuration which gives us the password for the administrator user on the server’s main WordPress. After logging into the WordPress administration panel, we are able to execute a reverse shell, and get access to the machine as nginx. After looking around the machine, we find an interesting file we are able to read, which references another file. Within the secondary file, we find the password for the user katie – allowing access to user.txt. As katie, we are allowed to run a command as root. Due to the nature of the command, we are able to exploit it and get a shell as root – allowing access to root.txt.

Enumeration

Like all machine, we begin by enumerating open ports – finding ports 22, 80, and 3306 open.

$ sudo nmap -p- -v -sV -A --min-rate=3000 -oA enum/nmap/tcp-all-scripts 10.129.110.218
# Nmap 7.91 scan initiated Sun Feb 28 08:58:51 2021 as: nmap -p- -v -sV -A --min-rate=3000 -oA enum/nmap/tcp-all-scripts 10.129.110.218
Nmap scan report for 10.129.110.218
Host is up (0.044s latency).
Not shown: 65532 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.1 (protocol 2.0)
| ssh-hostkey: 
|_  4096 52:47:de:5c:37:4f:29:0e:8e:1d:88:6e:f9:23:4d:5a (RSA)
80/tcp   open  http    nginx 1.17.4
| http-methods: 
|_  Supported Methods: GET HEAD
|_http-server-header: nginx/1.17.4
|_http-title: Site doesn't have a title (text/html).
3306/tcp open  mysql   MySQL (unauthorized)
|_ssl-cert: ERROR: Script execution failed (use -d to debug)
|_ssl-date: ERROR: Script execution failed (use -d to debug)
|_sslv2: ERROR: Script execution failed (use -d to debug)
|_tls-alpn: ERROR: Script execution failed (use -d to debug)
|_tls-nextprotoneg: ERROR: Script execution failed (use -d to debug)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.91%E=4%D=2/28%OT=22%CT=1%CU=40554%PV=Y%DS=2%DC=T%G=Y%TM=603BAFF
OS:D%P=x86_64-pc-linux-gnu)SEQ(SP=103%GCD=1%ISR=109%TI=Z%CI=Z%TS=A)SEQ(SP=1
OS:03%GCD=1%ISR=109%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M54DST11NW7%O2=M54DST11NW7%O
OS:3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11NW7%O6=M54DST11)WIN(W1=FE88%W2=
OS:FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSN
OS:W7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%D
OS:F=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O
OS:=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W
OS:=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%R
OS:IPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)

Uptime guess: 6.607 days (since Sun Feb 21 18:25:34 2021)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=259 (Good luck!)
IP ID Sequence Generation: All zeros

TRACEROUTE (using port 8888/tcp)
HOP RTT      ADDRESS
1   44.72 ms 10.10.14.1
2   44.87 ms 10.129.110.218

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 Sun Feb 28 09:00:13 2021 -- 1 IP address (1 host up) scanned in 82.07 seconds

Since port 80 is a webserver, we can further enumerate using tools like nikto and gobuster. From gobuster we find 2 directories – /testing and /main. By enumerating those directories, we learn that each is likely hosting WordPress.

Getting Initial Access

Going to the webserver hosted on port 80, we are presented with a bare website that has a couple links.

From the source code, we learn the links point to a new domain – spectra.htb. So that we may follow the links, we add the new domain to our /etc/hosts file. Clicking the “Test” link, we are sent to http://spectra.htb/testing/index.php, which returns a page stating there is a database connection error.

Clicking on the “Software Issue Tracker” link takes us to a WordPress site at http://spectra.htb/main/. To quickly enumerate the site, we launch wpscan. From the scan results, we learn the site is running version 5.4.2, and the only user is administrator.

_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.15
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[+] URL: http://spectra.htb/main/ [10.129.110.218]
[+] Started: Sun Feb 28 10:13:29 2021

Interesting Finding(s):

[+] Headers
 | Interesting Entries:
 |  - Server: nginx/1.17.4
 |  - X-Powered-By: PHP/5.6.40
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] XML-RPC seems to be enabled: http://spectra.htb/main/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

[+] WordPress readme found: http://spectra.htb/main/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] The external WP-Cron seems to be enabled: http://spectra.htb/main/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 5.4.2 identified (Insecure, released on 2020-06-10).
 | Found By: Rss Generator (Passive Detection)
 |  - http://spectra.htb/main/?feed=rss2, <generator>https://wordpress.org/?v=5.4.2</generator>
 |  - http://spectra.htb/main/?feed=comments-rss2, <generator>https://wordpress.org/?v=5.4.2</generator>

[+] WordPress theme in use: twentytwenty
 | Location: http://spectra.htb/main/wp-content/themes/twentytwenty/
 | Last Updated: 2020-08-11T00:00:00.000Z
 | Readme: http://spectra.htb/main/wp-content/themes/twentytwenty/readme.txt
 | [!] The version is out of date, the latest version is 1.5
 | Style URL: http://spectra.htb/main/wp-content/themes/twentytwenty/style.css?ver=1.2
 | Style Name: Twenty Twenty
 | Style URI: https://wordpress.org/themes/twentytwenty/
 | Description: Our default theme for 2020 is designed to take full advantage of the flexibility of the block editor...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Css Style In Homepage (Passive Detection)
 |
 | Version: 1.2 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://spectra.htb/main/wp-content/themes/twentytwenty/style.css?ver=1.2, Match: 'Version: 1.2'


[i] No plugins Found.


[i] Theme(s) Identified:

[+] twentynineteen
 | Location: http://spectra.htb/main/wp-content/themes/twentynineteen/
 | Last Updated: 2020-08-11T00:00:00.000Z
 | Readme: http://spectra.htb/main/wp-content/themes/twentynineteen/readme.txt
 | [!] The version is out of date, the latest version is 1.7
 | Style URL: http://spectra.htb/main/wp-content/themes/twentynineteen/style.css
 | Style Name: Twenty Nineteen
 | Style URI: https://wordpress.org/themes/twentynineteen/
 | Description: Our 2019 default theme is designed to show off the power of the block editor. It features custom sty...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Known Locations (Aggressive Detection)
 |  - http://spectra.htb/main/wp-content/themes/twentynineteen/, status: 200
 |
 | Version: 1.5 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://spectra.htb/main/wp-content/themes/twentynineteen/style.css, Match: 'Version: 1.5'

[+] twentyseventeen
 | Location: http://spectra.htb/main/wp-content/themes/twentyseventeen/
 | Last Updated: 2020-08-11T00:00:00.000Z
 | Readme: http://spectra.htb/main/wp-content/themes/twentyseventeen/readme.txt
 | [!] The version is out of date, the latest version is 2.4
 | Style URL: http://spectra.htb/main/wp-content/themes/twentyseventeen/style.css
 | Style Name: Twenty Seventeen
 | Style URI: https://wordpress.org/themes/twentyseventeen/
 | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Known Locations (Aggressive Detection)
 |  - http://spectra.htb/main/wp-content/themes/twentyseventeen/, status: 200
 |
 | Version: 2.3 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://spectra.htb/main/wp-content/themes/twentyseventeen/style.css, Match: 'Version: 2.3'

[+] twentytwenty
 | Location: http://spectra.htb/main/wp-content/themes/twentytwenty/
 | Last Updated: 2020-08-11T00:00:00.000Z
 | Readme: http://spectra.htb/main/wp-content/themes/twentytwenty/readme.txt
 | [!] The version is out of date, the latest version is 1.5
 | Style URL: http://spectra.htb/main/wp-content/themes/twentytwenty/style.css
 | Style Name: Twenty Twenty
 | Style URI: https://wordpress.org/themes/twentytwenty/
 | Description: Our default theme for 2020 is designed to take full advantage of the flexibility of the block editor...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Urls In Homepage (Passive Detection)
 | Confirmed By: Known Locations (Aggressive Detection)
 |  - http://spectra.htb/main/wp-content/themes/twentytwenty/, status: 200
 |
 | Version: 1.2 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://spectra.htb/main/wp-content/themes/twentytwenty/style.css, Match: 'Version: 1.2'


[i] User(s) Identified:

[+] administrator
 | Found By: Author Posts - Display Name (Passive Detection)
 | Confirmed By:
 |  Rss Generator (Passive Detection)
 |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 |  Login Error Messages (Aggressive Detection)

[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register

[+] Finished: Sun Feb 28 10:14:46 2021
[+] Requests Done: 21504
[+] Cached Requests: 17
[+] Data Sent: 5.657 MB
[+] Data Received: 3.835 MB
[+] Memory used: 283.426 MB
[+] Elapsed time: 00:01:17

In the upper right corner of the main page, there is a link titled “Sample Page”. After clicking the link, we a sent to a post that mentions we should go to our dashboard to delete the page.

As the link does not work, we assume the /testing directory we found earlier might be what is being referenced. After going to http://spectra.htb/testing/, we are presented with a directory index of what appears to be a WordPress site. As all files are listed, we look for something that may stand out. Within the listing, we find a file named wp-config.php.save. As the file extension suggests it’s a backup of the wp-config.php file, we open it to try to get database credentials. By opening it, we are presented with a blank page, however, by viewing the source, we are able to extract database credentials.

As ports 22 and 3306 are exposed externally, we attempt the use the credentials to authenticate, however, they do not work. Since we know the WordPress owner username is administator, we attempt to log into the administrative portal at http://spectra.htb/main/wp-admin/ with the password. By doing so, we are presented access to the Admin Dashboard.

As we’ve done before in other machines, we head over to the WordPress Plugins area, and edit the “Akismet” plugin index file to host a reverse shell. For the reverse shell we used PentestMonkey‘s php reverse shell, as simpler shells kept failing.

Before navigating to http://spectra.htb/main/wp-content/plugins/akismet/index.php to execute the reverse shell, we start a netcat listener on our chosen port. Then, we navigate to the index page to execute the reverse shell. By doing so, we get a shell as nginx.

Getting User

Having gotten a shell as nginx, we begin our initial local enumeration, but do not find anything of much interest. Next, we run linpeas to automate enumeration, however, it does not return anything that stands out. Next, we look around the machine, and see that /opt exists. As this directory typically hosts software not shipped with the OS’s package manager, we check this directory for interesting programs and files. In the /opt directory, we find autologin.conf.orig, which sounds interesting enough, so we look at it. Within it, we find references to directories /mnt/stateful_partition/etc/autologin/ and /etc/autologin/. /mnt/stateful_partition/etc/autologin/ does not exist, however, /etc/autologin does. In that directory, we find a file named passwd. From the file, we get an assumed password.

Using the password, we are able to log into the machine as katie, allowing us to read user.txt.

Getting Root

Having gained a shell as katie, we begin to enumerate the machine locally with our new access. One of the first commands we run is sudo -l. From the output, we learn we are able to /sbin/initctl as root without a password. From a quick search, we learn initctl is a tool to control daemons.

Next, we use the find command to search for files owned by the developer group, since katie is a member of that group. As most of the files are in the /etc/init/ directory (where daemons are stored), and we can write to them as part of our group permissions, we should be able to hijack one of them to get a reverse shell.

To get a reverse shell, we can use python, as the machine’s Bash does not support the /dev/tcp/ device file. For this, we edit /etc/init/test.conf, comment out the line that runs node, and set our python reverse shell to run using the exec init command.

Lastly, we start our reverse shell listener, and save the file. Then we execute sudo /sbin/initctl start test. Once we run the command, we are returned a process ID, and now have a shell as root. We are now able to read root.txt.

Thank you for taking the time to read my write-up. I am interested in other ways this machine has been solved. Feel free to reach out to me and we can discuss it. Thanks!

Resources