Ка­залось бы, мак­ровиру­сы дав­но и без­воз­врат­но ушли в прош­лое. Уж что‑что, а вре­донос­ные мак­росы в докумен­тах Office сов­ремен­ные анти­вирус­ные прог­раммы дол­жны обна­ружи­вать лег­ко и неп­ринуж­денно. Имен­но так и обсто­ят дела, если мак­рос, конеч­но, не обфусци­рован. Эффектив­ными при­ема­ми обхо­да анти­вирус­ного детек­та злов­редных VBA-мак­росов поделил­ся в сво­ей пуб­ликации незави­симый иссле­дова­тель Брен­дан Ортиз, а мы рас­ска­жем о его изыс­кани­ях тебе.

Го­товясь к сер­тифика­ции OSEP, Брен­дан Ортиз навер­няка выпил вед­ро кофе и перело­патил гигабай­ты тех­ничес­кой докумен­тации. Нас­чет кофе мы не уве­рены, а вот то, что резуль­татом этой под­готов­ки ста­ло мас­штаб­ное и под­робное иссле­дова­ние спо­собов зак­ладки VBA-мак­росов в самые обыч­ные докумен­ты Word, не под­лежит никако­му сом­нению. Брен­дан убе­дил­ся, что на сай­те antiscan.me (аль­тер­натива virustotal.com) ори­гиналь­ный файл обна­ружи­вал­ся как минимум 7 анти­вирус­ными движ­ками из 20. Тог­да он всерь­ез взял­ся за обфуска­цию сво­их художеств и смог в ито­ге сбить показа­тель детек­тирова­ния до 2 из 20. Пос­коль­ку анти­вирус­ные базы пери­оди­чес­ки обновля­ются, со вре­менем этот параметр вырос с 2 до 5. Но все рав­но — резуль­тат получил­ся впе­чат­ляющий.

warning

Вся информа­ция в этой статье при­водит­ся исклю­читель­но в озна­коми­тель­ных целях, автор и редак­ция не несут никакой ответс­твен­ности за пос­ледс­твия исполь­зования этой пуб­ликации. Пре­дуп­режда­ем, что при выпол­нении мак­росов в докумен­тах Microsoft на тво­ем устрой­стве могут быть спро­воци­рова­ны нежела­тель­ные дей­ствия.

 

Проверка эмуляции

Мно­гие анти­виру­сы, исполь­зующие для детек­тирова­ния вре­доно­сов эвристи­ку, запус­кают VBA-скрип­ты в «песоч­нице» с целью убе­дить­ся в их безопас­ности. Поэто­му нас­тоящие вирусо­писа­тели в пер­вую оче­редь про­веря­ют, работа­ет ли их сце­нарий в эму­лиро­ван­ной сре­де, и, если так, оста­нав­лива­ют выпол­нение вре­донос­ного пей­лоада, что­бы анти­вирус не забил тре­вогу.

Брен­дан Ортиз пред­ложил три прос­тых тес­та для опре­деле­ния эму­лято­ра. Эти тес­ты рас­полага­ются в самом начале соз­данно­го им мак­роса и не поз­воля­ют ему выпол­нить никаких злов­редных дей­ствий, если обна­ружит­ся, что скрипт запущен в изо­лиро­ван­ной сре­де.

Первая проверка
Пер­вая про­вер­ка

Пер­вый тест иссле­дова­тель наз­вал Document Name. Во мно­гих слу­чаях, ког­да анти­вирус­ный дви­жок эму­лиру­ет выпол­нение мак­роса VBA, он меня­ет имя докумен­та либо добав­ляет к это­му име­ни некото­рое чис­ло, что­бы отсле­дить и пре­дот­вра­тить мно­гок­ратный запуск скрип­та. Этот тест про­веря­ет, сов­пада­ет ли с име­нем ори­гиналь­ного докумен­та имя того докумен­та, в котором выпол­няет­ся полез­ная наг­рузка.

Что­бы зашиф­ровать ста­тичес­кую стро­ку, в которой хра­нит­ся имя докумен­та, исполь­зует­ся сце­нарий PowerShell, а затем во вре­мя выпол­нения скрип­та для ее рас­шифров­ки вызыва­ется собс­твен­ная фун­кция Joy. Если имя активно­го докумен­та не сов­пада­ет с ука­зан­ным име­нем, про­вер­ка счи­тает­ся не прой­ден­ной и выпол­няет­ся выход из под­прог­раммы.

