Эволюция шифровальщика JSWorm. Часть 1

Эволюция шифровальщика JSWorm. Часть 1

Life-Hack [Жизнь-Взлом]/Хакинг

#Обучение

В последние несколько лет ландшафт угроз, связанных с программами-шифровальщиками, постепенно меняется. От массовых эпидемий 2017 года, таких как WannaCryNotPetya и Bad Rabbit, вымогатели перешли к менее заметной, но гораздо более прибыльной тактике, которую условно можно назвать «охотой на крупную дичь». Новости о том, что атака шифровальщика вызвала сбой в работе сервисов международной корпорации, все больше становятся частью повседневной реальности. 

В некоторых случаях эта глобальная тенденция является отражением непрерывного жизненного цикла угроз: старые семейства шифровальщиков прекращают свою активность, им на смену приходят другие, которые преследуют новые цели. Однако встречаются и семейства зловредов, которые начинали с массового распространения, а затем перешли к узконаправленным целевым атакам, причем смена тактики заняла не больше пары лет. В этой статье мы расскажем об одном из таких семейств — JSWorm.

Хронология 

Шифровальщик JSWorm был обнаружен в 2019 г. В дальнейшем разные варианты этой угрозы были известны под разными названиями — NemtyNefilimOffwhite и др. 

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

На приведенной ниже схеме указаны некоторые из названий этого троянца и периоды активного распространения каждого варианта (но не дата первого обнаружения). Следует отметить, что это не полный список версий, а лишь основные этапы эволюции JSWorm.

Помимо изменения названий, разработчики перерабатывали код шифровальщика и пробовали разные способы распространения. 

В какой-то момент в 2020 г. они даже сменили язык программирования с C++ на Go и переписали код с нуля. Однако сходство в схемах шифрования и сообщениях с требованиями выкупа, а также использование злоумышленниками одного и того же сайта для публикации скомпрометированных данных позволяют нам считать, что все эти варианты зловреда — часть одной кампании. 

Исходная версия зловреда, а также некоторые из ее последующих «брендов» (например, Nemty) рекламировались на одном из хакерских форумов пользователем под псевдонимом jsworm.

Реклама ранней версии JSWorm, размещенная на форуме

Методы распространения 

С момента своего появления в 2019 г. и до первой половины 2020 г. JSWorm действовал как публичный сервис, работающий по схеме «шифровальщик как услуга» (RaaS). Было замечено распространение этого троянца с помощью: 

  • набора эксплойтов RIG;
  • ботнета Trik;
  • поддельных страниц оплаты;
  • спам-кампаний. 

В первой половине 2020 г. операторы закрыли публичный RaaS-сервис и занялись «охотой на крупную дичь». Существуют свидетельства того, что для первоначального заражения они использовали уязвимости серверного ПО (Citrix ADC) и доступ к компьютерам через незащищенный RDP. 

Технические подробности 

Рассмотрим несколько примечательных вариантов JSWorm, обнаруженных в на разных этапах развития этого семейства вредоносного ПО. Мы не будем даже пытаться описать все известные версии: их слишком много. Указанные даты обозначают приблизительный период активного распространения каждого из вариантов «в дикой природе». 

Май 2019 г. JSWorm 

MD5: a20156344fc4832ecc1b914f7de1a922 

Это образец одного из первых обнаруженных вариантов шифровальщика JSWorm. В отличие от последующих вариантов, он не содержит внутреннего номера версии. Образец написан на языке C++ и скомпилирован в MS Visual Studio. 

Помимо шифрования файлов, он выполняет еще несколько действий: например, останавливает некоторые из запущенных процессов и служб, чтобы как можно больше ценных файлов жертвы были доступны для шифрования. Кроме этого, он удаляет резервные копии системы и теневые копии, отключает режим восстановления системы и очищает журналы событий.

Схема шифрования 

Файлы шифруются с помощью кастомной модификации алгоритма Blowfish с 256-битным ключом. Ключ генерируется в начале выполнения программы на основании строки, получаемой путем конкатенации имени пользователя, MAC-адреса устройства и серийного номера тома (примеры значений приведены ниже).

Процесс генерации ключа

Затем генерируется строка, фигурирующая в сообщении с требованием выкупа как JSWORM PUBLIC KEY. Однако слово public в данном случае не имеет смысла, поскольку здесь не применяется асимметричное шифрование. То, что разработчики называют «открытым ключом», в действительности является уже упомянутым ключом алгоритма Blowfish, преобразованным посредством операции XOR со строкой KCQKCQKCQKCQ и закодированным с помощью Base64.

Операция XOR с ключом KCQKCQKCQKCQ

Вот пример вычисления такого ключа. Серийный номер тома и MAC-адрес приведены для иллюстрации. 

  • Ключ Blowfish: 53385773534FE:ED:00:DE:AF:00user
  • «Открытый ключ» после операции XOR: 5xpi~tfxvb\x05\x14q\x06\x15qsaq\x07\x14q\x02\x17qsa>049
  • «Открытый ключ» после преобразования в Base64: NXhwaX50Znh2Yn8FFHEGFXFzYXEHFHECF3FzYT4wNDk= 

