Содержание статьи
Во второй половине 2023 года команда Positive Technologies по расследованию инцидентов PT CSIRT (PT Expert Security Center) разбирала происшествие в инфраструктуре одного из своих заказчиков. Специалисты пришли к выводу, что за случившимся стоят представители хакерской группировки Twelve. Группа позиционирует себя как хактивистов политической направленности и выбирает себе цели среди российских компаний и учреждений. Считается, что эта группа тесно связана с группировкой Shadow, сменившей название сначала на C0met, а с недавних пор, вероятно, скрывающейся под именем Darkstar.
Судя по схожему почерку и инструментарию, эти две группировки являются частью одной команды и отвечают за разные направления. Обе используют в ходе атак различные варианты шифровальщиков, преимущественно семейства LockBit/Babuk. Но если хакеры из Shadow занимаются вымогательством, назначая выкуп за ключ дешифровки, то представители Twelve просто стремятся нанести максимальный ущерб целевой инфраструктуре, при этом публикуя в открытом доступе результаты своей работы, которые иногда включают в себя выгруженные из инфраструктуры чувствительные данные.
Инцидент
В ходе расследования инцидента специалисты обнаружили очень подозрительный исполняемый файл с именем twelve.
. Его анализ показал, что вместо привычного LockBit злоумышленники использовали шифровальщик, относящийся к семейству программ‑вымогателей Ryuk / Chaos / Yashma / Obsidian ORB, который использовался во множестве вредоносных кампаний по всему миру.
![1,4 тысячи загруженных вредоносных семплов chaos ransomware на VirusTotal 1,4 тысячи загруженных вредоносных семплов chaos ransomware на VirusTotal](https://static.xakep.ru/images/f0efae741c5f69f69a3c2cb31069b018/35381/1.png)
Судя по ряду признаков, для генерации вредоносного файла, скорее всего, использовался публично доступный конструктор Chaos Ransomware Builder, который позволяет злоумышленникам кастомизировать вредоносные программы‑шифровальщики. С его помощью, например, можно изменить имя процесса, имя файла с требованиями, текст самих требований, задать список расширений шифруемых файлов, сбилдить декриптор и так далее.
![Интерфейс Chaos Ransomware Builder Интерфейс Chaos Ransomware Builder](https://static.xakep.ru/images/f0efae741c5f69f69a3c2cb31069b018/35382/2.png)
Сам троян написан на .NET, благодаря чему можно изучить его функции, например в DNSpy.
![Список функций шифровальщика Список функций шифровальщика](https://static.xakep.ru/images/f0efae741c5f69f69a3c2cb31069b018/35383/3.png)
Пробежавшись по основным функциям, исследователи выяснили, что этот энкодер шифрует файлы с использованием алгоритма AES, затем зашифровывает ключи AES встроенным открытым RSA-ключом и записывает их в конец зашифрованных файлов.
Публичный RSA-ключ
Для каждого шифруемого файла троян генерирует индивидуальный AES-ключ:
string text = Program.CreatePassword(40); // Генерация ключа AESif (fileInfo.Length < (long)((ulong)-1926258176)) // Проверка размера файла{ if (Program.checkDirContains(files[i])) { string keyRSA = Program.RSA_Encrypt(text, Program.rsaKey()); // Шифрование AES-ключа публичным RSA-ключом Program.AES_Encrypt(files[i], text, keyRSA); // Шифрование файлов }}
В первую очередь было интересно понять, каким образом генерируется ключ для AES. Функция генерации ключа выглядит следующим образом:
public static string CreatePassword(int length) { StringBuilder stringBuilder = new StringBuilder(); Random random = new Random(); while (0 < length--) { stringBuilder.Append("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/"[random.Next("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/".Length)]); } return stringBuilder.ToString(); }
Ключ генерируется отдельно для каждого файла на основе функции Random
, при этом Random
запускается без сида. Если в DNSpy перейти в объявление класса Random
, то мы увидим следующее.
![](https://static.xakep.ru/images/f0efae741c5f69f69a3c2cb31069b018/35384/4.png)
То есть Random
, вызванный без сида, в качестве начального использует значение Environment.
. Важно отметить, что это справедливо для приложений .NET версии 4, генерация рандома для версий 5 и выше использует другие начальные значения.
Environment.
— это количество миллисекунд, прошедших с момента запуска системы. Таким образом, можно предположить, что, зная значение сида, мы в состоянии «угадывать» случайные значения.
Проверим наши предположения. Возьмем функцию CreatePassword
из вредоноса, добавим туда вывод текущего значения Environment.
и сгенерированного пароля, а затем выведем полученные значения в консоль:
using System;using System.Text;namespace test1{ class Program { static void Main(string[] args) { string s = CreatePassword(40); Console.WriteLine("Key: " + s); } public static string CreatePassword(int length) { StringBuilder stringBuilder = new StringBuilder(); Random random = new Random(); while (0 < length--) { stringBuilder.Append("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/"[random.Next("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/".Length)]); } Console.WriteLine("Environment.TickCount: " + Environment.TickCount); return stringBuilder.ToString(); }}}
В результате запуска программы получаем следующие значения:
C:\temp>1.exe
Environment.TickCount: 264152453
Key: &Cer88Tf8sErkcxYAgR5CvdawGij/JqSEVOln8m/
Теперь организуем добавление сида в функцию генерации ключа и передадим туда значения TickCount
из предыдущего запуска:
static void Main(string[] args) { int seed = 264152453; string s = CreatePassword(40,seed); Console.WriteLine("Key: " + s); } public static string CreatePassword(int length,int seed) { StringBuilder stringBuilder = new StringBuilder(); Random random = new Random(seed); while (0 < length--) { stringBuilder.Append("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/"[random.Next("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/".Length)]); } return stringBuilder.ToString(); }
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»