May 4, 2022

HTB Search. Обходим AMSI в PowerShell Web Access при пентесте машины на Windows

На­ша цель — машина Search с пло­щад­ки Hack The Box. Ее уро­вень слож­ности — hard.

Под­клю­чать­ся к машинам с HTB рекомен­дует­ся толь­ко через VPN. Не делай это­го с компь­юте­ров, где есть важ­ные для тебя дан­ные, так как ты ока­жешь­ся в общей сети с дру­гими учас­тни­ками.

До­бав­ляем IP-адрес машины в /etc/hosts:

И запус­каем ска­ниро­вание пор­тов.

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

На­ибо­лее извес­тный инс­тру­мент для ска­ниро­вания — это Nmap. Улуч­шить резуль­таты его работы ты можешь при помощи сле­дующе­го скрип­та.

Он дей­ству­ет в два эта­па. На пер­вом про­изво­дит­ся обыч­ное быс­трое ска­ниро­вание, на вто­ром — более тща­тель­ное ска­ниро­вание, с исполь­зовани­ем име­ющих­ся скрип­тов (опция -A).

У нас есть целая куча откры­тых пор­тов:

На хос­те работа­ет мно­го служб. Пер­вым делом про­веря­ем SMB и DNS, но они ничего не дают. Оста­ется толь­ко веб. Так как на пор­те 443 исполь­зует­ся про­токол HTTPS, сра­зу обра­тим вни­мание на его сер­тификат. Поле commonName содер­жит домен­ные име­на, для которых дей­стви­телен дан­ный сер­тификат. Nmap показы­вает эти нас­трой­ки в резуль­татах ска­ниро­вания, что поз­воля­ет нам быс­тро опре­делить исполь­зуемое имя. Добав­ляем его в файл /etc/hosts:

Изу­чая сайт, обра­щаем вни­мание на спи­сок сот­рудни­ков.

Так как на хос­те работа­ет Kerberos, мы можем про­верить, сущес­тву­ет ли какая‑то учет­ная запись. В этом нам поможет ата­ка ASRep Roasting. Смысл в том, что мы посыла­ем на сер­вер аутен­тифика­ции ано­ним­ный зап­рос для пре­дос­тавле­ния опре­делен­ному поль­зовате­лю дос­тупа к какой‑либо услу­ге. На что сер­вер отве­чает одним из трех дей­ствий:

Но спер­ва сос­тавим спи­сок поль­зовате­лей. С помощью сле­дующе­го кода мы можем сос­тавить все воз­можные ком­бинации име­ни поль­зовате­ля:

Сох­раним спи­сок в файл и выпол­ним про­вер­ку с помощью kerbrute. Для это­го исполь­зуем опцию renum и ука­жем адрес (--dc), домен (-d) и спи­сок с веро­ятны­ми име­нами учет­ных записей.

Все ска­ниро­вание заняло при­мер­но секун­ду, а мы получа­ем три сущес­тву­ющих акка­унта. С помощью скрип­та GetNPUsers.py из пакета impacket при­меня­ем к получен­ным име­нам ASRep Roasting в надеж­де получить зашиф­рован­ный пароль поль­зовате­ля. Но безус­пешно.

Пот­ратив очень мно­го вре­мени на поиск даль­нейше­го пути, я нашел на сай­те фотог­рафию http://search.htb/images/slide_2.jpg каких‑то записей.

При уве­личе­нии кар­тинки ста­ло понят­но, что это спи­сок дел, сре­ди которых есть такая строч­ка: «Send password to Hope Sharp».

Про­веря­ем это имя и узна­ем, что такой акка­унт в сис­теме есть.

Те­перь мы можем про­верить и ука­зан­ный пароль с помощью CrackMapExec.

И получа­ем пер­вую учет­ку!

Те­перь логич­но пой­ти на SMB и пос­мотреть, что рас­положе­но на дос­тупных ресур­сах.