Для шифрования содержимого каждого из файлов жертвы использовалась кастомная версия алгоритма Blowfish. При этом в каждом случае шифровалось не более 100 000 байт — возможно, чтобы ускорить процесс обработки больших файлов. Зашифрованные данные записывались поверх исходных. 

Разработчики изменили внутреннюю реализацию алгоритма Blowfish, сделав ее несовместимой со стандартными реализациями — возможно, чтобы усложнить работу исследователей. 

Зашифровав содержимое файла, программа переименовывает его. К имени файла добавляется дополнительное расширение .[ID-…][mail@domain.tld].JSWORM.

Недостатки схемы шифрования 

Ключ для расшифровки файлов по сути хранится в сообщении с требованием выкупа. Выполнив несложные манипуляции (декодирование Base64 и обратную операцию XOR), можно восстановить данные, не платя вымогателям. Даже если сообщение от вымогателей будет по какой-то причине утеряно, ключ на зараженной машине легко восстановить.

Июль 2019 г. JSWorm 4.0.3 

MD5: 5444336139b1b9df54e390b73349a168 

В этой обновленной и усовершенствованной версии JSWorm разработчики попытались исправить недостатки предыдущих вариантов. 

Этот образец может выполнять проверку языка системы — вероятно, для того, чтобы не допустить шифрования данных в системах, использующих русский (RU), белорусский (BE), узбекский (UZ), киргизский (KY), таджикский (TG), туркменский (TK), казахский (KK) и украинский (UK) языки.

Определение языка пользователя

При этом (вероятно, из-за ошибки разработчиков) данная версия вымогателя шифрует файлы только в русскоязычных системах. Если внимательно посмотреть на приведенный выше фрагмент кода, можно заметить, что первое условие — «!=» («не равно»). Из-за этого троянец выполняет ветку кода, которая завершает его работу без шифрования в системах, использующих отличный от русского язык. Если бы на месте этого условия стояло «==», то выполнялась бы другая ветка, соответствующая тому поведению троянца, которое, вероятно, было изначально задумано. 

Сообщение с требованием выкупа в этом варианте выглядит как HTA-файл с именем <ID>-DECRYPT.hta, где <ID> — уникальный идентификатор жертвы, присвоенный зловредом. Файл HTA запускается по завершении шифрования файлов. Зловред также добавляет его в автозапуск, прописывая в реестре значение:

  • reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v «zapiska» /d «C:\Users\user\JSWRM-DECRYPT.hta»
  • reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v «zapiska» /d «C:\Users\user\JSWRM-DECRYPT.hta»
Сообщение с требованием выкупа от JSWorm 4.0.3

Схема шифрования 

Эта версия JSWorm использует для шифрования файлов WinAPI-реализацию алгоритма RSA и кастомную реализацию алгоритма AES. JSWorm генерирует два случайных значения длиной 128 бит (вектор инициализации) и 256 бит (ключ), используя прописные и строчные буквы английского алфавита от A до Z и цифры от 0 до 9. Открытый ключ RSA встроен в код шифровальщика:

Открытый ключ, используемый в JSWorm 4.0.3

С помощью этого ключа JSWorm шифрует ключ AES и вектор инициализации, а затем кодирует их в Base64.

Шифрование с помощью WinAPI RSA в JSWorm 4.0.3

Полученное значение добавляется в файл сообщения с требованием выкупа (<ID>-DECRYPT.hta), но остается невидимым, поскольку прописывается в HTML-коде как комментарий. 

Значения в HTA-файле, содержащем сообщение с требованием выкупа

Чтобы усложнить процесс расшифровки для исследователей, разработчики зловреда применили кастомный вариант алгоритма блочного шифрования AES, несовместимый со стандартным алгоритмом. Содержимое файлов жертвы шифруется этим алгоритмом с использованием вышеописанных ключа и вектора инициализации. 

Подобно предыдущей версии, в целях оптимизации шифруются только первые 160 000 байт больших файлов. Как и в случае с предыдущим образцом, после шифрования к имени файла добавляется дополнительное расширение: <filename>.[ID-NQH1J49][doctorSune@protonmail.com].JSWRM.

Недостатки схемы шифрования 

В этом варианте JSWorm разработчики попытались исправить недостатки, найденные исследователями в предыдущих версиях. Однако расшифровка файлов без уплаты выкупа все еще возможна. Генератор псевдослучайных чисел, используемый для создания вектора инициализации и ключа, не является криптографически стойким. Анализ алгоритма генератора позволяет исследователям восстановить вектор и ключ, чтобы с их помощью расшифровать данные жертвы.

Август 2019 г. Nemty 1.4 

MD5: 1780f3a86beceb242aa81afecf6d1c01 

JSWorm и Nemty имеют существенные отличия в коде. Опираясь на результаты анализа, мы предполагаем, что разработчики полностью переписали код троянца — вероятно, чтобы исключить возможность успешной расшифровки, благодаря которой жертвы нескольких вариантов JSWorm восстановили данные без уплаты выкупа.

