Book – Máquina dificultad Medium donde veremos un método para cambiar la contraseña del usuario admin desde un panel de registro, un método de lectura en un PDF y escalada de privilegios hasta root.
Table of Contents
ToggleFase de reconocimiento - NMAP
Empezamos escaneando los puertos de la máquina víctima
❯ nmap -p- --open -sS --min-rate 5000 -vvv -n 10.129.95.163
Starting Nmap 7.99 ( https://nmap.org ) at 2026-09-23 20:56 +0200
Initiating Ping Scan at 20:56
Scanning 10.129.95.163 [4 ports]
Completed Ping Scan at 20:56, 0.06s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 20:56
Scanning 10.129.95.163 [65535 ports]
Discovered open port 80/tcp on 10.129.95.163
Discovered open port 22/tcp on 10.129.95.163
Completed SYN Stealth Scan at 20:56, 9.78s elapsed (65535 total ports)
Nmap scan report for 10.129.95.163
Host is up, received echo-reply ttl 63 (0.054s latency).
Scanned at 2026-09-23 20:56:27 CEST for 10s
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 9.97 seconds
Raw packets sent: 65539 (2.884MB) | Rcvd: 65536 (2.621MB)
Reconocimiento web
wfuzz -c -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt —hc=404 -t 20 http://10.129.95.163/FUZZ
A DESTACAR:
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000016: 301 9 L 28 W 315 Ch «images«
000000090: 301 9 L 28 W 313 Ch «docs«
000000259: 301 9 L 28 W 314 Ch «admin«
whatweb http://10.129.95.163
http://10.129.95.163 [200 OK] Apache[2.4.29], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.29 (Ubuntu)], IP[10.129.95.163], PasswordField[password], Script, Title[LIBRARY - Read | Learn | Have Fun]
Creamos una cuenta he iniciamos sesión – http://10.129.73.207/
Dentro encontramos una página web de libros
Con hovering descubrimos la ruta: http://10.129.73.207/download.php?file=1 (es donde se almacenan los archivos)
Aquí, podemos subir un archivo, pero automaticamente lo cambia a .pdf
Podemos aceder a el con la ruta de los archivos donde «Book title» crea una página de descarga para ello.
Si vamos al apartado «Contact Us» encontraremos un pequeño formulario donde escribir un mensaje al administrador del sistema:
Lo que intentamos con esto, es ver si el administrador de la web esta revisando los mensajes entrantes, pero vemos que no recibimos respuestas. Lo que si vemos es su email.
Explotación web – SQL truncation.
Vamos a salir de la sesión y a intentar iniciar sesión como admin con ese correo eléctronico usando inyecciones SQL: Tras probar algunas de las básicas para hacer un bypass, no funcionan.
Conociendo el email del administrador, vamos a probar a cambiar su contraseña dando de alta el mismo email pero con espacios (A esto se le conoce como SQL truncation) , necesitaremos la ayuda de burpsuite.
Vemos que funciona y efectivamente cambia la contraseña ¿En que consiste el SQL truncation?
Originalmente proviene de una mala configuración a la hora de establecer un límite de caracteres.
Digamos que lo que hace primero es comprobar lo que hemos introducido:
admin@book.htb+++++++++++++++++. ¿El mail es diferente a admin@book.htb? OK LO REGISTO → ¿Excede el limite de x caracteres? admin@book.htb+++++++++++++++++. SI
Pues me quedo solo hasta el valor que me corresponda y el resto lo quito. Y los + representan espacios en blanco, es como una especie de URL encode con el %20. Al ser un espacio blanco dentro de la base de datos, no lo representa por lo cual nos quedariamos solo con el mail. Y aqui es donde sucede la magia.
Iniciamos sesión en /admin con el mail del administrador admin@book.htb (recordemos que el SQL truncation lo que hace es eliminar los espacios y los sobrantes. Y la contraseña que hemos establecido admin123
Dynamic PDF.
Después de investigar un rato, lo único interesante que veo es el apartado «collections» donde los usuarios pueden a traves de un nombre, titulo y archivo, subir sus publicaciones y desde al administrador podemos revisarlo con un PDF
En el directorio /root encontrarás la flag final.
Mi primera máquina resuelta después de dos años y prácticamente reutilizando apuntes de hace años… Hay que seguir cogiendo experiencia, soltarse cada vez más e ir aprendiendo lo máximo posible.
Gracias por leer el artículo 😉
Al parecer el administrador cuenta con un PDF dinamico que la página web le deja descargar cada vez que alguien sube un nuevo registro, por lo que intentemos abusar el input del usuario que sube el contenido.
Primera prueba html y xss inyection:
Resultado:
Esto me da a entender que esta interpretando las etiquetas, incluso la del XSS, aunque no me quiera mostrar el alert, podriamos estar ante un caso OOB. Aclarar que los archivos que subamos automaticamente se suben en formato PDF, por ahora vamos a probar otras cosas.
Buscando algun payload para «dynamic PDF» encontré el siguiente recurso: https://hacktricks.wiki/en/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.html?highlight=dynamic%20pdf#server-side-xss-dynamic-pdf-1
Vamos a probar el primer bloque:
Como vemos nos devuelve el etc/passwd en base64 , pero al parecer nos da como la cadena incompleta, el propio script que funciona si eliminamos lo de «btoa» que es para representar la cadena de texto en vase64, nos dejaría ver el /ect/passwd en el propio PDF
<script> x=new XMLHttpRequest; x.onload=function(){document.write(this.responseText)}; x.open(«GET»,»file:///etc/passwd«);x.send(); </script>
Genial, vemos que hay un usuario llamado, reader, lo primero que se me ocurre ya que aparentemente solo podemos leer archivos, es listar su id_rsa que por defecto, debeía ser: /home/reader/.ssh/id_rsa
Efectivamente funciona. Pero el problema es que el output esta mal representado, falta algún carácter por culpa del formato PDF, además de los saltos de línea que no son correctos. Lo importante es que el archivo existe y ya tenemos una forma potencial de acceso al sistema.
ASí que, con el uso de etiquetas pre formateadas, vamos a intentar sanitizar el output de este archivo.
<script> x=new XMLHttpRequest; x.onload=function(){document.write(«<pre>» +this.responseText+»</pre>»)}; x.open(«GET»,»file:///home/reader/.ssh/id_rsa«);x.send(); </script>
Simplemente sustituimos la parte del btoa por <pre> , para que en vez de base 64 sea en etiquetas preformateadas. Ahora sí conseguirmos ver bien la id_rsa y acceder al usuario vía SSH. (recordad dar permisos 600 al archivo id_rsa)
Ya tenemos la flag de usuario – vamos a por root.
Escalación de privilegios
En la escalación de privilegios, siempre acostumbro a realizar un checklist personal el cual voy aumentando conforme mi experiencia, siempre empiezo viendo los permisos de /etc/passwd , viendo el /home del usuario, viendo su $PATH, viendo su id, grupos a los que pertenece, pruebo a convertirme en root…
Dependiendo del resultado, empiezo a buscar fallos en la configuración del sistema o algo de lo que pueda aprovecharme. Siempre de más fácil a más dificil y uno de esos checkeos es revisar tareas y procesos, donde con /etc/crontab no vamos a encontrar nada pero con PSPY si.
Vemos que hay un binario que se repite mucho, llamado «logrotate» ek cual guarda algo en root, lo cual significa que el usuario que esta ejecutando ese binario es root. Vamos a ver que es logrotate.
En pocas palabras es un binario el cual evita que los logs llenen el espacio del disco, para más información recomiendo leer los primeros puntos de este articulo: https://eltallerdelbit.com/logrotate-linux-rotacion-de-logs/
Además de esto, a primeras lo que se me ocurre es revisar la carpeta backups/logs que hay en el propio /home del usuario reader.
Desconozco si esto tendra relación pero vamos a buscar en internet si existe alguna vulnerabilidad con logrotate y podemos aprovecharnos de ello.
En internet encontre que esta versión de logrotate era vulnerable: https://github.com/whotwagner/logrotten
Al final es relativamente sencillo explotarla, pero a mi personalmente no me ha funcionado el payload que viene por defecto (la reverse shell) así lo modifique para cambiar los permisos de la /bin/bash , para mi, siempre que podamos ejecutar un comando como root en una escalada de privilegios… Personalemente lo ideal es cambiar la /bin/bash con permisos SUID y así en la misma sesión SSH podemos tener root.
Descargamos el archivo, lo pasamos a la máquina víctima y lo ejecutamos como viene en la descripción de github.
Por cierto, importante que envíeis algun input al propio archivo log, yo estuve esperando un rato, pensando que el equipo actualizaba ese log solo, pero no lo hace. Abrís otra ventana, os conectáis con ssh y hacéis un echo «hola» > access.log y listo.
Como siempre, muchas gracias por leer este articulo, espero que hayáis aprendido algo nuevo, cualquier duda me contactáis, un abrazo.
