Авторы вредоносных программ используют различные техники обхода защитных механизмов и сокрытия вредоносной активности. Одной из них является сокрытие вредоносного кода в контексте доверенного процесса. Как правило, вредоносное ПО, использующее технику сокрытия, внедряет свой код в системный процесс, например, explorer.exe. Но встречаются образцы, которые используют другие интересные приемы, об одном из таких зловредов мы и хотим рассказать.
В поле нашего зрения попали образцы для .NET, которые используют доверенное приложение InstallUtil.exe из состава Microsoft .NET Framework (информация с сайта Microsoft: «Программа для установки является программой командной строки, с помощью которой можно устанавливать и удалять ресурсы сервера путем выполнения компонентов установщика в соответствующих сборках. Эта программа работает совместно с классами в пространстве имен System.Configuration.Install»).
Методика была описана специалистом по информационной безопасности Кейси Смитом aka subTee (Proof of Concept). Если коротко, консольная утилита InstallUtil.exe запускает вредоносную .NET-сборку, минуя точку входа этой сборки и вся вредоносная активность скрывается в контексте доверенного процесса.
Схема распространения вредоносных образцов стандартна: в основном, они попадают к пользователю в запароленном архиве, а значки исполняемых файлов, в большинстве случаев, выбираются так, чтобы жертва приняла файл за обычный документ или фотографию. Также мы встречали исполняемые файлы, которые выдавали себя за генератор ключей для популярного ПО. В этом случае вредоносное содержимое генератора сначала попадало в папку %TEMP%, где далее запускалось описанным способом.
Анализ
Все встреченные вредоносные файлы были сильно обфусцированы, что усложнило ручной анализ. Мы взяли образец 263dc85de7ec717e8940b1ccdd6ee119 и для облегчения задачи выполнили деобфускацию его строк, классов, методов и полей. Так файл выглядел до деобфускации:
Использование InstallUtil.exe позволяет начать исполнение файла не с точки входа .NET-сборки: исполнение начинается с класса, который наследуется от System.Configuration.Install.Installer. В исследуемом образце такой класс был для удобства ручного анализа переименован в InstallUtilEntryClass. Также известно, что код в статических конструкторах классов выполняется в первую очередь при загрузке сборки в память, и авторы данного зловреда использовали эту особенность.
Рассмотрим функции вредоносного файла в порядке выполнения методов. Первым исследуем FirstMainClass, так как его конструктор помечен ключевым словом static и исполнение сборки начинается с него:
Конструктор выполняет следующие действия:
- CheckSandboxieEnvironment() с помощью попытки загрузки библиотеки SbieDll.dll определяет, запущен ли файл в Sandboxie. Если библиотеку удается загрузить, то вредоносный процесс завершается;
- CheckVirtualBoxEnvironment() выполняет поиск библиотеки vboxmrxnp.dll, принадлежащей Если библиотеку удается найти, то вредоносный процесс также завершается;
- AddResourceResolver() добавляет метод обработки события загрузки ресурсов. Этот метод выполняет распаковку сборки, запакованной алгоритмом Deflate, из определенного ресурса и загрузку этой сборки в память.
- Метод UnpackAllAssemblies() класса AssemblyResourceLoader выполняет итерацию по всем ресурсам сборки и, если имя ресурса содержит строку «+||», производит распаковку сборок из этих ресурсов. Сборки, которые распаковываются этим методом необходимы для работы вредоносного файла и являются легальными библиотеками: Interop.MSScript.Control, Interop.TaskScheduler и SevenZipSharp;
- RemoveZoneIdentifier() с помощью командной строки удаляет альтернативный поток NTFS Zone.Identifier для того, чтобы при запуске не появлялось предупреждение, если файл был скачан из Интернета. Авторы допустили небольшую ошибку в командной строке («cmd.exe /c (echo. > путь к файлу:Zone.Identifier) 2 > Null»), оставив пробел между символами 2 и >, что приводит к появлению ошибки в консоли:
- Метод ElevatePrivilegesProxy() является оболочкой для метода ElevatePrivileges(), который в свою очередь использует известную технику обхода UAC, описанную Мэттом Нельсоном aka enigma0x3.
Затем управление передается на классическую точку входа — метод Main(), который находится в классе Form5:
Видно, что после тридцатисекундной паузы происходит получение объекта WMI. Затем, настраивается объект ScriptControlClassInstance, которому передается язык (Visual Basic script) и тело скрипта:
Метод AddCode() добавляет и исполняет VB-скрипт, который запускает текущую сборку с помощью InstallUtil.exe. Далее вызовом Environment.Exit(0) происходит закрытие текущего процесса.
На следующем этапе вредоносный объект запускается с помощью утилиты InstallUtil, снова отрабатывает статический конструктор класса FirstMainClass, рассмотренный выше, и управление передается статическому конструктору класса InstallUtilEntryClass, который, как упоминалось ранее, наследуется от System.Configuration.Install.Installer:
Функции этого класса включают в себя:
- Копирование собственного вредоносного файла в %APPDATA%\program\msexcel.EXE, установка атрибутов Hidden+System для папки program, запуск msexcel.EXE и завершение текущего процесса;
- Добавление скопированного файла в автозагрузку (HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run или HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run);
- Cоздание задачи с именем «filesqmaepq0d.tnk», которая запускает msexcel.EXE каждую минуту для обеспечения выживания на компьютере жертвы;
- Проверку, запущен ли уже вредоносный процесс. Создается событие с именем «78759961M» и, если такое событие уже есть в системе, то новый процесс завершается;
- Создание класса «Form5» и вызов его деструктора.
Подведем промежуточные итоги: все вышеописанные действия (закрепление в системе, повышение привилегий, запуск из доверенного приложения) являются по сути вспомогательными, закладывающими фундамент для главной задачи. Перейдем к анализу следующего этапа подготовительных действий, которые приблизят нас к сути деятельности зловреда.
Вредоносная сборка помимо всего прочего содержит пять классов, которые наследуются от System.Windows.Forms.Form. Наследование от класса Form выбрано не случайно: в своей иерархии наследования он реализует несколько интерфейсов, один из которых — IDisposable, что позволяет переопределить метод Dispose() для своих целей. Методы Dispose() вызываются сборщиком мусора с целью освобождения неуправляемых ресурсов, используемых классом при закрытии или выгрузке сборки. Теперь посмотрим на исходный код метода Dispose() класса Form5:
Как мы видим, на каждой итерации цикла происходит выполнение различных методов и сохранение результатов. Рассмотрим подробнее:
- На первой итерации происходит получение полного пути к утилите RegAsm.exe из состава .NET Framework;
- Вызывается цепочка вложенных методов, цель которых — раскодировать из Base64 строки, хранящиеся в другом классе, и распаковать полученный массив с помощью библиотеки SevenZipExtractor. В результате мы получаем массив, который является утилитой удаленного администрирования NanoCore Client;
- Загружается библиотека PERun.dll из сборки, которая ранее была распакована из ресурса в память;
- В этой библиотеке ищется класс с именем RunPE и метод Run этого класса;
- На последней итерации происходит передача параметров и вызов метода Run.
Зная, что переменная legalProgramPath содержит полный путь к легальной утилите RegAsm.exe, PEFileByteArray содержит исполняемый файл в виде массива байт, а имя класса — RunPE, легко догадаться, что в методе Run() используется техника сокрытия вредоносного кода в адресном пространстве доверенного процесса RunPE. Эта техника широко известна и описана, например, здесь.
В недрах метода Run() создается процесс легальной утилиты в состоянии CREATE_SUSPENDED (шестой параметр – 4u):
В конечном итоге, в адресное пространство процесса RegAsm.exe загружается и запускается на выполнение полезная нагрузка: утилита удаленного администрирования NanoCore Client. В списке запущенных процессов остаются только доверенные процессы и даже опытному пользователю будет сложно понять, что его система скомпрометирована:
Выбор RegAsm.exe в качестве «носителя» можно объяснить тем, что, во-первых, это легальная утилита от Microsoft, во-вторых, она находится в том же каталоге, что и InstallUtil.exe, а в-третьих, вызов утилитой из .NET Framework другой утилиты из этого же фреймворка вызовет меньше подозрений, чем вызов, например, notepad.exe. По сути, использование RegAsm.exe не принципиально: «носителем» может быть любая программа, лишь бы она вызывала меньше подозрений у защитного ПО и пользователей. Важно и то, что все действия с вредоносным модулем выполняются в памяти, что позволяет обходить файловые сканеры.
Данный образец, как уже было сказано, содержит NanoCore Client, который позволяет скрытно управлять компьютером жертвы, делать снимки экрана, записывать нажатия клавиш, скачивать файлы и многое другое. Стоит отметить, что полезная нагрузка в данном случае может быть чем угодно: от «модных» сегодня шифровальщиков и майнеров до продвинутых троянцев.
Заключение
Авторы вредоносных программ идут на различные ухищрения для сокрытия вредоносной активности, и рассмотренная техника, позволяющая выполнять вредоносный код в контексте двух легальных программ, яркое тому подтверждение. Чтобы обнаружить такую методику сокрытия, необходимо анализировать поведение программы. Защитные решения «Лаборатории Касперского» детектируют данное поведение как PDM: Trojan.Win32.Generic и PDM: Exploit.Win32.Generic.
IOC (MD5)
263DC85DE7EC717E8940B1CCDD6EE119 payload: EF8AF3D457DBE875FF4E3982B34F1DE9
3E4825AA1C09E27C2E6A1309BE8D6382 payload: 82709B139634D74DED404A516B7952F0
7E3863F827C1696835A49B8FD7C02D96 payload: D1A9879FFCB14DF70A430E59BFF5EF0B
8CB8F81ECF1D4CE46E5E96C866939197 payload: D8652841C19D619D2E3B5D7F78827B6E
FDF4086A806826503D5D332077D47187 payload: BF4A3F4B31E68B3DE4FB1F046253F2D0
Использование легитимных утилит для сокрытия вредоносного кода