Этот образец, как и предыдущий, написан на языке C++ и скомпилирован в MS Visual Studio. В нем реализован несложный прием для защиты от анализа, основанный на обфускации строк. Строки (например, имя и содержимое файла с требованием выкупа, открытый ключ RSA, URL-адрес страницы для перевода денег и т. д.) зашифрованы с помощью поточного шифра RC4 с жестко прописанным ключом «fuckav» и кодированы в Base64.

Сообщение с требованием выкупа, созданное Nemty 1.4

После запуска образец собирает информацию об устройствах для хранения данных, присоединенных к зараженному компьютеру, получает его внешний IP-адрес с помощью HTTP-запроса на сайт http://api.ipify.org и определяет страну нахождения жертвы, запрашивая данные по адресу http://api.db-ip.com/v2/free/. Затем он генерирует пару сессионных ключей RSA-2048 и объединяет все собранные данные в JSON-структуре. Эта структура затем шифруется с использованием содержащегося в коде зловреда открытого ключа RSA и сохраняется в конце сообщения с требованием выкупа как NEMTY DECRYPTION KEY.

Информация о жертве, еще не зашифрованная с помощью RSA

В этой структуре представляют интерес несколько значений: 

  • isRU: уточняет, не относится ли внешний IP-адрес жертвы к одной из следующих стран: Россия, Белоруссия, Казахстан, Таджикистан, Украина;
  • version: внутренняя версия троянца;
  • CompID: уникальный идентификатор зараженного компьютера;
  • FileID: идентификатор заражения, который генерируется при каждом запуске вредоносного ПО;
  • UserID: идентификатор партнера, жестко прописанный в коде образца;
  • key: закодированный в Base64 ключ для шифрования файлов (о нем ниже);
  • pr_key: закодированный в Base64 секретный сессионный ключ RSA-2048 (о нем ниже).

Схема шифрования 

Код троянца содержит жестко прописанный открытый ключ RSA-8192, созданный злоумышленниками. Далее мы будем называть его открытым мастер-ключом RSA. 

После запуска на компьютере жертвы троянец также генерирует пару сессионных ключей RSA-2048 (секретный ключ из этой пары обозначен выше как pr_key). Кроме этого, он генерирует 256-битный ключ, который будет использоваться для применения кастомного алгоритма блочного шифрования на базе AES

256-битный ключ и pr_key шифруются с помощью открытого мастер-ключа RSA и сохраняются в сообщении с требованием выкупа. 

При шифровании очередного файла жертвы Nemty 1.4 генерирует 128-битный вектор инициализации, который затем использует вместе с 256-битным ключом, чтобы шифровать содержимое файла посредством кастомного алгоритма на базе AES. Вектор инициализации шифруется с помощью открытого сессионного ключа RSA и добавляется к зашифрованному файлу. 

Имена зашифрованных файлов меняются: к ним добавляется дополнительное расширение ._NEMTY_<…>_. На месте многоточия прописывается упомянутый выше идентификатор заражения — FileID.

Недостатки схемы шифрования 

Как и в случае с предыдущими вариантами JSWorm, реализация криптографической схемы в Nemty 1.4 небезупречна. В ней есть слабые места, которые можно использовать для расшифровки файлов: 

  1. для создания ключей используется генератор псевдослучайных чисел, который не является криптографически стойким;
  2. ключ для RSA-сессии не удаляется из системного хранилища. 

Первая уязвимость позволяет восстановить 256-битный ключ, а вторая — pr_key. Узнав pr_key, можно расшифровать вектор инициализации, а затем, с помощью 256-битного ключа и вектора инициализации, расшифровать содержимое файлов жертвы.

Связь с командным сервером 

Образец загружает Tor-клиент с адреса https://dist.torproject.org/torbrowser/8.5.4/tor-win32-0.4.0.5.zip, распаковывает его и запускает на зараженном компьютере. Через 30 секунд (очевидно, разработчики считают, что столько времени будет достаточно, чтобы установить соединение с сетью Tor) троянец отправляет информацию о заражении на командный сервер, адрес которого жестко прописан в коде образца: 

zjoxyw5mkacojk5ptn2iprkivg5clow72mjkyk5ttubzxprjjnwapkad.onion 

Nemty 1.4 отправляет HTTP-запрос GET с URI /public/gate?data= 

Данные, которые отправляются на сервер, идентичны тем, что прописываются в каждом сообщении с требованием выкупа, и по сути представляют собой зашифрованную JSON-структуру, о которой мы рассказывали выше. 

Последующие версии Nemty 

Название Nemty использовалось до марта 2020 г. Один из последних вариантов этого шифровальщика имел внутреннюю версию 3.1

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

Также стоит отметить, что разработчики этого зловреда часто добавляли в код транслитерированные строки на русском языке — возможно, чтобы привлечь внимание исследователей или просто шутки ради. Некоторые из них содержат нецензурные цитаты из рэп-текстов.

Строки из образца Nemty 2.4
Строки из образца Nemty 2.6

Продолжение следует…

Источник


Report Page