Обзор
Это мой анализ для ROOK Ransomware.
ROOK — это относительно новая программа-вымогатель, появившаяся в последние несколько месяцев. С библиотекой Mbed TLS (https://github.com/ARMmbed/mbedtls ) вредоносная программа использует схему гибридной криптографии для шифрования файлов с помощью AES и защиты своих ключей с помощью RSA-2048.
Что касается скорости выполнения, то ROOK довольно быстр, поскольку использует довольно хороший метод многопоточности с двумя глобальными списками для обхода файлов и каталогов.
Как утверждают другие исследователи, ROOK заимствует часть кода из просочившегося исходного кода BABUK. Если быть более точным, разработчики ROOK скопировали и вставили код завершения сервисов и процессов, а также удаления теневых копий. Многопоточный подход ROOK представляет собой повторную реализацию и обновление BABUK версии 3, которая теперь более эффективна для обхода каталогов.
Однако, в отличие от разработчиков BABUK, которые являются большими поклонниками использования кривых ECDH и шифров eSTREAM таких как ChaCha и HC-128, для гибридного шифрования, разработчики ROOK придерживаются традиционного выбора RSA и AES.
IOCS
Анализируемый образец представляет собой 64-битный исполняемый файл Windows.
MD5: 6d87be9212a1a0e92e58e1ed94c589f9
SHA256: c2d46d256b8f9490c9599eea11ecef19fde7d4fdd2dea93604cee3cea8e172ac
Сэмпл: MalwareBazaar (https://bazaar.abuse.ch/sample/c2d46d256b8f9490c9599eea11ecef19fde7d4fdd2dea93604cee3cea8e172ac/)
Записка с требованием выкупа
Содержимое примечания о выкупе по умолчанию хранится в виде открытого текста в исполняемом файле ROOK.
Имя файла заметки о выкупе ROOK — "HowToRestoreYourFiles.txt", что очень похоже на "How To Restore Your Files.txt" BABUK.
Статический анализ кода
Генерация RSA-ключа
Первое, что делает ROOK при выполнении, — настраивает ключи RSA для асимметричного шифрования.
Во-первых, вредоносное ПО инициализирует контекст CTR_DRBG (https://tls.mbed.org/api/structmbedtls__ctr__drbg__context.html) с помощью библиотеки Mbed TLS (https://tls.mbed.org/api/ctr__drbg_8h.html) , которая используется для построения псевдо-ГСЧ для последующей случайной генерации ключей AES.
Затем он вызывает mbedtls_pk_parse_public_key (https://tls.mbed.org/api/pk_8h.html#ade680bf8e87df7ccc3bb36b52e43972b ) для преобразования открытого ключа RSA TA в структуру mbedtls_pk_context. Контекст открытого ключа ROOK затем извлекается из поля pk_ctx во вновь заполненной структуре mbedtls_pk_context.
Ниже приведено необработанное содержимое открытого ключа.
Затем ROOK вызывает RegCreateKeyExW, чтобы открыть подраздел Software в HKEY_CURRENT_USER. Используя это, он вызывает RegQueryValueExW, чтобы проверить, существует ли там значение реестра RookPublicKey. Если это не так, вредоносная программа генерирует пару открытого и закрытого ключей для жертвы.
Затем ROOK шифрует закрытый ключ RSA жертвы, используя контекст собственного открытого ключа.
Открытый ключ жертвы и зашифрованный закрытый ключ последовательно сохраняются в реестре со значениями RookPublicKey и RookPrivateKey.
Если открытый ключ жертвы уже был сгенерирован ранее и вредоносное ПО может запросить его непосредственно из реестра, зашифрованный закрытый ключ жертвы извлекается из значения реестра RookPrivateKey.
Наконец, вредоносное ПО вызывает mbedtls_pk_parse_public_key для получения контекста открытого ключа жертвы и стирает необработанный закрытый ключ жертвы из памяти.
Анти-обнаружение: альтернативные потоки данных
Альтернативные потоки данных (ADS) — это атрибут файла в файловой системе NT (NTFS), который был разработан для совместимости с иерархической файловой системой Macintosh (HFS).
Для обычных файлов обычно существует один первичный поток данных, известный как безымянный поток данных, поскольку его имя представляет собой пустую строку. Однако ADS позволяет файлам иметь более одного потока данных, при этом любой поток с именем считается альтернативным.
Поскольку альтернативные потоки данных скрыты от проводника Windows и команды dir в командной строке, они представляют собой хитрый способ скрыть внешний исполняемый файл от, казалось бы, безобидного файла.
Чтобы избежать обнаружения, ROOK использует ADS для сокрытия собственного исполняемого файла. Во-первых, он вызывает GetModuleFileNameW с дескриптором NULL, чтобы получить собственный путь к исполняемому файлу.
Затем он вызывает CreateFileW для получения собственного дескриптора и SetFileInformationByHandle для переименования файла с потоком данных с именем ":ask". Это в конечном итоге помещает весь исполняемый файл в альтернативный поток данных ":ask", оставляя пустой файл в основном потоке.
Приостановив выполнение после освобождения дескриптора с помощью вызова CloseHandle, мы можем проверить, как это выглядит в системе.
Выполнив команду "dir / r", мы можем проверить, какие изменения в исполняемом файле.
Чтобы проверить это, я использую две копии образца ROOK, а ro0k.mal_ скрывает себя в потоке данных ":ask". Как мы видим в командной строке, этот файл отображается пустым, но его альтернативный поток данных содержит полный вредоносный исполняемый файл.
После этого файл программы-вымогателя будет отображаться в файловой системе пустым до конца выполнения.
После скрытия себя ROOK также снова вызывает SetFileInformationByHandle, чтобы настроить файл на удаление после закрытия всех дескрипторов в конце.
Аргументы командной строки
ROOK может работать как с аргументами командной строки, так и без них.
Ниже приведен список аргументов, которые могут быть предоставлены оператором.
Логирование
Когда аргумент отладки предоставляется в командной строке, ROOK включает отладку и вызывает CreateFileW для создания файла журнала для последующего входа в систему.
Он также вызывает InitializeCriticalSection для инициализации критического раздела, чтобы предотвратить одновременную запись в файл журнала нескольких потоков.
Остановка служб
Для остановки сервисов ROOK заимствует эту часть из просочившегося исходного кода BABUK.
Вредоносная программа сначала вызывает GetTickCount для подсчета тактов перед остановкой служб. Затем он вызывает OpenSCManagerA для получения дескриптора диспетчера управления службами.
Затем он перебирает жестко закодированный список служб, которые необходимо остановить. Для каждой из этих служб вредоносное ПО вызывает OpenServiceA для получения дескриптора службы и QueryServiceStatusEx для запроса и проверки состояния службы SERVICE_STOP_PENDING.
Если это не так, ROOK вызывает EnumDependentServicesA для перечисления всех зависимых служб целевой службы и их остановки.
Для каждой зависимой службы вредоносная программа вызывает OpenServiceA, чтобы получить ее дескриптор, и ControlService, чтобы отправить код остановки управления, чтобы остановить ее. Он также приостанавливается и вызывает QueryServiceStatusEx, чтобы дождаться полной остановки состояния службы.
После остановки всех зависимых сервисов ROOK вызывает ControlService, отправляет контрольный код остановки основному сервису и непрерывно проверяет, пока сервис не будет полностью остановлен.
Для остановки всех служб максимальное время ожидания составляет 30000 мс или 30 секунд от исходного количества тиков. Если для остановки служб требуется более 30 секунд, вредоносная программа прерывает работу и выходит из функции.
Ниже приведен список остановленных служб.
"memtas", "mepocs", "vss", "sql", "svc$", "veeam", "backup", "GxVss", "GxBlr", "GxFWD", "GxCVD", "GxCIMgr", "DefWatch", "ccEvtMgr", "ccSetMgr", "SavRoam", "RTVscan", "QBFCService", "QBIDPService", "Intuit.QuickBooks.FCS", "QBCFMonitorService", "AcrSch2Svc", "AcronisAgent", "CASAD2DWebSvc", "CAARCUpdateSvc"
Завершающие процессы
Эта часть кода также скопирована и вставлена из исходного кода BABUK.
ROOK вызывает CreateToolhelp32Snapshot для получения моментального снимка всех процессов и потоков в системе. Затем он вызывает Process32FirstW и Process32NextW для перечисления моментального снимка.
Для каждого процесса, чье имя находится в списке процессов, подлежащих завершению, вредоносное ПО вызывает OpenProcess для получения дескриптора процесса и TerminateProcess для его завершения.
Ниже приведен список процессов, которые остановлены.
sql.exe", "oracle.exe", "ocssd.exe", "dbsnmp.exe", "visio.exe", "winword.exe", "wordpad.exe", "notepad.exe", "excel.exe", "onenote.exe", "outlook.exe", "synctime.exe", "agntsvc.exe", "isqlplussvc.exe", "xfssvccon.exe", "mydesktopservice.exe", "ocautoupds.exe", "encsvc.exe", "firefox.exe", "tbirdconfig.exe", "mydesktopqos.exe", "ocomm.exe", "dbeng50.exe", "sqbcoreservice.exe", "infopath.exe", "msaccess.exe", "mspub.exe", "powerpnt.exe", "steam.exe", "thebat.exe", "thunderbird.exe"
Удаление теневых копий
Эта часть кода также скопирована и вставлена из исходного кода BABUK.
ROOK сначала проверяет, работает ли его процесс под управлением 64-битного процессора, вызывая IsWow64Process.
Если это так, вредоносная программа вызывает Wow64DisableWow64FsRedirection, чтобы отключить перенаправление файловой системы для своего процесса.
Затем он выполняет ShellExecuteW, чтобы запустить следующую команду в командной строке для удаления всех теневых копий в системе.
vssadmin.exe delete shadows /all /quiet
Наконец, если процесс вредоносной программы работает под 64-битной архитектурой, он вызывает Wow64RevertWow64FsRedirection, чтобы включить перенаправление файловой системы.
Настройка многопоточности
Перед шифрованием файлов ROOK устанавливает собственную многопоточную систему.
Сначала он вызывает GetSystemInfo для получения количества процессоров в системе.
Многопоточная структура разделена на две части: шифрование файлов и перечисление каталогов.
Для шифрования файлов вредоносная программа вычисляет максимальное количество файлов, которые должны быть зашифрованы несколькими потоками одновременно, в 24 раза больше числа процессоров. Затем он вызывает HeapAlloc, чтобы выделить глобальный массив для хранения файлов, которые должны быть зашифрованы, и CreateSemaphoreA, чтобы создать 2 семафора, которые используются для синхронизации между потоками, обращающимися к массиву файлов. Наконец, он также вызывает InitializeCriticalSection для инициализации критической секции, которая позволяет одному потоку добавлять или удалять файл из глобального массива за раз.
Для перечисления каталогов вредоносная программа вычисляет максимальное количество каталогов, которые должны быть пронумерованы несколькими потоками одновременно, в 6 раз больше числа процессоров. Он также создает глобальный массив, 2 семафора и критическую секцию, как в части шифрования файлов выше.
Затем вредоносное ПО вызывает HeapAlloc, чтобы выделить два массива для хранения дескрипторов дочерних потоков, один для шифрования файлов, а другой для перечисления каталогов.
Затем ROOK вызывает CreateThread для порождения потоков для удвоения числа процессоров для каждого массива потоков. Функциональные возможности этих потоков позже обсуждаются в разделе "Дочерние потоки"
Обход сетевых ресурсов
Когда аргумент командной строки "-paths" или "-shares" не указан, ROOK рекурсивно проходит через все ресурсы в сети.
Вредоносное ПО вызывает WNetOpenEnumW для получения дескриптора перечисления для всех сетевых ресурсов и WNetEnumResourceW для их перечисления.
Для каждого сетевого ресурса, если он является контейнером для других ресурсов, которые также могут быть перечислены, ROOK рекурсивно передает его обратно текущей функции для прохождения.
Если ресурс представляет собой обычный и подключаемый каталог, вредоносное ПО передает его рекурсивной функции для обхода, что будет обсуждаться в разделе "Обход дисков" (https://chuongdong.com/reverse engineering/2022/01/06/RookRansomware/#drives-traversal).
Обход дисков
Когда указан аргумент командной строки "-paths", ROOK специально перечисляет их и завершает работу после завершения.
Аргумент может быть представлен в виде списка путей, разделенных запятой. Вместо обычного пути к каталогу ROOK также принимает двухсимвольную строку буквы диска, за которой следует двоеточие, в качестве пути к диску.
При обходе диска ROOK строит следующий путь к диску.
\\\\?\\<drive_letter>:
По пути вредоносная программа проверяет и избегает перечисления диска, если это дисковод для компакт-дисков.
Если тип диска — удаленный, ROOK вызывает WNetGetConnectionW, чтобы получить имя удаленного диска, и передает его для обхода функцией recursive_traverse_dir.
Если тип диска не удаленный, а дисковод для компакт-дисков, вредоносная программа просто передает его функции recursive_traverse_dir.
В функции recursive_traverse_dir ROOK начинает с выполнения двух вложенных циклов while. Первый зацикливается и ждет, пока счетчик семафора END_ACCESS_DIR_SEMAPHORE не уменьшится до нуля, а его состояние не станет несигнальным. Когда это происходит, это означает, что каждый каталог в глобальном списке каталогов уже пройден и ни один поток не извлекается из него.
Ожидая этого, внутренний цикл while ожидает, пока семафор BEGIN_ACCESS_FILE_SEMAPHORE не будет сигнализирован, что позволит текущему процессу получить доступ к глобальному списку файлов. После получения права собственности на критическую секцию для глобального списка файлов с помощью EnterCriticalSection ROOK извлекает файл с текущим индексом, увеличивает индекс и шифрует его. Процедура шифрования файлов будет обсуждаться позже в разделе "Шифрование файлов"
Вместо того, чтобы просто зацикливаться и ждать, пока список каталогов будет очищен, ROOK извлекает и шифрует файлы в глобальном списке файлов во время ожидания, чтобы повысить эффективность и избежать пустой траты вычислительных ресурсов. Это делает общий процесс перечисления и шифрования довольно быстрым.
Затем вредоносное ПО вызывает EnterCriticalSection, чтобы получить право собственности на список глобальных каталогов, и добавляет путь к каталогу, по которому нужно пройти. Затем он вызывает ReleaseSemaphore для освобождения семафора BEGIN_ACCESS_DIR_SEMAPHORE, который увеличивает свой счетчик на единицу и сообщает другим потокам, что для перечисления доступен другой каталог.
Затем функция начинает перечислять каталог для всех его подкаталогов. ROOK строит путь **"\\\*"** и передает его **FindFirstFileW** для начала перечисления.
Для каждого найденного подкаталога вредоносная программа проверяет, нет ли имени файла в списке файлов и каталогов, которых следует избегать. Если это не так, создается полный путь к подкаталогу и передается обратно в recursive_traverse_dir для рекурсивного обхода.
Ниже приведен список файлов и каталогов, которых следует избегать.
<log_filename>, "Mozilla Firefox", "$Recycle.Bin", "ProgramData", "All Users", "autorun.inf", "boot.ini", "bootfont.bin", "bootsect.bak", "bootmgr", "bootmgr.efi", "bootmgfw.efi", "desktop.ini", "iconcache.db", "ntldr", "ntuser.dat", "ntuser.dat.log", "ntuser.ini", "thumbs.db", "Program Files", "Program Files (x86)", "AppData", "Boot", "Windows", "Windows.old", "Tor Browser", "Internet Explorer", "Google", "Opera", "Opera Software", "Mozilla", "#recycle", "..", "."
Если аргумент командной строки "-paths" не указан, ROOK вручную монтирует все диски, на которых нет смонтированных томов, и просматривает их все.
Во-первых, он создает список всех букв дисков и перебирает его, чтобы найти диски с типом DRIVE_NO_ROOT_DIR. Затем эти диски добавляются в конец списка.
Затем ROOK вызывает FindFirstVolumeW и FindNextVolumeW для сканирования доступных томов в системе. Для каждого тома вредоносная программа вызывает GetVolumePathNamesForVolumeNameW, чтобы получить путь GUID тома, и SetVolumeMountPointW, чтобы установить путь в качестве корневого пути для следующего диска без полномочий root в списке.
Наконец, вредоносная программа вызывает GetLogicalDrives для перебора всех дисков в системе и их обхода.
Обход шар
Когда указан аргумент командной строки "-shares", ROOK специально перечисляет их и завершает работу после завершения.
Аргумент может быть представлен в виде списка путей к сетевым серверам, каждый из которых разделен запятой.
Чтобы обойти каждый общий сервер, вредоносное ПО вызывает NetShareEnum для получения информации о каждом общем ресурсе на нем.
Для каждого общего ресурса, если его тип не является специальным общим ресурсом, зарезервированным для межпроцессного взаимодействия (IPC$) или удаленного администрирования сервера (ADMIN$), общий ресурс пропускается.
Если имя общего ресурса — "ADMIN$", вредоносное ПО строит путь **»\\\\ADMIN\$"** и передает его в **recursive_traverse_dir** для прохождения.
Дочерние потоки
Для порожденных дочерних потоков у них есть два разных режима выполнения в зависимости от флага, переданного в качестве параметра.
Если флаг равен 1, поток будет обрабатывать каталог из глобального списка каталогов.
Во-первых, он входит во вложенный цикл while, подобный тому, который мы видели ранее.Первый цикл ожидает, пока семафор BEGIN_ACCESS_DIR_SEMAPHORE не перейдет в несигнальное состояние, что означает, что никакой поток не добавляется в список каталогов.
Ожидая этого, ROOK эффективно ждет, чтобы получить доступ к глобальному списку файлов, извлечь файл и зашифровать его аналогично предыдущему вложенному циклу while.
После того, как список каталогов заполнен, вредоносное ПО получает право собственности на критический раздел списка, извлекает каталог и начинает просматривать его в поисках подфайлов.
Для перечисления ROOK сначала строит путь к файлу заметки о выкупе в каталоге, вызывает CreateFileW для его создания и WriteFile для записи в него содержимого заметки о выкупе.
Ниже приведено исходное содержание записки о выкупе.
Затем он строит путь **"\\*"** и передает его **FindFirstFileW**, чтобы начать перечисление файлов в каталоге.
Для каждого найденного файла ROOK проверяет, чтобы его имя не было в списке файлов и каталогов, которых следует избегать, и не является HowToRestoreYourFiles.txt.
ROOK также пропускает файл, если его расширение ".exe", ".dll" или ".Rook". После проверки вредоносное ПО входит во вложенный цикл while и ждет, пока ни один поток не сможет добавить в глобальный список файлов, и извлекает файлы для шифрования в течение времени ожидания.
Получив доступ к списку файлов, ROOK вызывает EnterCriticalSection, чтобы получить право собственности на критическую секцию списка файлов, и добавляет подфайл в список.
Если параметр флага from равен 1, дочерний поток будет непрерывно шифровать файлы из списка глобальных каталогов, пока список не станет полностью пустым.
Шифрование файлов
Перед шифрованием файла ROOK вызывает SetFileAttributesW, чтобы установить нормальный атрибут файла.
Он строит следующий путь **«.Rook»** и вызывает **MoveFileExW**, чтобы изменить имя файла на зашифрованное расширение **.Rook**.
Затем вредоносное ПО вызывает CreateFileW, чтобы получить дескриптор файла для цели, и начинает шифрование.
Во-первых, он использует контекст Mbed TLS CTR_DRBG для генерации случайного 16-байтового ключа AES.
Затем ROOK заполняет следующие структуры для нижнего колонтитула файла.
Вредоносная программа начинает с вызова GetFileSizeEx, чтобы получить размер файла и сохранить его в нижнем колонтитуле файла. Затем он использует открытый ключ RSA жертвы для шифрования ключа AES и сохраняет его в поле метаданных AES_key_encrypted_by_my_public.
Затем он копирует закрытый ключ жертвы, зашифрованный с помощью открытого ключа ROOK во время генерации ключа RSA, в поле метаданных my_private_key_encrypted_by_Rook_public.
Если размер файла превышает 0x80000 байт, вредоносное ПО считывает и шифрует не более трех фрагментов размером 0x80000 байт в начале файла с использованием AES-128 ECB.
Если размер файла меньше 0x80000 байт или находится в диапазоне от 0x80000 до 0x180000 байт, весь файл будет зашифрован.
Наконец, нижний колонтитул файла записывается в конец файла, что завершает процедуру шифрования.
Если ROOK не может открыть файл до шифрования, вредоносная программа пытается завершить процесс владельца файла.
Сначала он вызывает RmStartSession для запуска нового сеанса Restart Manager и WideCharToMultiByte для преобразования пути к файлу в многобайтовый буфер.
Используя этот дескриптор сеанса, вредоносное ПО вызывает RmRegisterResources, чтобы зарегистрировать целевой файл в качестве ресурса для RM.
Затем он вызывает RmGetList, чтобы получить список всех приложений, использующих файл. Для каждого из этих приложений, если тип приложения — проводник Windows или критический процесс, оно пропускается.
Затем ROOK проверяет, не является ли приложение собственным процессом программы-вымогателя, используя идентификаторы процессов. Наконец, он вызывает OpenProcess, чтобы получить дескриптор процесса и завершить его с помощью TerminateProcess.
После завершения всех процессов, использующих файл, ROOK передает его обратно для шифрования.
Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://chuongdong.com/reverse engineering/2022/01/06/RookRansomware/
Это мой анализ для ROOK Ransomware.
ROOK — это относительно новая программа-вымогатель, появившаяся в последние несколько месяцев. С библиотекой Mbed TLS (https://github.com/ARMmbed/mbedtls ) вредоносная программа использует схему гибридной криптографии для шифрования файлов с помощью AES и защиты своих ключей с помощью RSA-2048.
Что касается скорости выполнения, то ROOK довольно быстр, поскольку использует довольно хороший метод многопоточности с двумя глобальными списками для обхода файлов и каталогов.
Как утверждают другие исследователи, ROOK заимствует часть кода из просочившегося исходного кода BABUK. Если быть более точным, разработчики ROOK скопировали и вставили код завершения сервисов и процессов, а также удаления теневых копий. Многопоточный подход ROOK представляет собой повторную реализацию и обновление BABUK версии 3, которая теперь более эффективна для обхода каталогов.
Однако, в отличие от разработчиков BABUK, которые являются большими поклонниками использования кривых ECDH и шифров eSTREAM таких как ChaCha и HC-128, для гибридного шифрования, разработчики ROOK придерживаются традиционного выбора RSA и AES.
IOCS
Анализируемый образец представляет собой 64-битный исполняемый файл Windows.
MD5: 6d87be9212a1a0e92e58e1ed94c589f9
SHA256: c2d46d256b8f9490c9599eea11ecef19fde7d4fdd2dea93604cee3cea8e172ac
Сэмпл: MalwareBazaar (https://bazaar.abuse.ch/sample/c2d46d256b8f9490c9599eea11ecef19fde7d4fdd2dea93604cee3cea8e172ac/)
Записка с требованием выкупа
Содержимое примечания о выкупе по умолчанию хранится в виде открытого текста в исполняемом файле ROOK.
Имя файла заметки о выкупе ROOK — "HowToRestoreYourFiles.txt", что очень похоже на "How To Restore Your Files.txt" BABUK.
Статический анализ кода
Генерация RSA-ключа
Первое, что делает ROOK при выполнении, — настраивает ключи RSA для асимметричного шифрования.
Во-первых, вредоносное ПО инициализирует контекст CTR_DRBG (https://tls.mbed.org/api/structmbedtls__ctr__drbg__context.html) с помощью библиотеки Mbed TLS (https://tls.mbed.org/api/ctr__drbg_8h.html) , которая используется для построения псевдо-ГСЧ для последующей случайной генерации ключей AES.
Затем он вызывает mbedtls_pk_parse_public_key (https://tls.mbed.org/api/pk_8h.html#ade680bf8e87df7ccc3bb36b52e43972b ) для преобразования открытого ключа RSA TA в структуру mbedtls_pk_context. Контекст открытого ключа ROOK затем извлекается из поля pk_ctx во вновь заполненной структуре mbedtls_pk_context.
Ниже приведено необработанное содержимое открытого ключа.
Затем ROOK вызывает RegCreateKeyExW, чтобы открыть подраздел Software в HKEY_CURRENT_USER. Используя это, он вызывает RegQueryValueExW, чтобы проверить, существует ли там значение реестра RookPublicKey. Если это не так, вредоносная программа генерирует пару открытого и закрытого ключей для жертвы.
Затем ROOK шифрует закрытый ключ RSA жертвы, используя контекст собственного открытого ключа.
Открытый ключ жертвы и зашифрованный закрытый ключ последовательно сохраняются в реестре со значениями RookPublicKey и RookPrivateKey.
Если открытый ключ жертвы уже был сгенерирован ранее и вредоносное ПО может запросить его непосредственно из реестра, зашифрованный закрытый ключ жертвы извлекается из значения реестра RookPrivateKey.
Наконец, вредоносное ПО вызывает mbedtls_pk_parse_public_key для получения контекста открытого ключа жертвы и стирает необработанный закрытый ключ жертвы из памяти.
Анти-обнаружение: альтернативные потоки данных
Альтернативные потоки данных (ADS) — это атрибут файла в файловой системе NT (NTFS), который был разработан для совместимости с иерархической файловой системой Macintosh (HFS).
Для обычных файлов обычно существует один первичный поток данных, известный как безымянный поток данных, поскольку его имя представляет собой пустую строку. Однако ADS позволяет файлам иметь более одного потока данных, при этом любой поток с именем считается альтернативным.
Поскольку альтернативные потоки данных скрыты от проводника Windows и команды dir в командной строке, они представляют собой хитрый способ скрыть внешний исполняемый файл от, казалось бы, безобидного файла.
Чтобы избежать обнаружения, ROOK использует ADS для сокрытия собственного исполняемого файла. Во-первых, он вызывает GetModuleFileNameW с дескриптором NULL, чтобы получить собственный путь к исполняемому файлу.
Затем он вызывает CreateFileW для получения собственного дескриптора и SetFileInformationByHandle для переименования файла с потоком данных с именем ":ask". Это в конечном итоге помещает весь исполняемый файл в альтернативный поток данных ":ask", оставляя пустой файл в основном потоке.
Приостановив выполнение после освобождения дескриптора с помощью вызова CloseHandle, мы можем проверить, как это выглядит в системе.
Выполнив команду "dir / r", мы можем проверить, какие изменения в исполняемом файле.
Чтобы проверить это, я использую две копии образца ROOK, а ro0k.mal_ скрывает себя в потоке данных ":ask". Как мы видим в командной строке, этот файл отображается пустым, но его альтернативный поток данных содержит полный вредоносный исполняемый файл.
После этого файл программы-вымогателя будет отображаться в файловой системе пустым до конца выполнения.
После скрытия себя ROOK также снова вызывает SetFileInformationByHandle, чтобы настроить файл на удаление после закрытия всех дескрипторов в конце.
Аргументы командной строки
ROOK может работать как с аргументами командной строки, так и без них.
Ниже приведен список аргументов, которые могут быть предоставлены оператором.
Логирование
Когда аргумент отладки предоставляется в командной строке, ROOK включает отладку и вызывает CreateFileW для создания файла журнала для последующего входа в систему.
Он также вызывает InitializeCriticalSection для инициализации критического раздела, чтобы предотвратить одновременную запись в файл журнала нескольких потоков.
Остановка служб
Для остановки сервисов ROOK заимствует эту часть из просочившегося исходного кода BABUK.
Вредоносная программа сначала вызывает GetTickCount для подсчета тактов перед остановкой служб. Затем он вызывает OpenSCManagerA для получения дескриптора диспетчера управления службами.
Затем он перебирает жестко закодированный список служб, которые необходимо остановить. Для каждой из этих служб вредоносное ПО вызывает OpenServiceA для получения дескриптора службы и QueryServiceStatusEx для запроса и проверки состояния службы SERVICE_STOP_PENDING.
Если это не так, ROOK вызывает EnumDependentServicesA для перечисления всех зависимых служб целевой службы и их остановки.
Для каждой зависимой службы вредоносная программа вызывает OpenServiceA, чтобы получить ее дескриптор, и ControlService, чтобы отправить код остановки управления, чтобы остановить ее. Он также приостанавливается и вызывает QueryServiceStatusEx, чтобы дождаться полной остановки состояния службы.
После остановки всех зависимых сервисов ROOK вызывает ControlService, отправляет контрольный код остановки основному сервису и непрерывно проверяет, пока сервис не будет полностью остановлен.
Для остановки всех служб максимальное время ожидания составляет 30000 мс или 30 секунд от исходного количества тиков. Если для остановки служб требуется более 30 секунд, вредоносная программа прерывает работу и выходит из функции.
Ниже приведен список остановленных служб.
"memtas", "mepocs", "vss", "sql", "svc$", "veeam", "backup", "GxVss", "GxBlr", "GxFWD", "GxCVD", "GxCIMgr", "DefWatch", "ccEvtMgr", "ccSetMgr", "SavRoam", "RTVscan", "QBFCService", "QBIDPService", "Intuit.QuickBooks.FCS", "QBCFMonitorService", "AcrSch2Svc", "AcronisAgent", "CASAD2DWebSvc", "CAARCUpdateSvc"
Завершающие процессы
Эта часть кода также скопирована и вставлена из исходного кода BABUK.
ROOK вызывает CreateToolhelp32Snapshot для получения моментального снимка всех процессов и потоков в системе. Затем он вызывает Process32FirstW и Process32NextW для перечисления моментального снимка.
Для каждого процесса, чье имя находится в списке процессов, подлежащих завершению, вредоносное ПО вызывает OpenProcess для получения дескриптора процесса и TerminateProcess для его завершения.
Ниже приведен список процессов, которые остановлены.
sql.exe", "oracle.exe", "ocssd.exe", "dbsnmp.exe", "visio.exe", "winword.exe", "wordpad.exe", "notepad.exe", "excel.exe", "onenote.exe", "outlook.exe", "synctime.exe", "agntsvc.exe", "isqlplussvc.exe", "xfssvccon.exe", "mydesktopservice.exe", "ocautoupds.exe", "encsvc.exe", "firefox.exe", "tbirdconfig.exe", "mydesktopqos.exe", "ocomm.exe", "dbeng50.exe", "sqbcoreservice.exe", "infopath.exe", "msaccess.exe", "mspub.exe", "powerpnt.exe", "steam.exe", "thebat.exe", "thunderbird.exe"
Удаление теневых копий
Эта часть кода также скопирована и вставлена из исходного кода BABUK.
ROOK сначала проверяет, работает ли его процесс под управлением 64-битного процессора, вызывая IsWow64Process.
Если это так, вредоносная программа вызывает Wow64DisableWow64FsRedirection, чтобы отключить перенаправление файловой системы для своего процесса.
Затем он выполняет ShellExecuteW, чтобы запустить следующую команду в командной строке для удаления всех теневых копий в системе.
vssadmin.exe delete shadows /all /quiet
Наконец, если процесс вредоносной программы работает под 64-битной архитектурой, он вызывает Wow64RevertWow64FsRedirection, чтобы включить перенаправление файловой системы.
Настройка многопоточности
Перед шифрованием файлов ROOK устанавливает собственную многопоточную систему.
Сначала он вызывает GetSystemInfo для получения количества процессоров в системе.
Многопоточная структура разделена на две части: шифрование файлов и перечисление каталогов.
Для шифрования файлов вредоносная программа вычисляет максимальное количество файлов, которые должны быть зашифрованы несколькими потоками одновременно, в 24 раза больше числа процессоров. Затем он вызывает HeapAlloc, чтобы выделить глобальный массив для хранения файлов, которые должны быть зашифрованы, и CreateSemaphoreA, чтобы создать 2 семафора, которые используются для синхронизации между потоками, обращающимися к массиву файлов. Наконец, он также вызывает InitializeCriticalSection для инициализации критической секции, которая позволяет одному потоку добавлять или удалять файл из глобального массива за раз.
Для перечисления каталогов вредоносная программа вычисляет максимальное количество каталогов, которые должны быть пронумерованы несколькими потоками одновременно, в 6 раз больше числа процессоров. Он также создает глобальный массив, 2 семафора и критическую секцию, как в части шифрования файлов выше.
Затем вредоносное ПО вызывает HeapAlloc, чтобы выделить два массива для хранения дескрипторов дочерних потоков, один для шифрования файлов, а другой для перечисления каталогов.
Затем ROOK вызывает CreateThread для порождения потоков для удвоения числа процессоров для каждого массива потоков. Функциональные возможности этих потоков позже обсуждаются в разделе "Дочерние потоки"
Обход сетевых ресурсов
Когда аргумент командной строки "-paths" или "-shares" не указан, ROOK рекурсивно проходит через все ресурсы в сети.
Вредоносное ПО вызывает WNetOpenEnumW для получения дескриптора перечисления для всех сетевых ресурсов и WNetEnumResourceW для их перечисления.
Для каждого сетевого ресурса, если он является контейнером для других ресурсов, которые также могут быть перечислены, ROOK рекурсивно передает его обратно текущей функции для прохождения.
Если ресурс представляет собой обычный и подключаемый каталог, вредоносное ПО передает его рекурсивной функции для обхода, что будет обсуждаться в разделе "Обход дисков" (https://chuongdong.com/reverse engineering/2022/01/06/RookRansomware/#drives-traversal).
Обход дисков
Когда указан аргумент командной строки "-paths", ROOK специально перечисляет их и завершает работу после завершения.
Аргумент может быть представлен в виде списка путей, разделенных запятой. Вместо обычного пути к каталогу ROOK также принимает двухсимвольную строку буквы диска, за которой следует двоеточие, в качестве пути к диску.
При обходе диска ROOK строит следующий путь к диску.
\\\\?\\<drive_letter>:
По пути вредоносная программа проверяет и избегает перечисления диска, если это дисковод для компакт-дисков.
Если тип диска — удаленный, ROOK вызывает WNetGetConnectionW, чтобы получить имя удаленного диска, и передает его для обхода функцией recursive_traverse_dir.
Если тип диска не удаленный, а дисковод для компакт-дисков, вредоносная программа просто передает его функции recursive_traverse_dir.
В функции recursive_traverse_dir ROOK начинает с выполнения двух вложенных циклов while. Первый зацикливается и ждет, пока счетчик семафора END_ACCESS_DIR_SEMAPHORE не уменьшится до нуля, а его состояние не станет несигнальным. Когда это происходит, это означает, что каждый каталог в глобальном списке каталогов уже пройден и ни один поток не извлекается из него.
Ожидая этого, внутренний цикл while ожидает, пока семафор BEGIN_ACCESS_FILE_SEMAPHORE не будет сигнализирован, что позволит текущему процессу получить доступ к глобальному списку файлов. После получения права собственности на критическую секцию для глобального списка файлов с помощью EnterCriticalSection ROOK извлекает файл с текущим индексом, увеличивает индекс и шифрует его. Процедура шифрования файлов будет обсуждаться позже в разделе "Шифрование файлов"
Вместо того, чтобы просто зацикливаться и ждать, пока список каталогов будет очищен, ROOK извлекает и шифрует файлы в глобальном списке файлов во время ожидания, чтобы повысить эффективность и избежать пустой траты вычислительных ресурсов. Это делает общий процесс перечисления и шифрования довольно быстрым.
Затем вредоносное ПО вызывает EnterCriticalSection, чтобы получить право собственности на список глобальных каталогов, и добавляет путь к каталогу, по которому нужно пройти. Затем он вызывает ReleaseSemaphore для освобождения семафора BEGIN_ACCESS_DIR_SEMAPHORE, который увеличивает свой счетчик на единицу и сообщает другим потокам, что для перечисления доступен другой каталог.
Затем функция начинает перечислять каталог для всех его подкаталогов. ROOK строит путь **"\\\*"** и передает его **FindFirstFileW** для начала перечисления.
Для каждого найденного подкаталога вредоносная программа проверяет, нет ли имени файла в списке файлов и каталогов, которых следует избегать. Если это не так, создается полный путь к подкаталогу и передается обратно в recursive_traverse_dir для рекурсивного обхода.
Ниже приведен список файлов и каталогов, которых следует избегать.
<log_filename>, "Mozilla Firefox", "$Recycle.Bin", "ProgramData", "All Users", "autorun.inf", "boot.ini", "bootfont.bin", "bootsect.bak", "bootmgr", "bootmgr.efi", "bootmgfw.efi", "desktop.ini", "iconcache.db", "ntldr", "ntuser.dat", "ntuser.dat.log", "ntuser.ini", "thumbs.db", "Program Files", "Program Files (x86)", "AppData", "Boot", "Windows", "Windows.old", "Tor Browser", "Internet Explorer", "Google", "Opera", "Opera Software", "Mozilla", "#recycle", "..", "."
Если аргумент командной строки "-paths" не указан, ROOK вручную монтирует все диски, на которых нет смонтированных томов, и просматривает их все.
Во-первых, он создает список всех букв дисков и перебирает его, чтобы найти диски с типом DRIVE_NO_ROOT_DIR. Затем эти диски добавляются в конец списка.
Затем ROOK вызывает FindFirstVolumeW и FindNextVolumeW для сканирования доступных томов в системе. Для каждого тома вредоносная программа вызывает GetVolumePathNamesForVolumeNameW, чтобы получить путь GUID тома, и SetVolumeMountPointW, чтобы установить путь в качестве корневого пути для следующего диска без полномочий root в списке.
Наконец, вредоносная программа вызывает GetLogicalDrives для перебора всех дисков в системе и их обхода.
Обход шар
Когда указан аргумент командной строки "-shares", ROOK специально перечисляет их и завершает работу после завершения.
Аргумент может быть представлен в виде списка путей к сетевым серверам, каждый из которых разделен запятой.
Чтобы обойти каждый общий сервер, вредоносное ПО вызывает NetShareEnum для получения информации о каждом общем ресурсе на нем.
Для каждого общего ресурса, если его тип не является специальным общим ресурсом, зарезервированным для межпроцессного взаимодействия (IPC$) или удаленного администрирования сервера (ADMIN$), общий ресурс пропускается.
Если имя общего ресурса — "ADMIN$", вредоносное ПО строит путь **»\\\\ADMIN\$"** и передает его в **recursive_traverse_dir** для прохождения.
Дочерние потоки
Для порожденных дочерних потоков у них есть два разных режима выполнения в зависимости от флага, переданного в качестве параметра.
Если флаг равен 1, поток будет обрабатывать каталог из глобального списка каталогов.
Во-первых, он входит во вложенный цикл while, подобный тому, который мы видели ранее.Первый цикл ожидает, пока семафор BEGIN_ACCESS_DIR_SEMAPHORE не перейдет в несигнальное состояние, что означает, что никакой поток не добавляется в список каталогов.
Ожидая этого, ROOK эффективно ждет, чтобы получить доступ к глобальному списку файлов, извлечь файл и зашифровать его аналогично предыдущему вложенному циклу while.
После того, как список каталогов заполнен, вредоносное ПО получает право собственности на критический раздел списка, извлекает каталог и начинает просматривать его в поисках подфайлов.
Для перечисления ROOK сначала строит путь к файлу заметки о выкупе в каталоге, вызывает CreateFileW для его создания и WriteFile для записи в него содержимого заметки о выкупе.
Ниже приведено исходное содержание записки о выкупе.
Затем он строит путь **"\\*"** и передает его **FindFirstFileW**, чтобы начать перечисление файлов в каталоге.
Для каждого найденного файла ROOK проверяет, чтобы его имя не было в списке файлов и каталогов, которых следует избегать, и не является HowToRestoreYourFiles.txt.
ROOK также пропускает файл, если его расширение ".exe", ".dll" или ".Rook". После проверки вредоносное ПО входит во вложенный цикл while и ждет, пока ни один поток не сможет добавить в глобальный список файлов, и извлекает файлы для шифрования в течение времени ожидания.
Получив доступ к списку файлов, ROOK вызывает EnterCriticalSection, чтобы получить право собственности на критическую секцию списка файлов, и добавляет подфайл в список.
Если параметр флага from равен 1, дочерний поток будет непрерывно шифровать файлы из списка глобальных каталогов, пока список не станет полностью пустым.
Шифрование файлов
Перед шифрованием файла ROOK вызывает SetFileAttributesW, чтобы установить нормальный атрибут файла.
Он строит следующий путь **«.Rook»** и вызывает **MoveFileExW**, чтобы изменить имя файла на зашифрованное расширение **.Rook**.
Затем вредоносное ПО вызывает CreateFileW, чтобы получить дескриптор файла для цели, и начинает шифрование.
Во-первых, он использует контекст Mbed TLS CTR_DRBG для генерации случайного 16-байтового ключа AES.
Затем ROOK заполняет следующие структуры для нижнего колонтитула файла.
Вредоносная программа начинает с вызова GetFileSizeEx, чтобы получить размер файла и сохранить его в нижнем колонтитуле файла. Затем он использует открытый ключ RSA жертвы для шифрования ключа AES и сохраняет его в поле метаданных AES_key_encrypted_by_my_public.
Затем он копирует закрытый ключ жертвы, зашифрованный с помощью открытого ключа ROOK во время генерации ключа RSA, в поле метаданных my_private_key_encrypted_by_Rook_public.
Если размер файла превышает 0x80000 байт, вредоносное ПО считывает и шифрует не более трех фрагментов размером 0x80000 байт в начале файла с использованием AES-128 ECB.
Если размер файла меньше 0x80000 байт или находится в диапазоне от 0x80000 до 0x180000 байт, весь файл будет зашифрован.
Наконец, нижний колонтитул файла записывается в конец файла, что завершает процедуру шифрования.
Если ROOK не может открыть файл до шифрования, вредоносная программа пытается завершить процесс владельца файла.
Сначала он вызывает RmStartSession для запуска нового сеанса Restart Manager и WideCharToMultiByte для преобразования пути к файлу в многобайтовый буфер.
Используя этот дескриптор сеанса, вредоносное ПО вызывает RmRegisterResources, чтобы зарегистрировать целевой файл в качестве ресурса для RM.
Затем он вызывает RmGetList, чтобы получить список всех приложений, использующих файл. Для каждого из этих приложений, если тип приложения — проводник Windows или критический процесс, оно пропускается.
Затем ROOK проверяет, не является ли приложение собственным процессом программы-вымогателя, используя идентификаторы процессов. Наконец, он вызывает OpenProcess, чтобы получить дескриптор процесса и завершить его с помощью TerminateProcess.
После завершения всех процессов, использующих файл, ROOK передает его обратно для шифрования.
Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://chuongdong.com/reverse engineering/2022/01/06/RookRansomware/