По­ходив по раз­ным катало­гам, ничего инте­рес­ного не обна­ружи­ваем. Из необыч­ного — лишь дирек­тория RedirectedFolders$, которая выводит нас на домаш­ние катало­ги всех поль­зовате­лей. Прод­винуть­ся даль­ше это не помога­ет, но мож­но получить име­на всех поль­зовате­лей.

В ито­ге получа­ем боль­шой спи­сок поль­зовате­лей. Сох­ранить в файл толь­ко име­на мож­но такой коман­дой:

Вы­пол­няем с ним все те же опе­рации, но ни к чему не при­ходим. Одна­ко мы не поп­робова­ли одно­го...

Ре­али­зация про­токо­ла Kerberos в Windows исполь­зует име­на учас­тни­ков служ­бы (SPN), что­бы опре­делить, какую учет­ную запись задей­ство­вать для шиф­рования билета служ­бы. В Active Directory сущес­тву­ет два вари­анта SPN: SPN на осно­ве хос­та и про­изволь­ные SPN. Пер­вый вари­ант SPN свя­зан с учет­ной записью компь­юте­ра домена, а вто­рой обыч­но (но не всег­да) — с учет­кой поль­зовате­ля домена.

Про­ще говоря, если зап­росить билет, он будет зашиф­рован паролем учет­ной записи, SPN которой был пре­дос­тавлен. И если мы получим билет, мы смо­жем его прос­то проб­рутиь, что­бы узнать пароль учет­ки!

Ав­томати­зация зап­роса имен SPN, а затем еще и билетов выпол­нена в скрип­те GetUserSPNs из набора impacket. Для его исполь­зования дос­таточ­но ука­зать опцию -request.

И есть одна учет­ная запись, которую мы можем попытать­ся зах­ватить, — web_svc. Вот толь­ко билет получить не уда­ется, потому что вре­мя на хос­тах зна­читель­но отли­чает­ся (а в Kerberos эта раз­ница не дол­жна пре­вышать пяти минут). Син­хро­низи­ровать вре­мя на локаль­ном хос­те нам поможет про­токол NTP:

Те­перь пов­торя­ем зап­рос билета и получа­ем хеш!

Сра­зу закиды­ваем его в hashcat и ука­зыва­ем режим 13100 (параметр -m):

По­луча­ем пароль поль­зовате­ля и запус­каем спрей по всем учет­ным записям. Высока веро­ятность, что он будет исполь­зован еще где‑то.

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

От­кры­ваем файл с учет­ными дан­ными и видим скры­тый стол­бец С.

Раз­дви­нуть стол­бцы не выходит, так как лист докумен­та защищен паролем от изме­нения.

Но такую защиту мож­но лег­ко снять. Откро­ем документ как архив и най­дем в нем нас­трой­ки для нуж­ного лис­та. У нас это вто­рой лист, поэто­му нужен файл sheet2.xml.

В этом фай­ле находим и уда­ляем сле­дующую стро­ку, это поле sheetProtection.

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

Те­перь нуж­но про­верить их валид­ность. Для это­го выбира­ем и сох­раня­ем в файл с пароля­ми стол­бец C, а в файл с име­нами учет­ных записей — стол­бец D. Пос­ле это­го переби­раем их с помощью уже при­меняв­шегося CrackMapExec, толь­ко с опци­ей --no-bruteforce. С этой опци­ей CME не будет переби­рать все воз­можные сочета­ния. Вмес­то это­го он исполь­зует для пер­вого име­ни пер­вый пароль из спис­ка, для вто­рого — вто­рой и так далее.

В ито­ге мы получа­ем еще одно­го поль­зовате­ля — Sierra.Frye. А на рабочем сто­ле это­го юзе­ра есть пер­вый флаг.

Прос­матри­вая осталь­ные катало­ги поль­зовате­ля, вро­де докумен­тов и заг­рузок, находим сер­тифика­ты.

Сер­тификат мож­но прос­то открыть и прос­мотреть, для это­го я изме­нил рас­ширение на .crt. Но у нас зап­росили пароль.

Эти пароли бру­тят­ся, а для их извле­чения сущес­тву­ет целый пакет скрип­тов 2john (уже есть в Kali Linux). Нам нужен pfx2john.py, который в качес­тве аргу­мен­та при­нима­ет толь­ко путь к фай­лу.

От­прав­ляем на перебор в прог­рамму John The Ripper и спус­тя некото­рое вре­мя получа­ем пароль.

Те­перь откры­ваем сер­тификат и смот­рим его дан­ные.

Это сер­тификат для веб‑при­ложе­ния. Что­бы его исполь­зовать, мы дол­жны добавить его в хра­нили­ще сер­тифика­тов бра­узе­ра (Settings → Privacy & Security → Security → View certificate).

Те­перь оста­лось най­ти сер­вис, для которо­го нужен сер­тификат. Я поп­робовал что‑то вро­де search.research.htb, research.search.htb, а так­же поля из самого сер­та, но все безус­пешно. Тог­да я поп­робовал исполь­зовать имя фай­ла сер­тифика­та. С адре­са https://search.htb/staff/ про­изо­шел редирект на https://search.htb/staff/en-US/logon.aspx.

PowerShell Web Access — это фича, при помощи которой мож­но управлять сер­вером уда­лен­но через бра­узер при помощи PowerShell. Авто­ризу­емся от име­ни поль­зовате­ля Sierra.Frye и получим кон­соль PowerShell.

За­тем я поп­робовал про­кинуть реверс‑шелл для PowerShell, но мне помешал AMSI.

Antimalware Scan Interface (AMSI) — это ком­понент Microsoft Windows, который обес­печива­ет более глу­бокую про­вер­ку встро­енных служб сце­нари­ев. Прод­винутое вре­донос­ное ПО укло­няет­ся от тра­дици­онных методов про­вер­ки с помощью замас­кирован­ных или зашиф­рован­ных сце­нари­ев. Такое вре­донос­ное ПО час­то заг­ружа­ется непос­редс­твен­но в память, поэто­му не исполь­зует фай­лы на устрой­стве. AMSI — это интерфейс, через который при­ложе­ния и служ­бы отправ­ляют зап­росы на про­вер­ку уста­нов­ленно­му на компь­юте­ре анти­виру­су.

Но мы можем запат­чить AMSI, что­бы наш код не ухо­дил на про­вер­ку. Этот метод я взял из кур­са OSEP, он зак­люча­ется в изме­нении адре­сов заголов­ков amsiContext (кон­текст, в котором про­исхо­дит ска­ниро­вание). В этом вари­анте мы будем «занулять» ука­затель.

Под­робнее про обход AMSI — в статье «F#ck AMSI! Как обхо­дят Anti-Malware Scan Interface при зараже­нии Windows».

Пер­вым делом мы получа­ем все типы, опре­делен­ные в этой сбор­ке, и ищем AmsiUtils.

Те­перь получа­ем его поля, из которых выбира­ем amsiContext.

За­тем — адрес, по которо­му хра­нит­ся зна­чение.

И записы­ваем по дан­ному адре­су 0.

Те­перь мож­но ввес­ти стро­ку 'amsiutils', что­бы про­верить работу AMSI. Но PowerShell прос­то выведет ее вмес­то того, что­бы заб­локиро­вать. Это говорит о том, что AMSI боль­ше нам не помеша­ет.

Пов­торя­ем наш реверс‑шелл и получа­ем бэк­коннект.

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

Из­началь­но саму наг­рузку, реали­зован­ную на PowerShell или C#, нуж­но было запус­кать на целевом хос­те. Но есть и вер­сия на Python, которую мож­но исполь­зовать пря­мо с Linux. Заг­рузим BloodHound с GitHub и уста­новим:

А теперь соберем информа­цию с целево­го хос­та, бла­го это не зай­мет мно­го вре­мени. В парамет­рах ука­зыва­ем учет­ные дан­ные для под­клю­чения, адрес хос­та и тип собира­емой информа­ции — всю (параметр -c, зна­чение all).

В логах видим, сколь­ко доменов, лесов и компь­юте­ров было най­дено, сколь­ко поль­зовате­лей и групп получе­но. В резуль­тате работы BloodHound в текущей дирек­тории будет соз­дано нес­коль­ко фай­лов. Для работы с ними нам нуж­но уста­новить СУБД Neo4j и гра­фичес­кую оснас­тку bloodhound для отри­сов­ки гра­фов свя­зей.

За­пус­тим Neo4j коман­дой sudo neo4j console. Пос­ле сооб­щения об успешном стар­те зай­дем на http://localhost:7474/ через бра­узер. Нам сра­зу пред­ложат уста­новить пароль. Пос­ле уста­нов­ки пароля запус­тим BloodHound (коман­да bloodhound в коман­дной стро­ке) и авто­ризу­емся с толь­ко что уста­нов­ленным паролем. Откро­ется пус­тое окош­ко — закинем в него получен­ные от BloodHound фай­лы с кодом на Python. Затем выберем опцию поис­ка путей для повыше­ния при­виле­гий и получим малень­кий граф.

Пер­вым делом у нас дол­жна быть учет­ная запись BD-ADFS-GMSA.SEARCH.HTB. Пос­коль­ку у нее есть пра­во GenericAll для учет­ки TRISTAN.DAVIES, мы можем манипу­лиро­вать парамет­рами под­кон­троль­ного поль­зовате­ля, вплоть до сме­ны пароля. А уже этот поль­зователь явля­ется адми­нис­тра­тором. Имя учет­ной записи натал­кива­ет на мысль о MSA.

Уп­равля­емые учет­ные записи (MSA) — это спе­циаль­ный тип учет­ных записей Active Directory, которые мож­но исполь­зовать для безопас­ного запус­ка служб, при­ложе­ний и заданий пла­ниров­щика. Основная их идея в том, что паролем таких учет­ных записей пол­ностью управля­ет Active Directory. Для них авто­мати­чес­ки генери­рует­ся слож­ный пароль дли­ной 240 сим­волов, который меня­ется авто­мати­чес­ки каж­дые 30 дней.

Для аутен­тифика­ции исполь­зует­ся толь­ко Kerberos, так как инте­рак­тивный вход невоз­можен. Это свя­зано с тем, что пароль не известен никому и не хра­нит­ся в локаль­ной сис­теме, поэто­му его нель­зя извлечь из сис­темно­го про­цес­са LSASS с помощью mimikatz.

Но и такими учет­ными запися­ми нуж­но как‑то управлять, а это зна­чит, что, если у нас есть к ним дос­туп, мы можем получить хеш пароля. Для это­го написан инс­тру­мент gMSADumper. Исполь­зуем его:

У нас есть хеш пароля учет­ной записи! Поп­робу­ем соз­дать сес­сию это­го поль­зовате­ля. Не ука­зыва­ем пароль явно, вмес­то это­го заг­ружа­ем его msDS-ManagedPassword.

Те­перь по нашему пла­ну сме­ним пароль вто­рого поль­зовате­ля (я пос­тавлю ralfpass).

Про­веря­ем новый пароль с помощью CME.

И соз­даем новую сес­сию, теперь при­виле­гиро­ван­ную.

Мы работа­ем как адми­нис­тра­тор, в качес­тве под­твержде­ния чита­ем флаг рута.

Ма­шина зах­вачена!

Наши проекты:

- Кибер новости: the Matrix
- Хакинг: /me Hacker
- Кодинг: Minor Code
- IT Бункер : Бункер Айтишника