Наверное, каждый из тех, кто читает эту статью, хорошо знаком с GitHub — крупнейшим веб-сервисом для хостинга IT-проектов и их совместной разработки. Здесь можно найти почти любой open source-проект. Для компиляции проекта может быть нужен какой-то специфический софт, которого прямо сейчас у пользователя нет, да и сам процесс сборки из исходников требует определенных знаний и опыта. Понимая это, разработчики, помимо исходного кода, очень часто размещают на гите готовые бинарные файлы. Илья Померанцев, специалист по анализу вредоносного кода CERT Group-IB, на примере реального кейса показывает, как использованием непроверенного чужого кода может привести к потере криптовалюты.
Началась эта история с того, что наш клиент загрузил исполняемый файл с одного из доменов GitHub — raw.githubusercontent.com. Наша система TDS Polygon признала объект вредоносным, и он был передан аналитикам.
Источник загрузки — GitHub пользователя под ником faca5. Изучение исходного кода проекта BitTXGenerator, генератора поддельных биткоин-транзакций, не дало никаких результатов. Во всех файлах автором числится некто bunkdeath, датой разработки указан 2010 год, в названиях файлов часто фигурирует DBMS, при этом нет никаких упоминаний про биткоин и криптовалюту.
По имеющимся данным легко найти оригинальный репозиторий и описание оригинального проекта.
Впоследствии нам удалось найти демонстрационное видео автора с использованием BitTXGenerator. Его выложил пользователь под ником Herbert Grun. Интерес привлек кадр, где можно рассмотреть открытые окна автора, в числе которых есть ArtMoney.
Это достаточно известная программа для модификации параметров компьютерных игр. Например, для получения бесконечных виртуальных денег. Это порождает сомнения, действительно ли приложение Electrum отображает реальный баланс кошелька.
Анализ файла
Перейдем к анализу самого сэмпла. Из поведенческих маркеров стало ясно, что перед нами самораспаковывающийся архив, внутри которого находится откомпилированный AutoIt-скрипт:
Анализ в DIE подтвердил эту догадку:
Далее следует обратить внимание на дерево процессов. Мы видим, что файл PXCeHZSXMe.exe, который лежал внутри sfx-архива BitTXGenerator1.2.1.exe, дропнет и запустит скрипт eVMcf.au3, который можно найти среди созданных файлов:
Распаковка
Стадия 1
После декомпиляции и последующей деобфускации PXCeHZSXMe.exe перед нами оказывается незамысловатый AutoIt-скрипт, который извлекает полезную нагрузку из секции ресурсов и сохраняет ее на диск, чтобы потом запустить.
Исполнение начинается с поиска открытых окон антивируса Касперского и Avast. Если они есть, то ВПО засыпает на 20 и 30 секунд соответственно. Видимо, пытается обойти антивирус, но поскольку он таким образом его не обойдет — логика этого действия абсолютно непонятна. Также интересна функция декодирования Base64-строк.
Для этой операции автор решил прибегнуть к помощи Shellcode. Еще одно лишенное логики действие, ведь подобную функцию можно легко реализовать на AutoIt:
В секции ресурсов в закодированном виде хранятся три файла:
- Исполняемый файл AutoIt. Служит для запуска скрипта (HLTH.exe)
- AutoIt-скрипт, содержащий вредоносную функциональность (eVMcf.au3)
- Текстовый файл с именами файлов, в которые будут сохранены AutoIt-скрипт и исполняемый файл AutoIt
Перейдем к анализу второй стадии распаковки, реализованной с помощью eVMcf.au3.
Стадия 2
Выполнение скрипта начинается с поиска виртуальной среды, а также открытого диалогового окна Avast. Почему на этот раз диалоговое окно антивируса Касперского перестало пугать автора ВПО — навсегда останется загадкой.
Интересно, каким образом малвара уходит «в спячку». Вернее, то, каким образом она проверяет, что эта «спячка» действительно была. Дело в том, что многие «глупые» песочницы осуществляют перемотку времени. То есть при попытке вызвать WinAPI-функцию Sleep песочница пропускает его, сразу же возвращая управление обратно в поток ВПО. Это отличный индикатор для ее обнаружения. Достаточно взять разницу между системным временем до системного вызова и после него. Однако то, как этот механизм реализован в нашем сэмпле, опять вызывает много вопросов.
Дело в том, что WinAPI-функция GetTickCount возвращает время в миллисекундах, то есть очень точно. Даже если бы код был изначально написан на языке ассемблера, а оптимизация была максимальной — разница во времени никогда бы не была строго равна времени «спячки». Мы же имеем дело с интерпретируемым языком. Это попросту не имеет никакого смысла.
Далее следует опциональная проверка на повторный запуск. Реализована через проверку существования именованного семафора.
Сама полезная нагрузка хранится последней строкой в виде AutoIt-комментария и закодирована при помощи Base64.
Функция декодирования абсолютно аналогична той, что использовалась на первом этапе. Это позволяет предположить, что у обоих скриптов идентичный автор.
Возможно хранение одной или двух полезных нагрузок. Поддерживается инжект в процесс RegSvcs и wscript. Есть поддержка x86 и x64. Опционально возможна обработка пейлоада как batch-скрипта с сохранением его в файл для последующего запуска.
Сама функция инжекта вновь вызывает ряд вопросов. Во всех загрузчиках на AutoIt, которые нам известны, инжект выполняется с помощью Shellcode. В этом же случае вся процедура встраивания в чужой процесс реализована непосредственно на AutoIt. Это вдвойне странно, если вспомнить, как реализовано декодирование Base64.
Стадия 3
После декодирования комментария мы получили два новых исполняемых файла. Первый из них является sfx-архивом. Его оставим на потом.
Второй — это приложение, написанное на Delphi. Главная форма соответствует интерфейсу рекламированного автором софта.
При клике на кнопку Generate Transaction выводится текст Status: Generating Transaction. Затем запускается таймер, по истечении которого появляется один из 16 заготовленных текстов.
Кнопка Broadcast Transaction выведет Status: Broadcasting to all peers и тоже запустит таймер. По итогу будет просто выведена надпись Status: Broadcast successful.
Есть еще несколько таймеров, которые с разной периодичностью выводят захардкоженную информацию о якобы подключенных пирах.
По итогу оказывается, что обещанная автором функциональность — просто фейк.
А теперь зададимся вопросом, зачем же было так пиарить софт, который ничего не делает?
Вот тут мы и вспоминаем про первый файл.
Кое-что он всё-таки делает...
Процедура распаковки аналогична той, что была проведена с исходным файлом. По итогу перед нами оказалось еще одно приложение на Delphi. Главная форма содержит в себе элемент TMemo, большое количество таймеров, которые не имеют обработчиков, и обработчик события onCreate для самой формы.
При создании формы модуль устанавливает перехватчик для буфера обмена. Когда появляется новое содержимое, оно проверяется на соответствие биткоин-кошельку. Если соответствие обнаружено, то содержимое заменяется на кошелек из списка TMemo. То есть происходит подмена адреса кошелька.
Для первого кошелька мы нашли информацию о двух входящих транзакциях на общую сумму $775 (приблизительно 50 000 рублей). Отмечу, что мы также нашли другие экземпляры ВПО с другим набором кошельков.
Это всего лишь один из многочисленных примеров того, чем может закончиться бездумное использование чужого кода, особенно в скомпилированном виде. Да, изучение исходников может занять время, но зато это поможет сэкономить львиную долю нервов, а возможно, и денег.
teecat
Слышал звон про уязвимости с симлинками?