На вто­ром эта­пе про­веря­ется путь. Если мы заранее зна­ем, из какой пап­ки будет открыт документ с вре­донос­ным сце­нари­ем (нап­ример, из пап­ки «Заг­рузки» поль­зовате­ля Windows), то мы можем срав­нить ее с текущим путем. Несов­падение пути ука­жет на то, что скрипт, ско­рее все­го, работа­ет в анти­вирус­ном движ­ке. В этом слу­чае мы так­же выходим из под­прог­раммы.

На­конец, прос­той тест на вре­мя. Ког­да скрипт выпол­няет­ся в эму­лято­ре анти­виру­са, тот обыч­но про­пус­кает фраг­менты кода, в которых реали­зова­на пауза или «засыпа­ние», ина­че любящие «пос­пать» мак­ровиру­сы поп­росту завесят дви­жок. Поэто­му Брен­дан пред­ложил сле­дующую нехит­рую про­вер­ку: фик­сиру­ем акту­аль­ное вре­мя, «спим» две секун­ды, а затем про­сыпа­емся и вновь фик­сиру­ем вре­мя. Если раз­ница меж­ду дву­мя эти­ми зна­чени­ями сос­тавит мень­ше двух секунд, ско­рее все­го, мы в анти­вирус­ном движ­ке. В этом слу­чае под­прог­рамма так­же завер­шает­ся.

Ес­ли все три про­вер­ки завер­шились пол­ным и безого­вороч­ным успе­хом, мак­рос перехо­дит к выпол­нению полез­ной наг­рузки, которая выг­лядит при­мер­но так, как показа­но на сле­дующем рисун­ке.

Полезная нагрузка
По­лез­ная наг­рузка
 

Несколько слов об AMSI

В ходе сво­их экспе­римен­тов Брен­дан Ортиз выяс­нил, что понача­лу его вре­донос­ный мак­рос успешно детек­тировал­ся эвристи­кой боль­шинс­тва анти­вирус­ных движ­ков. Кро­ме того, нес­мотря на мно­гочис­ленные попыт­ки иссле­дова­теля запус­тить мак­рос при вклю­чен­ной защите Windows Defender, сис­тема уби­вала скрипт. По какой же при­чине мак­рос помечал­ся как вре­донос­ный? Все дело в том, что интерфейс Anti-Malware Scan Interface (AMSI) заг­лядыва­ет в сце­нарий VBA и кон­тро­лиру­ет его поведе­ние.

Принцип работы AMSI
Прин­цип работы AMSI

AMSI — это раз­работан­ный Microsoft интерфейс, который прис­пособ­лен к работе с любыми анти­виру­сами и поз­воля­ет им зап­рашивать информа­цию о про­цес­сах, про­исхо­дящих во вре­мя исполне­ния прог­рамм. Это зна­чит, что анти­виру­су переда­ются даже бес­фай­ловые угро­зы, нап­ример коман­ды PowerShell, если анти­вирус вызыва­ет AMSI. Еще это озна­чает, что ты можешь как угод­но обфусци­ровать полез­ную наг­рузку, но, как толь­ко она деоб­фусци­рует­ся во вре­мя выпол­нения, AMSI нач­нет отсле­живать поведе­ние кода.

Ког­да поль­зователь пыта­ется выпол­нить коман­ду в PowerShell, AMSI сна­чала заг­ружа­ет, а затем про­веря­ет эту коман­ду. Если обна­ружи­вают­ся какие‑либо эле­мен­ты, которые обыч­но исполь­зуют­ся для вре­донос­ных дей­ствий, в час­тнос­ти вызовы API Win32 или COM (то есть сра­баты­вают заложен­ные в AMSI «триг­геры»), то AMSI при­оста­нав­лива­ет подоз­ритель­ный про­цесс.

На кар­тинке ниже показа­но, как VBA интегри­рует­ся с AMSI. С уче­том все­го это­го иссле­дова­тель стал искать спо­собы усколь­знуть от прис­таль­ного вни­мания AMSI при выпол­нении скрип­тов VBA и PowerShell.

