Бэкдор в предложении о работе на LinkedIn

Кибератаки — теперь даже в переписке с эйчарами. В этой статье-переводе — кейс-предостережение о здоровой паранойе, осторожном поиске вредоноса и двойной (!) краже личности.

Обложка: Бэкдор в предложении о работе на LinkedIn

От переводчика: это перевод статьи Романа Иманкулова “A backdoor in a LinkedIn job offer”. Автор рассказывает, как чуть не стал жертвой атаки, о которой до этого знал только понаслышке, и показывает, как ему удалось найти хитро замаскированный бэкдор среди на первый взгляд безобидных тестов.

На прошлой неделе мне в личку на LinkedIn постучалась рекрутер из небольшого криптостартапа. Мы пообщались пару дней; она рассказала о неработающем прототипе, для которого им нужен ведущий разработчик, и прислала ссылку на публичный GitHub-репозиторий для ревью. А именно, попросила «посмотреть проблему с устаревшими модулями Node».

В просьбе посмотреть существующий код нет ничего странного, но что-то мне не давало покоя, и я решил подстраховаться.

Вместо клонирования репозитория и локальной установки зависимостей я запустил временный VPS на Hetzner, склонировал проект туда и дал доступ к нему ИИ-ассистенту Pi в режиме «только чтение», активировав исключительно инструменты для чтения файлов:

			pi --tools read,grep,find,ls
		

Попросил агента пробежаться по коду и подсветить все подозрительные моменты. Он почти сразу же споткнулся о файл app/test/index.js.

Бэкдор

Проект выглядел как типичное приложение с фронтендом на React и бэкендом на Node. Западня пряталась в файле app/test/index.js — примерно 250 строк кода, оформленных под тесты. Внутри этого файла URL-адрес собирался по частям:

			const protocol = "https",
  domain = "store",
  separator = "://",
  path = "/icons/",
  token = "77",
  subdomain = "rest-icon-handler",
  bearrtoken = "logo";
		

В итоге получалась ссылка https://rest-icon-handler.store/icons/77.

А дальше, прямо посреди кучи закомментированных тестов, лежал загрузчик, который запускал всё, что прилетало обратно от сервера.

Бэкдор в предложении о работе на LinkedIn_12
Вредоносный код на строке 225, спрятанный у всех на виду среди закомментированных тестов.

Механизм запуска

Файлу даже не нужно, чтобы вы запускали тесты. В самом app/index.js вызывается const test = require('./test'), который подгружает и выполняет app/test/index.js.

В package.json запуск app/index.js вшит прямо в инициализацию проекта:

Бэкдор в предложении о работе на LinkedIn_16
Скрипт prepare вызывает app:pre, который запускает команду node app/index.js.

Главная деталь здесь — скрипт prepare. npm запускает его автоматически сразу после завершения npm install, так что для активации бэкдора достаточно просто установить зависимости.

Просьба «разобраться с устаревшими модулями Node» была всего лишь приманкой с целью вынудить меня запустить npm install.

В принципе, можно было дать вредоносному коду запуститься в песочнице и посмотреть, что сервер пришлёт на втором этапе атаки, но я решил на этом остановиться. Хватило и того факта, что репозиторий выполняет всё, что ему присылает сторонний сервер.

Кража личности

Коммиты в репозитории были сделаны от имени реального разработчика — фулстек-инженера с обычным профилем в LinkedIn, личным сайтом и давней историей на GitHub. Я написал ему, притворившись, что унаследовал кодовую базу и у меня есть пара вопросов по ней, чтобы посмотреть, как он отреагирует.

Он сказал, что никогда с этими людьми не работал. Его личность уже использовали на GitHub для создания фейков, из-за чего один из репозиториев заблокировали, и к этой кодовой базе он не имеет никакого отношения. Он также подавал жалобы на эти проекты.

Бэкдор в предложении о работе на LinkedIn_23
Вся история изменений из 39 коммитов приписана разработчику, который никогда не работал с этим репозиторием.

Вторая украденная личность

Профиль рекрутера принадлежал реальной журналистке, довольно известной в области культуры и никак не связанной с технологиями. Когда я схитрил и сообщил, что по какой-то причине у меня не получается установить проект, журналистка моментально превратилась в знатока npm и версий Node. Это выглядело весьма забавно.

Бэкдор в предложении о работе на LinkedIn_26
Далёкий от ИТ рекрутер вдруг начинает рассуждать о версиях Node и активно уговаривает меня запустить npm install.

Это может случиться с каждым

Я знал о таких атаках, но она всё равно застала меня врасплох. Какие-то подозрения появились с первых же сообщений, но будь я более уставшим или если бы я куда-то спешил, то запросто мог бы на автомате запустить npm install. Так что если вам пишут в LinkedIn с предложением посмотреть репозиторий, чуточка паранойи и правила цифровой гигиены точно не повредят.

Ещё один важный урок: проверять код с помощью ИИ-ассистента в режиме «только чтение» оказалось эффективнее, чем разбираться во всём самому. Бэкдор замаскировали под небрежный код начинающего разработчика, но агент обнаружил его за секунды.

Я отправил жалобы на репозиторий в GitHub и на профиль рекрутера в LinkedIn. Пока ничего не изменилось, код всё ещё висит в открытом доступе.

Рекомендуем