Закрепление в системе с использованием WMI
В качестве вступления... Друзья и коллеги мне постоянно твердили, чтобы писал статьи, связанные с анализом вредоносных программ. Но неуверенность в результате, возможно, и в своих силах, а также лень, и прежде всего, лень, постоянно останавливали. Да и потом, сейчас много литературы на эту тематику, и на русский стали переводить достаточно оперативно! Ну, что я нового расскажу, да и вряд ли лучше маститых авторов!? Но все же решил сделать серию публикаций про интересные трюки и оригинальные идеи, выявленные при анализе вредоносных программ, а также и про подходы, которые использовались при анализе. Надеюсь, что публикации будет интересными, а возможности и желания хватит на большую серию, а там уже увидим…
Итак, в качестве первой публикации решил выбрать одну из любимых находок, которая попалась мне в октябре 2016 года. Речь идет об одной из первых реализаций интересной техники закрепления с помощью WMI "Event Triggered Execution: Windows Management Instrumentation Event Subscription" (T1546.003). Вроде и 5 лет прошло, но многие так и не знают про нее, а она ведь не теряет своей актуальности и по сей день. Законтрибьютили эту замечательную технику на MITRE в январе 2020 года двое амиго'с из Elastic: Brent Murphy и David French.
Когда в октябре 2016 года разбирал два образца (закодированный скрипт и файл данных), связанные с майнерами, понял, что выявил нечто новое и оригинальное. На тот момент по данной теме была только публикация "красноглазых" из FireEye, но она больше была с намеками и совершенно без конкретики. Сразу "по горячим следам" решил поделиться результатами с коллегами-антивирусниками. К слову сказать, закодированный скрипт на тот момент успешно детектировался антивирусами. Отправил для оперативности сначала на публичный сервис "Лаборатории Касперского" newvirus, в ответе дежурный аналитик мягко меня "послал". Во второй раз уже отправлял своему знакомому коллеге из "Каспера" с контекстом, и сразу все завертелось, они лихо подхватили и, по его словам, стали докручивать эвристик. А с "Доктор Вебом" получилось куда забавнее: 2 раза отправлял через знакомого в "Веб", и два раза мне отвечали, что ничего интересного не выявили, вредонос детектится. Они искренне не могли понять, что же я хочу от них. На третий раз, как это у нас исстари на Руси водится, но я уже более подробно, с пояснениями расписал свою находку, спецы "Веба" осознали с чем имеют дело, и все сразу сложилось. Было занятно, когда спустя какое-то время, где-то через месяц-два, встречались с руководителем вирлаба "Доктор Веба". И он начал рассказывать про новые выявленные компанией техники и среди прочего начал рассказывать и про мою находку…
– Позвольте! – говорю. – Я же вам эти образцы больше месяца назад отправлял 3 раза…
– Н-да? Хм… Я лично смотрел их. Ах, это были Вы!? Наверное, был поначалу очень сильно занят и посчитал, что это что-то не серьезное… Ну раз вы знакомы с данной техникой… Тогда скипаю… И это скипаю… тоже скипаю… Итак, следующая выявленная нами новая техника…
Образцы на VT:
Кстати, iisstt.dat, о котором в основном пойдет речь дальше, сейчас только "Доктор Веб" и детектит :-)
Никакой контекстной информации по образцам не было, только то, что выявлены были на одном компьютере.
Смотрим на содержимое файлов.
В файле iisstt.dat сразу бросаются в глаза сигнатура "FOMB" (или "BMOF" – соответственно для 32-битного числа little-endian 424D4F46h
) и далее после нее поля какого-то заголовка.
Итак, по порядку. z.zip – тот самый закодированный скрипт-загрузчик, который детектировался антивирусами. Скрипт закодирован штатным средством Microsoft Script Encoder. Для декодирования можно, например, воспользоваться очень старенькой опенсорсной утилитой scrdec.exe авторства некоего MrBrownstone.
Результат декодирования:
Скрипт предназначен для загрузки из интернета на компьютер других файлов и их запуска. В нем есть зашифрованные строки, и функция расшифровки ниже с тонко намекающим названием DCaesar.
Function DCaesar(str,offset)
Dim length,char,i
DCaesar = ""
length = Len(str)
For i = 1 To length
char = Mid(str,i,1)
If char >= "A" And char <= "Z" Then
char = Asc("Z") - (Asc("Z") - Asc(char) + offset) Mod 26
DCaesar = DCaesar & Chr(char)
ElseIf char >= "a" And char <= "z" Then
char = Asc("z") - (Asc("z") - Asc(char) + offset) Mod 26
DCaesar = DCaesar & Chr(char)
Else
DCaesar = DCaesar & char
End If
Next
End Function
Function MDnStr(OldStr,Pwd)
Dim newstr:newstr = ""
length = Len(Pwd)
lengthstr = Len(OldStr)
For i = 1 To lengthstr
char = Mid(OldStr,i,1)
p = i Mod length
If p = 0 Then p = 1
p = Mid(Pwd,p,1)
newstr = newstr & DCaesar(char,p)
Next
MDnStr = newstr
End Function
Все кажется просто, бери и расшифровывай. Только вот хитрые злоумышленники ключ для расшифровки передают в качестве параметра командной строки VBS-скрипта, это видно на картинке выше, с декодированным скриптом:
strpwd=WScript.Arguments(1)
Но определить ключ совершенно несложно, по зашифрованным строкам, ведь очевидно же, что "macu" в начале строки со ссылкой – это "http", и так далее. В итоге получаем ключ "moqmnjplm". Кстати, теперь стало понятно чем обусловлено поведение антивирусников поначалу, и винить их в этом особо не следует: ежедневно на них льется всякий шлак в больших количествах. Скрипт детектируется, ссылки связаны с майнерами, зачем тратить время и что-то там еще расшифровывать, когда вроде бы все и так очевидно.
Вот это, кстати, яркий пример того, что при анализе малвари надо соблюдать некий баланс: не пропускать важные детали, но при этом не зарываться в ненужных мелочах и не тратить на них драгоценное время. Для этого, конечно, определенно нужен некоторый опыт. Отвлечемся на философию и поговорим вообще про качества реверсера. Занимаюсь реверсом ну, очень давно, и также достаточно давно сформулировал для себя основные качества хорошего реверсера. Их всего три, в порядке важности, по моей субъективной теории. Это интерес, упрямство и интуиция! Знания и опыт, конечно, важны, но они не так критичны, они легко приобретаются со временем, при наличии перечисленных выше качеств, а это уже больше свойства и черты характера. Интерес – это основной двигатель познания чего-то нового. Упрямство – это способность не сдаваться при первых сложностях, а продолжать добиваться цели, пока не достигнешь ее. А интуиция, как многие врачи считают, чуть ли не одно из основных качеств талантливого хирурга. А чем реверсер не хирург!? Или все же патологоанатом, помните картинку на одной отличной книжке по анализу малвари :-)
Короче, тогда не поленился, переделал вредоносный скрипт, чтобы он сам расшифровал все строки.
Когда среди других строк расшифровал выделенную выше строку, весьма был удивлен:
mofcomp.exe c:\windows\temp\iisstt.dat
Компиляция MOF-файла! Неожиданно! Утилита mofcomp.exe предназначена для компиляции MOF-файлов с целью изменения структуры WMI, причем эти изменения в результате компиляции вносятся непосредственно в репозиторий WMI. BMOF-файлы (Binary MOF-файлы) – это скомпилированные MOF-файлы, изначальное их предназначение – использование в системных драйверах, данные BMOF хранятся в ресурсе "MOFDATA" многих драйверов Windows. Изучив техническую документацию по WMI, злоумышленники посчитали отличной идеей использовать BMOF для завуалированного закрепления в системе с помощью репозитория и событий WMI.
Также после расшифровки строк стало понятно, что файл iisstt.dat помимо прочих файлов был загружен VBS-скриптом z.zip.
Пытливый ум реверсера всегда ищет короткий путь. Почему-то на глаза первым попался файл из дистрибутива Windows 98:
wmimofck.exe ("WMI Mof checking tool")
SHA-256: b704d8f8dbf9e9c474ead751649bec37e59655e658678bc13836dcce4155d640)
Эта утилита предназначена для проверки MOF-файлов, если на вход подается BMOF-файл, то он перед проверкой распаковывается. Чем не вариант!? Почему эта утилита была только в Windows 98 осталось загадкой. Работа реверсера не должна быть похожа на постоянное изобретение велосипеда, на каждом этапе надо искать, кто-то мог сделать это до вас. Но искать, правда, надо еще уметь делать, этому обязательно следует учиться! Ну, а если нашли, следует проверить, что найденное соответствует тому, что вы исследуете. Согласитесь, проверять ведь намного легче, чем начинать что-то с нуля!?
В старой доброй "ольке" (OllyDbg v1.10) нашел место, где содержимое BMOF распаковывается. Сначала я написал скрипт для "ольки", чтобы распакованное содержимое BMOF просто дампилось в отладчике. Ну а потом, рассудил, как "опытный реверсер", что вот де польется поток этой новой малвари, как это бывало уже не раз, и надо быть готовым к этому и иметь готовый инструмент, который можно было бы максимально просто и быстро использовать. А вот разбираться в формате BMOF на данном этапе, как всегда, нет ни времени, ни возможности. Поэтому решил взять и просто "инфицировать" wmimofck.exe.
Инфицирование wmimofck.exe
Разница между виртуальным и физическим размерами кодовой секции wmimofck.exe составляет целые 1 852 байта, в которые можно вместить очень много кода, без дополнительных телодвижений. Поэтому решил увеличить просто виртуальный размер кодовой секции и поместить в свободную область в конце секции код, сохраняющий в файл распакованное содержимое BMOF.
Единственная маленькая загвоздка – отсутствовала импортируемая функция WriteFile, пришлось вручную поправить импорт для добавления WriteFile. Как вариант, можно было найти в экспорте загруженной kernel32.dll через PEB, но так, мне кажется, сложнее.
В итоге из штатной тулзы проверки MOF-файлов из Windows 98 получился распаковщик BMOF bmfunp.exe, к функциональности доработанной оригинальной программы после небольших усилий добавилось сохранение распакованного содержимого данных BMOF.
Чтобы извлечь содержащуюся в BMOF полезную нагрузку не понадобился парсер BMOF. Полезной нагрузкой оказался вот такой VBS-скрипт:
Отличный скрипт от злоумышленников! Открывает доступ по RDP, уведомляет об этом злоумышленников путем открытия ссылки, также загружает по другой ссылке и выполняет произвольный VBS-код. А, самое, главное, что при выполнении команды mofcomp.exe c:\windows\temp\iisstt.dat
этот скрипт помещается непосредственно в репозиторий WMI и регистрируется как обработчик события WMI, в результате чего будет запускаться ежедневно в 23:00:00.
И файл iisstt.dat больше не нужен, новых файлов на диске при закреплении не создается, все в недрах WMI.