Table of contents
Enumeration
First I scanned for all ports on the machine and saved the output as grep format. It's much faster to scan for all ports on the box before doing the version and script scan.
sudo nmap -p- --min-rate=5000 -oG broker 10.10.11.243 --vv
I used grep to search for ports that are open and then I used awk to filter for open ports and substitute the new line with comma so we can take the output and scan again the target machine much quicker using Nmap script scan.
└──╼ $grep -oP '([\d]+/open)' broker | awk -F / '{print $1}' | tr '\n' ','
22,80,1883,5672,8161,61614,61616,
└──╼ $nmap -sVC -T4 -p "22,80,1883,5672,8161,61614,61616" 10.10.11.243
Starting Nmap 7.93 ( https://nmap.org ) at 2023-11-26 19:19 EST
Nmap scan report for 10.10.11.243
Host is up (0.094s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3eea454bc5d16d6fe2d4d13b0a3da94f (ECDSA)
|_ 256 64cc75de4ae6a5b473eb3f1bcfb4e394 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ basic realm=ActiveMQRealm
|_http-title: Error 401 Unauthorized
1883/tcp open mqtt
| mqtt-subscribe:
| Topics and their most recent payloads:
| ActiveMQ/Advisory/MasterBroker:
|_ 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
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
| fingerprint-strings:
| NULL:
| ActiveMQ
| TcpNoDelayEnabled
| SizePrefixDisabled
| CacheSize
| ProviderName
| ActiveMQ
| StackTraceEnabled
| PlatformDetails
| Java
| CacheEnabled
| TightEncodingEnabled
| MaxFrameSize
| MaxInactivityDuration
| MaxInactivityDurationInitalDelay
| ProviderVersion
|_ 5.15.15
There're seven ports that are open so, I saw http 80 port open I fire up the browser and pasted the IP address in the URL bar, then it prompt me for a login credentials:
Using the default credentials admin as user and admin as password, it's seems it worked and it's letting me in.
Click on "see some web demos" to see some information
The server is running the The Apache ActiveMQ hence we did a vulnerability research on this...
Upon doing so we found a CVE-2023-46604 on the Apache ActiveMQ and it's vulnerable to a deserialization vulnerability which than gives the threat actors Remote Code Execution (RCE). In fact in our previous Nmap scan we found that the version is 5.15.15 is less than 5.15.16 this indicate that it's vulnerable.
Apache ActiveMQ is a message broker service, designed to act as a communication bridge between disparate services. Developed in Java, it can broker multiple protocol formats, such as AMQP, STOMP, MQTT and OpenWire. CVE-2023-46604 is a remote unauthenticated deserialization vulnerability in the OpenWire transport connector provided by ActiveMQ. By default the OpenWire transport connector listens for TCP connections on port 61616 and is enabled by default. Successful exploitation allows an attacker to execute arbitrary code with the same privileges of the ActiveMQ server.
source
Foothold
There's an exploit module of this vulnerability on Metasploit link, however I found a script on GitHub so I thought why not using it.
modify the file poc-linux.xml
to contain the malicious code in our case we're going to use an encoded reverse shell payload and then attempting to past it in our code.
Run the Golang script to check what are the arguments needed in order for it to work.
We specify the target's IP address using the -i flag, the target port running ActiveMQ with
the -p flag, and our web server hosting the malicious payload with the -u flag.
Finally, we open a new terminal and execute the following command:
We start a Python3 HTTP server as well as we start a Netcat listener.
we can see the target requesting the web page in the log of our python server
Checking our listener we can see we successfully managed to get a shell on the box.
Privilege Escalation
Checking what are the commands that the user can run as root, we can see clearly that the user has the permission to load the nginx configuration.
We can elevate our privileges as root by modifying the nginx configuration file. we will use the ngx_http_dav_module
to write our public SSH key into the root user's authorized_keys
file
to do so:
First filter out the commented lines '#' with grep
and redirect the output to /tmp
directory like so.
activemq@broker:/etc/nginx$ cat nginx.conf | grep -v '\#' | grep . > /tmp/nginx.conf
The configuration file should look like this at the end.
activemq@broker:/etc/nginx$ nano /tmp/nginx.conf
user root;
: Specifies the user that the Nginx worker processes should run as. In this case, it's set to the root user.
http { ... }
: This block contains the main configuration for the HTTP server.server { ... }
: Configures a server block. This is where you define settings specific to a particular virtual server.
listen 4446;
: Specifies the port on which the server will listen for incoming connections. In this case, it's set to port 4446.root /;
: Sets the root directory for the server. In this case, it's set to the root directory /
.
autoindex on;
: Enables directory listing. If a client requests a directory, and there is no index file, Nginx will generate a listing of the directory contents.
dav_methods PUT;
: Enables WebDAV and allows the use of the HTTP PUT method to upload resources to the server.
Starts the Nginx web server with a specific configuration file.
Generate the ssh keys with the command ssh-keygen -f brokerkey
and uploading the public key brokerkey.pub
and writing it to /root/.ssh/authorized_key
.
We can now ssh into the machine as the root user with our private key.
cat root.txt
to get the root flag.