HackTheBox / máquina retirada
Searcher
Cadena de cuatro descuidos encadenados: una librería desactualizada con eval() inseguro, un parámetro sin validar, credenciales en un .git/config y un script sudo que invoca por ruta relativa.
- SO
- Linux (Ubuntu)
- dificultad
- Easy
- puertos
- 22 · 80
- publicado
- Flask
- eval injection
- RCE
- credential reuse
- git leak
- sudo
- path hijacking
- Docker
Aviso. Contenido educativo sobre una máquina retirada de HackTheBox. Se explica el concepto de cada vector, sin credenciales reales ni payloads listos para copiar y pegar.
Searcher no se gana con un exploit espectacular, sino encadenando descuidos pequeños hasta llegar al control total del sistema. No fue magia: fue método. Esa es, para mí, la lección más valiosa de la máquina.
Reconocimiento — Leer lo que el servidor te regala
Nmap mostraba solo dos puertos abiertos. El servidor web corría Apache, pero por
debajo asomaba Werkzeug/Python — la firma inequívoca de una aplicación Flask.
80/tcp open http Apache httpd 2.4.52 (Ubuntu)
└─ Werkzeug/2.1.2 Python/3.10.6
La aplicación era un buscador. Y en el pie de página, la propia web confesaba su stack: «Powered by Flask and Searchor 2.4.0». Nombre y versión exacta del componente, servidos en bandeja.
Lección. El fingerprinting no siempre necesita herramientas sofisticadas. A veces el componente vulnerable y su versión están escritos en el footer. Leer antes de atacar.
Foothold — Cuando una librería evalúa tu input
Searchor 2.4.0 arrastraba una vulnerabilidad conocida: construía las URLs de
búsqueda usando eval() de forma insegura. Si tu entrada llega a un eval()…
llega a ejecución de código.
El detalle interesante es que la aplicación validaba el parámetro engine
contra una lista cerrada, pero el parámetro query era terreno libre. Inyectando
en el parámetro correcto se conseguía ejecución remota de comandos y, de ahí, una
reverse shell.
Lección.
eval()sobre input de usuario es uno de los antipatrones más peligrosos del desarrollo. Y nunca asumas que todos los parámetros de una petición se validan por igual: basta uno que se escape del filtro.
Movimiento lateral — Los secretos viven en los sitios más tontos
Ya dentro, apareció un repositorio git en el directorio de la aplicación. El
fichero .git/config guardaba la URL del remoto… con las credenciales
incrustadas en texto plano:
[remote "origin"]
url = http://usuario:contraseña@gitea.searcher.htb/…
Esa contraseña estaba reutilizada por el usuario del sistema. Un salto de usuario prácticamente regalado.
Lección. La reutilización de credenciales sigue siendo una de las vías de ataque más efectivas del mundo real. Y los repositorios git filtran secretos constantemente:
.git/config, el historial de commits, objetos sueltos.
Escalada a root — El peligro de las rutas relativas
El usuario podía ejecutar un script de Python como root vía sudo. Ese script,
entre sus funciones, invocaba a otro script (full-checkup.sh) usando una
ruta relativa en lugar de una ruta absoluta.
La consecuencia: creando un full-checkup.sh propio en un directorio con permisos
de escritura, y lanzando el comando desde ahí, el script privilegiado ejecutaba
mi código… como root.
$ cd /tmp && echo 'chmod u+s /bin/bash' > full-checkup.sh
$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup
uid=0(root) gid=0(root) groups=0(root)
Lección. Cualquier programa privilegiado debe invocar binarios y scripts con rutas absolutas. Una ruta relativa ejecutada en contexto root es una invitación abierta a la escalada de privilegios.
Reflexión final
| Fase | Vector |
|---|---|
| Recon | Apache + Werkzeug/Flask + Searchor 2.4.0 (revelado en el footer) |
| Foothold | eval() inseguro en Searchor 2.4.0 → RCE |
| User | Credenciales en .git/config → reutilizadas por el usuario del sistema |
| Root | sudo sobre script Python → path hijacking por ruta relativa |
Cuatro descuidos que por separado parecen menores — librería desactualizada, validación incompleta, secreto en texto plano, ruta relativa — se suman hasta el compromiso total. Así funcionan los compromisos reales: no hay una bala de plata, hay la acumulación de pequeños fallos.
Cada máquina me recuerda por qué la seguridad es ofensiva y defensiva a la vez: entender cómo se rompe algo es el primer paso para saber protegerlo.