Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Казалось бы, макровирусы давно и безвозвратно ушли в прошлое. Уж что‑что, а вредоносные макросы в документах Office современные антивирусные программы должны обнаруживать легко и непринужденно. Именно так и обстоят дела, если макрос, конечно, не обфусцирован. Эффективными приемами обхода антивирусного детекта зловредных VBA-макросов поделился в своей публикации независимый исследователь Брендан Ортиз, а мы расскажем о его изысканиях тебе.
Готовясь к сертификации OSEP, Брендан Ортиз наверняка выпил ведро кофе и перелопатил гигабайты технической документации. Насчет кофе мы не уверены, а вот то, что результатом этой подготовки стало масштабное и подробное исследование способов закладки VBA-макросов в самые обычные документы Word, не подлежит никакому сомнению. Брендан убедился, что на сайте antiscan.me (альтернатива virustotal.com) оригинальный файл обнаруживался как минимум 7 антивирусными движками из 20. Тогда он всерьез взялся за обфускацию своих художеств и смог в итоге сбить показатель детектирования до 2 из 20. Поскольку антивирусные базы периодически обновляются, со временем этот параметр вырос с 2 до 5. Но все равно — результат получился впечатляющий.
warning
Вся информация в этой статье приводится исключительно в ознакомительных целях, автор и редакция не несут никакой ответственности за последствия использования этой публикации. Предупреждаем, что при выполнении макросов в документах Microsoft на твоем устройстве могут быть спровоцированы нежелательные действия.
Многие антивирусы, использующие для детектирования вредоносов эвристику, запускают VBA-скрипты в «песочнице» с целью убедиться в их безопасности. Потому настоящие вирусописатели в первую очередь проверяют, работает ли их сценарий в эмулированной среде, и, если так — останавливают выполнение вредоносного пейлоада, чтобы антивирус не забил тревогу.
Брендан Ортиз предложил три простых теста для определения эмулятора. Эти тесты располагаются в самом начале созданного им макроса и не позволяют ему выполнить никаких зловредных действий, если обнаружится, что скрипт запущен в изолированной среде.
Первая проверка
Первый тест исследователь назвал «Document Name». Во многих случаях, когда антивирусный движок эмулирует выполнение макроса VBA, он меняет имя документа либо добавляет к этому имени некоторое число, чтобы отследить и предотвратить многократный запуск скрипта. Этот тест проверяет, совпадает ли с именем оригинального документа имя того документа, в котором выполняется полезная нагрузка.
Чтобы зашифровать статическую строку, в которой хранится имя документа, используется сценарий PowerShell, а затем во время выполнения скрипта для ее расшифровки вызывается собственная функция Joy
. Если имя активного документа не совпадает с указанным именем, проверка считается непройденной и выполняется выход из подпрограммы.
На втором этапе проверяется путь. Если мы заранее знаем, из какой папки будет открыт документ с вредоносным сценарием (например, из папки «Загрузки» пользователя Windows), то мы можем сравнить ее с текущим путем. Несовпадение пути укажет на то, что скрипт, скорее всего, работает в антивирусном движке. В этом случае мы также выходим из подпрограммы.
Наконец, простой тест на время. Когда скрипт выполняется в эмуляторе антивируса, тот обычно пропускает фрагменты кода, в которых реализована пауза или «засыпание», иначе любящие «поспать» макровирусы попросту завесят движок. Поэтому Брендан предложил следующую нехитрую проверку: фиксируем актуальное время, «спим» две секунды, а затем просыпаемся и вновь фиксируем время. Если разница между двумя этими значениями составит менее 2 секунд, скорее всего, мы в антивирусном движке. В этом случае подпрограмма также завершается.
Если все три проверки завершились полным и безоговорочным успехом, макрос переходит к выполнению полезной нагрузки, которая выглядит примерно так, как показано на следующем рисунке.
Полезная нагрузка
В ходе своих экспериментов Брендан Ортиз выяснил, что поначалу его вредоносный макрос успешно детектировался эвристикой большинства антивирусных движков. Кроме того, несмотря на многочисленные попытки исследователя запустить макрос при включенной защите Windows Defender, система убивала скрипт. По какой же причине макрос помечался как вредоносный? Все дело в том, что интерфейс Anti-Malware Scan Interface (AMSI) заглядывает в сценарий VBA и контролирует его поведение.
Принцип работы AMSI
AMSI — это разработанный Microsoft интерфейс, который приспособлен к работе с любыми антивирусами и позволяет им запрашивать информацию о процессах, происходящих во время исполнения программ. Это значит, что антивирусу передаются даже бесфайловые угрозы, например команды PowerShell, если антивирус вызывает AMSI. Еще это означает, что ты можешь как угодно обфусцировать полезную нагрузку, но как только она деобфусцируется во время выполнения, AMSI начнет отслеживать поведение кода.
Когда пользователь пытается выполнить команду в PowerShell, AMSI сначала загружает, а затем проверяет эту команду. Если обнаруживаются какие‑либо элементы, которые обычно используются для вредоносных действий, в частности, вызовы API Win32 или COM (то есть, срабатывают заложенные в AMSI «триггеры»), то AMSI приостанавливает подозрительный процесс.
На картинке ниже показано, как VBA интегрируется с AMSI. С учетом всего этого исследователь стал искать способы ускользнуть от пристального внимания AMSI при выполнении скриптов VBA и PowerShell.
Интеграция AMSI с JavaScript/VBA
Начать Брендан решил с импорта функций. Чтобы пропатчить AMSI в памяти, необходим доступ к некоторым низкоуровневым библиотекам и функциям Windows. В VBA разрешено импортировать API Windows для использования в макросе. Такая возможность радикально расширяет функционал VBA.
Злоумышленник, вызывая определенные API Windows из VBA, C#, PowerShell и т. д., должен хорошенько в них разобраться, чтобы все сделать правильно. Дело в том, что нативные функции для этих целей в соответствующих языках отсутствуют. Но вооружившись некоторыми «подготовительными знаниями», заполнить эти пробелы довольно легко. Когда ты знаешь, какие API Windows хочешь импортировать, для начала обязательно погугли соответствующую документацию Microsoft. Там ты найдешь подробную информацию об интересующей тебя функции, в частности, каковы ее возвращаемые значения, какие параметры она принимает, в какой DLL находится интересующий тебя API и т. д. Так ты получишь по‑настоящему хорошее представление о событиях, происходящих «под капотом» скрипта.
Брендан использовал в своем макросе объявление PInvoke (Platform-Invoke, «Платформенный вызов»). PInvoke – это коллекция определений для вызова нативных функций API Windows из языков программирования, в которых может отсутствовать такой низкоуровневый функционал. Особенности работы этого инструмента подробно описаны вот на этом сайте. Там можно найти декларации для импорта API в различные сценарии на все случаи жизни.
Импорт необходимых API Windows в VBA — это только первый шаг. Чтобы придуманный Бренданом Ортизом скрипт работал, нужно обойти AMSI. Для этого исследователь решил пропатчить AMSI прямо в памяти. А конкретнее, пропатчить первые несколько байтов в функциях AmsiScanBuffer
и AmsiScanString
из библиотеки Amsi.dll
, загружаемой из запущенного процесса. Эти функции, если верить документации Microsoft, отвечают за сканирование содержимого буфера в поисках характерных для малвари строк.
Патч AMSI
Сначала объявляется список указателей переменных для хранения адресов функций. Затем в переменной lib
сохраняется адрес из библиотеки amsi.dll
, это делается при помощи направляемого к API Windows вызова LoadLib
. Все строки в этом патче памяти AMSI должны быть обфусцированы. На первом этапе автор скрипта использовал для этого функцию VBA Chr()
, чтобы скрыть некоторые характерные строки вроде amsi.dLl
и AmsiUacInitialize
.
Затем нужно найти, где лежит функция AmsiScanString
. Для этого Брендан использовал функцию Windows API GetProcAddress
, переименованную в GetPrAddr
. Поскольку AMSI еще не пропатчен, а вредоносы часто пытаются отключить его, нацеливаясь на функции AmsiScanString
и AmsiScanBuffer
, автор скрипта воспользовался относительной адресацией начиная с функции AmsiUacInitialize
.
Источник: xakep.ru