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
cve-2026-85706 — PoC de exploit en Python para CVE-2026-85706, una lectura arbitraria de archivos no autenticada en GitLab CE/EE mediante el bypass de codificación de rutas de Workhorse, con writeup y variantes de bypass. | Kitploit
Herramientas/GitHubGitHub/guneykabel/cve-2026-85706
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebRecopilación de InformaciónVirtualización de SeguridadSeguridad WebPruebas de Penetración
GitHubguneykabel/cve-2026-85706

cve-2026-85706

PoC de exploit en Python para CVE-2026-85706, una lectura arbitraria de archivos no autenticada en GitLab CE/EE mediante el bypass de codificación de rutas de Workhorse, con writeup y variantes de bypass.

Ver Repositorio
4hace 12h 9mAú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 →
Compartir

cve-2026-85706

Lectura arbitraria de archivos locales sin autenticación en GitLab CE/EE. Afecta a 18.7–19.1.7, 19.2.0–19.2.5, 19.3.0–19.3.1. Corregido en 19.1.8 / 19.2.6 / 19.3.2 (2026-09-10). CVSS 10.0, presuntamente explotado en la naturaleza. Informe original de s3ntago y este repositorio es solo mi writeup + PoC.

disclaimer

Esta PoC se publica únicamente con fines educativos y de investigación defensiva, para ayudar a administradores e investigadores a comprender y probar la vulnerabilidad. Ejecútala exclusivamente contra sistemas que poseas o para los que tengas autorización escrita explícita de prueba. Si tu instancia está dentro del rango afectado, deja de leer y aplica el parche a 19.1.8 / 19.2.6 / 19.3.2 primero.

cómo funciona

Tres endpoints de repositorio (POST :id/repository/commits, POST/PUT :id/repository/files/:file_path) están detrás del requestBodyUploader de Workhorse. El handler de Rails lee la ruta en disco directamente del campo crudo file.path de la petición y hace File.open sobre ella antes de cualquier autenticación. no sirve como autenticación porque el signing round-tripper de Workhorse adjunta un JWT válido a cada petición que proxya, así que cualquier cosa que llegue al proxy genérico de la API pasa esa comprobación.

require_gitlab_workhorse!
Gitlab-Workhorse-Api-Request

La única razón por la que esto no es un LFI instantáneo para todo el mundo es que se supone que Workhorse reescribe la petición primero. Pero su regex de rutas coincide contra la ruta escapada (EscapedPath() más un clon con path.Clean que nunca decodifica %XX), mientras que Puma decodifica %XX antes del enrutado de Grape. Así que percent-encodea cualquier carácter de un segmento estático (%63ommits, %72epository, %66iles), añade una barra final, o pega .json que la regex de Workhorse no detecta, y Rails sigue enrutando al handler vulnerable. Ese desajuste de codificación es donde reside el bypass. (Variantes como //, /./, %2F, ; no funcionan porque path.Clean normaliza las dos primeras y Puma rechaza %2F.)

Luego solo hay que enviar metadatos de subida falsificados sin firmar como parámetros de query:

root@kitploit:~
POST /api/v4/projects/1/repository/%63ommits?file=&file.path=<ABSOLUTE_PATH>&file.size=1&Content-Type=application/x-www-form-urlencoded

file= en blanco satisface la validación requires :file, WorkhorseFile (en blanco coacciona a nil). La lectura se dispara antes de la autenticación. Recuperar los bytes de vuelta es la parte divertida: en la rama urlencoded el helper ejecuta Rack::Utils.parse_nested_query(File.read(path)) e interpola los errores del parser en el cuerpo del 400. Cualquier % no seguido de dos dígitos hexadecimales lanza InvalidParameterError: invalid %-encoding (<raw file bytes>) y el contenido del archivo vuelve dentro del mensaje de error. La rama JSON (Oj) no filtra nada, por eso el content type urlencoded importa aquí.

El fix (master 0d9ce3e7, backports 1fe30154 / b43c8b26 / 0ff7b6b2) añade authenticate! a los tres endpoints más el pre-paso /authorize, confía solo en el UploadedFile producido por el middleware para ruta/tamaño, y deja de hacer eco de los errores del parser. El bug se introdujo en diciembre de 2025, por eso el rango afectado empieza en 18.7.

uso

root@kitploit:~
./exploit.py --url http://localhost:8080 --file /etc/hostname
./exploit.py --url http://localhost:8080 --file /opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml

El script recorre todas las formas de bypass verificadas (segmentos codificados, barra final, .json; endpoints commits + files, POST y PUT) y clasifica cada respuesta para que puedas saber en qué punto de la cadena murió una prueba. Solo objetivos autorizados, obviamente.

fallos / limitaciones / precondiciones

  • El eco solo se dispara si el archivo contiene un % no seguido de dos caracteres hexadecimales.
  • La regex de fuga es greedy ((.*) hasta el último ) en el cuerpo). Bien contra el error JSON estándar, sobrecapturará si algo delante envuelve la respuesta en HTML. El fix adecuado es parsear el campo message del JSON.
  • La API de commits necesita un id de proyecto legible anónimamente (el bloque before da 404 en caso contrario).

referencias

  • commit del fix (master): https://gitlab.com/gitlab-org/gitlab/-/commit/0d9ce3e758a85f0690be751e213625f7902c0361
  • notas de la versión parche: https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-3-2-released/
  • writeup: https://securityonline.info/gitlab-vulnerabilities-cve-2026-85706-cvss-10/
Descargar herramienta