
В конце апреля команда безопасности Microsoft зафиксировала компрометацию пакета mistralai версии 2.4.6 в репозитории PyPI — главном хранилище библиотек для Python. Именно оттуда миллионы разработчиков каждый день берут готовые библиотеки для своих проектов — одной командой в терминале. Злоумышленники внедрили вредоносный код прямо в файл mistralai/client/__init__.py — это стартовая точка библиотеки, которая запускается в момент подключения пакета к проекту. То есть достаточно написать import mistralai — и машина уже скомпрометирована.
Технически сразу после импорта код тайно обращается к адресу 83.142.209.194 и скачивает файл transformers.pyz во временную папку /tmp/. Название выбрано намеренно: transformers — это широко известная библиотека от Hugging Face, которую используют почти все ML-разработчики. Случайный администратор в логах ничего подозрительного не заметит. Следом запускается второй этап — основная нагрузка, которая собирает данные для авторизации: токены, ключи, переменные среды, сохраненные сессии.
Перед тем как начать работу, вредонос проверяет язык операционной системы. Если Linux настроен на русский — процесс завершается без каких-либо действий. Это не случайность, так как хакерские группы из СНГ давно придерживаются негласного правила: не трогать пользователей в странах бывшего СССР. Причина сугубо прагматичная — атаки на «своих» привлекают внимание местных силовых структур, а это прямой риск для авторов. Поэтому проверка языка системы стала стандартным элементом в арсенале русскоязычных киберпреступников.

Для систем, которые вирус геолоцирует как израильские или иранские, предусмотрен отдельный сценарий. С вероятностью один к шести запускается команда rm -rf /. Она рекурсивно и без предупреждения удаляет все содержимое корневой файловой системы. Восстановить данные после этого крайне сложно, а чаще — невозможно. Вероятность один к шести прописана: в коде буквально стоит случайное число от 1 до 6, и только при одном конкретном результате удаление не срабатывает.
Если в проектах есть mistralai, нужно немедленно проверить версию пакета. Зараженной является 2.4.6 — ее следует удалить и обновиться. Дальше — заблокировать IP-адрес 83.142.209.194 на уровне сети и проверить файловую систему на наличие /tmp/transformers.pyz, файла pgmonitor.py и службы pgsql-monitor.service. Все токены и ключи, которые были активны на затронутых машинах, нужно отозвать и перевыпустить. Изолированные Linux-хосты стоит не возвращать в работу до полной проверки.
Также недавно писали, что врачи впервые поставили диагноз зависимости от ИИ. Подробности в статье.
<div class="mediaPollEmbed" data-prerendered><noscript><section><h2>Куда уходит экранное время: что россияне чаще всего делают в смартфоне</h2><p>7 вопросов</p><form method="POST" action="https://media-poll.mail.ru/api/f7bc6674-cad0-5dec-b90d-feb273350ee9"><fieldset><legend>Сколько активного экранного времени на смартфоне у вас обычно набирается за день?</legend><label><input type="radio" name="26686" value="94329"/>1–2 часа</label><br/><label><input type="radio" name="26686" value="94330"/>3–4 часа</label><br/><label><input type="radio" name="26686" value="94331"/>5–6 часов</label><br/><label><input type="radio" name="26686" value="94332"/>Больше 6 часов</label><br/><label><input type="radio" name="26686" value="94333"/>Не отслеживаю экранное время</label><br/></fieldset><button type="submit">Далее</button></form></section></noscript></div><script type="text/javascript">(function(window){var mediaPoll=(window.mediaPoll=window.mediaPoll||{});var container=document.currentScript.previousElementSibling;var uuid="f7bc6674-cad0-5dec-b90d-feb273350ee9";mediaPoll.loadAPIPromise=mediaPoll.loadAPIPromise||new Promise((resolve,reject)=>{const loadScript=(onload,onerror)=>{var head=document.getElementsByTagName('head')[0];var script=document.createElement('script');script.async=true;script.onload=onload;script.onerror=onerror;script.src='https://media-poll.mail.ru/-/1778677839930/embed/main.js';head.appendChild(script)};loadScript(resolve,()=>{mediaPoll.loadAPIPromise=null;reject()})});mediaPoll.loadAPIPromise.then(()=>{window.mediaPoll.render(uuid,container)})})(window)</script>