В этой статье я покажу, как воору­жить standalone-интер­пре­татор Python для заг­рузки опас­ных зависи­мос­тей пря­мо в память при помощи инс­тру­мен­та Pyramid (не путать с веб‑фрей­мвор­ком). Потен­циаль­но это поз­воля­ет обой­ти анти­вирус­ную защиту при пен­тесте и скрыть источник подоз­ритель­ной телемет­рии от EDR при опе­раци­ях Red Team.

Сколь­ко есть раз­ных тех­ник обхо­да анти­вирус­ных механиз­мов и EDR-решений — и не сос­читать! Обфуска­ция и шиф­рование полез­ной наг­рузки, динами­чес­кое раз­решение WinAPI, сис­темные вызовы, отло­жен­ное исполне­ние, укло­нение от хуков защит­ных про­дук­тов, под­пись .exe спу­фан­ными сер­тифика­тами, флук­туирующие начин­ки, под­мена сте­ка вызовов... Кажет­ся, этот спи­сок мож­но про­дол­жать бес­конеч­но.

А если пред­положить, что сущес­тву­ют такие «сле­пые» зоны, оста­ваясь в пре­делах которых мож­но без­наказан­но тво­рить что заб­лагорас­судит­ся (в гра­ницах разум­ного) и не боять­ся при этом спа­лить весь ред­тиминг? Что ж, такие зоны дей­стви­тель­но есть, и это никакой не Ring 0, а обыч­ный интер­пре­татор Python! На питоне написа­но огромное количес­тво нас­тупатель­ных ути­лит, но запус­кать их при­нято с уда­лен­ной машины. Почему? Ах да, зависи­мос­ти...

Се­год­ня мы с тобой раз­берем под­ход Living-Off-the-Blindspot, пред­став­ленный иссле­дова­телем Диего Кап­риот­ти (@naksyn) на недав­нем DEF CON 30.

warning

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

 

Что к чему и почему

Да­вай спер­ва оки­нем взо­ром теорию и раз­берем­ся, почему твой анти­вирус (или EDR) зна­ет о тебе все, потом пой­мем прин­цип бес­фай­лового импорта модулей в Python, а затем перей­дем к рас­смот­рению его реали­зации в Pyramid. Для пер­вых двух час­тей я вос­поль­зуюсь слай­дами ори­гиналь­ного выс­тупле­ния.

Пер­вое, на чем хочет­ся заос­трить вни­мание, — это две самые любимые тех­ники раз­работ­чиков защит­ного соф­та для ана­лиза поведе­ния прог­рамм:

  • ху­ки Windows API (Win32 или Native) в поль­зователь­ском прос­транс­тве;
  • под­писка на уве­дом­ления о чувс­тви­тель­ных событи­ях в прос­транс­тве ядра.
 

Хуки в userland

EDR VISIBILITY — Usermode Hooks (изображение — Python vs Modern Defenses)
EDR VISIBILITY — Usermode Hooks (изоб­ражение — Python vs Modern Defenses)

Что­бы отсле­живать зло­упот­ребле­ние механиз­мами Windows API, твой анти­вирус, ско­рее все­го, пат­чит джам­пами реали­зации фун­кций из биб­лиотек user32.dll и ntdll.dll пос­ле их заг­рузки в память ана­лизи­руемым про­цес­сом. Пос­ле вызова таких, казалось бы, ори­гиналь­ных фун­кций WinAPI ничего не подоз­рева­ющий про­цес­сор натал­кива­ется на соот­ветс­тву­ющий джамп, ука­зыва­ющий на область памяти уже под­гру­жен­ной биб­лиоте­ки средс­тва защиты, и сле­дует по нему, в резуль­тате чего кон­троль над потоком выпол­нения прог­раммы переда­ется анти­виру­су.

Те­перь «вирусо­нена­вис­тник» может как угод­но измы­вать­ся над тво­им про­цес­сом, иссле­дуя его вир­туаль­ную память и про­водя дру­гие одно­му богу извес­тные про­вер­ки, по резуль­татам которых будет вынесен вер­дикт: «виновен» (заб­локиро­вать выпол­нение API-фун­кции или, может, вооб­ще убить про­цесс) или «оправдан» («отпустить» поток выпол­нения исходной прог­рамме).

Что‑то похожее мы про­вора­чива­ли, ког­да экспе­римен­тирова­ли с тех­никой флук­туирующе­го шелл‑кода. Тог­да наш джамп (патч для перех­вата кон­тро­ля над фун­кци­ей kernel32!Sleep) выг­лядел при­мер­но так:

/*
{ 0x49, 0xBA, 0x37, 0x13, 0xD3, 0xC0, 0x4D, 0xD3, 0x37, 0x13, 0x41, 0xFF, 0xE2 }
Disassembly:
0: 49 ba 37 13 d3 c0 4d movabs r10,0x1337d34dc0d31337
7: d3 37 13
a: 41 ff e2 jmp r10
*/
uint8_t trampoline[] = {
0x49, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov r10, addr
0x41, 0xFF, 0xE2 // jmp r10
};

www

Я уже рекомен­довал статью @ShitSecure A tale of EDR bypass methods, где дос­тупным язы­ком разоб­раны популяр­ные при­емы, которые при­меня­ются средс­тва­ми защиты, и спо­собы их обхо­да. Пов­торение — мать уче­ния, и к тому же там тоже есть про хуки в userland.

 

Уведомления обратного вызова в ядре

EDR VISIBILITY — Kernel Callbacks (изображение — Python vs Modern Defenses)
EDR VISIBILITY — Kernel Callbacks (изоб­ражение — Python vs Modern Defenses)

Ку­да более мощ­ный механизм сох­ранения кон­тро­ля над поведе­нием про­цес­сов реали­зует­ся через ядер­ный механизм Notification Callback Routines. Он пре­дос­тавля­ет интерфей­сы для реали­зации фун­кций под­писки на потен­циаль­но опас­ные события, нап­ример вызов ntdll!NtCreateProcess. Ког­да получе­но уве­дом­ление о соз­дании нового про­цес­са, EDR бежит внед­рять свои биб­лиоте­ки в целевой про­цесс, что­бы в том чис­ле иметь воз­можность пат­чить стан­дар­тные биб­лиоте­ки Windows API, как опи­сано в пре­дыду­щем раз­деле.

Дру­гой показа­тель­ный при­мер того, зачем нуж­ны Kernel Callbacks, — тай­млайн зап­рета получе­ния дос­тупа к памяти про­цес­са lsass.exe, опи­сан­ный в дру­гом кру­том ресер­че с DEF CON 30 — EDR detection mechanisms and bypass techniques with EDRSandBlast авто­ров @th3m4ks и @_Qazeer.

How come the EDR knows everything? (изображение — EDR detection mechanisms and bypass techniques with EDRSandBlast)
How come the EDR knows everything? (изоб­ражение — EDR detection mechanisms and bypass techniques with EDRSandBlast)

Так, получая уве­дом­ления о нежела­тель­ных событи­ях на каж­дом из эта­пов дам­па LSASS (соз­дание про­цес­са дам­пера, получе­ние им хен­дла lsass.exe, чте­ние памяти lsass.exe, соз­дание фай­ла с резуль­тиру­ющим слеп­ком памяти), анти­вирус или EDR может выс­тро­ить мно­гоуров­невую за­щиту от получе­ния зло­умыш­ленни­ком учет­ных дан­ных из памяти сетево­го узла.

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

 

Слепые зоны EDR

Пирамида боли редтимера
Пи­рами­да боли ред­тимера

В исходной статье автор раз­деля­ет стра­тегии бай­паса EDR на четыре основные области. Мы сок­ратим их до трех:

  1. Свес­ти к миниму­му свое при­сутс­твие на узле, где уста­нов­лен EDR. Для это­го дос­таточ­но иметь SOCKS-прок­си на сто­роне жер­твы и мар­шру­тизи­ровать через него тра­фик во внут­реннюю сеть или к локаль­ным ресур­сам машины (Impacket тебе в помощь).
  2. Всту­пить в апри­орно нерав­ный бой с EDR: анху­кать биб­лиоте­ки, крип­товать свой арсе­нал до посине­ния, жить с sleep 100500, выпол­няя по одной коман­де в сут­ки, думать о рис­ках каж­дого вве­ден­ного в кон­соль сим­вола. Это слож­но (очень). Обыч­но это мож­но себе поз­волить, если весь твой инс­тру­мен­тарий кас­томный, но, как люди исполь­зуют ту же «Кобу» (зап­рещен­ный на тер­ритории РФ инс­тру­мент) на про­ектах, я пока так и не понял.
  3. Опе­риро­вать из сле­пых зон EDR. Сюда мож­но отнести исполь­зование легитим­ных тулз адми­нис­три­рова­ния и раз­работ­ки во вре­донос­ных целях, нап­ример воору­жить офи­циаль­ный (и под­писан­ный) бинарь Python для мал­варно­го трей­дкраф­та пря­мо на машине‑жер­тве.

Что про­исхо­дит внут­ри интер­пре­тато­ра Python и как трак­товать те или иные мар­керы его поведе­ния? «А черт его зна­ет...» — так отве­тят не толь­ко боль­шинс­тво из нас, но и мно­гие вен­доры защит­ного ПО. Для нас пре­лесть это­го язы­ка в том, что, начиная с вер­сии 3.7, офи­циаль­ная сбор­ка интер­пре­тато­ра пос­тавля­ется в standalone-виде, то есть не тре­бует уста­нов­ки на хост.

Кро­ме того, до тех пор, пока мы оста­емся в пре­делах интер­пре­тато­ра (то есть не выпол­няем инжекты в дру­гие про­цес­сы или не соз­даем новых), вся телемет­рия исхо­дит от под­писан­ного python.exe, а это не облегча­ет жизнь защит­ному ПО, ког­да надо раз­бирать­ся, что из это­го есть что.

Итак, что же нам нуж­но, что­бы воору­жить standalone-интер­пре­татор Python?

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

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

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

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