Интеграция AMSI с JavaScript/VBA
Ин­тегра­ция AMSI с JavaScript/VBA
 

Импорт Windows API в VBA

На­чать Брен­дан решил с импорта фун­кций. Что­бы про­пат­чить AMSI в памяти, необ­ходим дос­туп к некото­рым низ­коуров­невым биб­лиоте­кам и фун­кци­ям Windows. В VBA раз­решено импорти­ровать API Windows для исполь­зования в мак­росе. Такая воз­можность радикаль­но рас­ширя­ет фун­кци­ональ­ность VBA.

Зло­умыш­ленник, вызывая опре­делен­ные API Windows из VBA, C#, PowerShell и т. д., дол­жен хорошень­ко в них разоб­рать­ся, что­бы все сде­лать пра­виль­но. Дело в том, что натив­ные фун­кции для этих целей в соот­ветс­тву­ющих язы­ках отсутс­тву­ют. Но, воору­жив­шись некото­рыми «под­готови­тель­ными зна­ниями», запол­нить эти про­белы доволь­но лег­ко. Ког­да ты зна­ешь, какие API Windows хочешь импорти­ровать, для начала обя­затель­но погуг­ли соот­ветс­тву­ющую докумен­тацию Microsoft. Там ты най­дешь под­робную информа­цию об инте­ресу­ющей тебя фун­кции, в час­тнос­ти каковы ее воз­вра­щаемые зна­чения, какие парамет­ры она при­нима­ет, в какой DLL находит­ся инте­ресу­ющий тебя API. Так ты получишь по‑нас­тояще­му хорошее пред­став­ление о событи­ях, про­исхо­дящих «под капотом» скрип­та.

Брен­дан исполь­зовал в сво­ем мак­росе объ­явле­ние PInvoke (Platform-Invoke, «Плат­формен­ный вызов»). PInvoke — это кол­лекция опре­деле­ний для вызова натив­ных фун­кций API Windows из язы­ков прог­рамми­рова­ния, в которых может отсутс­тво­вать такая низ­коуров­невая фун­кци­ональ­ность. Осо­бен­ности работы это­го инс­тру­мен­та под­робно опи­саны вот на этом сай­те. Там мож­но най­ти дек­ларации для импорта API в раз­личные сце­нарии на все слу­чаи жиз­ни.

 

Обход AMSI

Им­порт необ­ходимых API Windows в VBA — это толь­ко пер­вый шаг. Что­бы при­думан­ный Брен­даном Орти­зом скрипт работал, нуж­но обой­ти AMSI. Для это­го иссле­дова­тель решил про­пат­чить AMSI пря­мо в памяти. А кон­крет­нее — про­пат­чить пер­вые нес­коль­ко бай­тов в фун­кци­ях AmsiScanBuffer и AmsiScanString из биб­лиоте­ки Amsi.dll, заг­ружа­емой из запущен­ного про­цес­са. Эти фун­кции, если верить докумен­тации Microsoft, отве­чают за ска­ниро­вание содер­жимого буфера в поис­ках харак­терных для мал­вари строк.

Патч AMSI
Патч AMSI

Сна­чала объ­явля­ется спи­сок ука­зате­лей перемен­ных для хра­нения адре­сов фун­кций. Затем в перемен­ной lib сох­раня­ется адрес из биб­лиоте­ки amsi.dll, это дела­ется при помощи нап­равля­емо­го к API Windows вызова LoadLib. Все стро­ки в этом пат­че памяти AMSI дол­жны быть обфусци­рова­ны. На пер­вом эта­пе автор скрип­та исполь­зовал для это­го фун­кцию VBA Chr(), что­бы скрыть некото­рые харак­терные стро­ки вро­де amsi.dLl и AmsiUacInitialize.

За­тем нуж­но най­ти, где лежит фун­кция AmsiScanString. Для это­го Брен­дан исполь­зовал фун­кцию Windows API GetProcAddress, пере­име­нован­ную в GetPrAddr. Пос­коль­ку AMSI еще не про­пат­чен, а вре­доно­сы час­то пыта­ются отклю­чить его, нацели­ваясь на фун­кции AmsiScanString и AmsiScanBuffer, автор скрип­та вос­поль­зовал­ся отно­ситель­ной адре­саци­ей, начиная с фун­кции AmsiUacInitialize.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии