Lateral Movement
Moving between computers by re-using accounts to get more access
Last updated
Moving between computers by re-using accounts to get more access
Last updated
Network tunneling using .
Some protocols allow running commands as a user on the computer when having valid credentials. This is useful because often different computers will contain different new secrets to escalate further into the domain, and eventually reach the Domain Admin.
The Windows Management Instrumentation (WMI) protocol works over port 135 and is used commonly for automating tasks. This is also useful for lateral movement, however, because it allows us to remotely run commands on another computer as a user:
The above method needs to be done from a PowerShell console on an already-compromised machine, but NetExec can also send commands through this protocol, and even pass the hash. Simply use the syntax you're used to with -u
and -p
, and use -x
to specify the command to execute (such as a reverse shell):
PsExec is part of Microsoft's Sysinternals suite and is made to easily run commands on a remote machine through an interactive console. The .exe
provided implements the following steps on SMB:
Write psexesvc.exe
to the ADMIN$
share which maps to the C:\Windows
directory
Create a service from this binary that can take commands
Run any incoming authenticated commands through this service
It can target any host where the user has local administrator privileges to be able to do the above actions. Using the official PsExec.exe
a session can be started as follows:
NetExec implements a similar idea called smbexec
which also drops an executable on the machine and executes it remotely. This also instantly gives you the nt authority\system
permissions:
This implementation is not exactly the same however, an alternative is psexec.py
from impacket to get an interactive shell:
If your user is inside of the "Remote Management Users" group, this may be an option.
Windows Remote Management (WinRM) is another protocol built to execute commands remotely, this time allowing an interactive shell to be started as well. The commands are a little more complex in PowerShell, but we generate a password credential and start a session with that remotely:
NetExec can also run commands to start a reverse-shell for example, if you don't have access to a compromised PowerShell shell. This is very similar to the WMI command:
Lastly, there is the purpose-built evil-winrm
tool that can start an interactive session remotely. It also supports extra commands in the shell like uploading/downloading and starting the connection using pass-the-hash or a private key certificate:
Read 'Basic Commands' to learn about the extra built-in commands like uploading/downloading, loading assemblies, and AMSI Bypass all from inside the shell.
Remote Desktop Protocol is used very often by administrators and clients to use their Windows machine and configure it visually. When a user is in the "Remote Desktop Users" group, they can use this protocol on port 3389 to connect. There is no CLI-only option for this, only GUI.
Linux has a tool called Remmina that you can add hosts to, and connect to via RDP.
Windows has this built-in with "Remote Desktop Connection" (mstsc.exe), which often works better because it is the official client, and supports copy-pasting across machines for example.
Tip: Getting the domain correct can be a bit finicky, so try using NetExec with SMB to get it:
It might sound a bit unusual, but Windows machines can also host OpenSSH servers that allow you to connect via a terminal. These also don't require the user to be in any special group like #winrm or #rdp, so any user can log in with this. It simply requires a username and password:
Shells like these are also very nice to work with, having command history and working arrow keys, as well as fast responses and flawless interactivity with programs you start.
Microsoft has its own Database and SQL protocol called MSSQL, hosted on SQL Server. You may encounter this in a SQL Injection attack as well, but when inside the network you may also be able to directly authenticate and connect to it.
An interesting exploitable command is xp_cmdshell
which runs a shell command from an SQL query. Because this is dangerous, this feature first needs to be enabled and then only permitted users can run it. But if you compromise a database administrator with enough privileges, they can enable and abuse this feature to get code execution on the SQL server:
This process can also be automated using NetExec which implements this in the nxc mssql -x
module. By providing an administrator like the SQL service account itself, for example:
For a simple SQL client connection instead, if you have lower privileges for example, check out mssqlclient.py from Impacket. This can connect to an SQL Server with any credentials, and then you can manually query the database to do whatever you need in an MSSQL console.
In Active Directory, having the NTLM hash of a user is just as good as having their password. This is due to the pass-the-hash attack where all verification uses the hash instead of the password (as seen in the #authentication-flow). Most offensive tools allow a -hashes
or -H
argument to pass the hash and impersonate a user without knowing their password.
NTLM Authentication won't send the plain NTLM hashes over the network, ever. It only calculates a challenge-response using it which cannot be reversed, only brute-forced. Using a challenge-response an attacker can still guess passwords and calculate the hash as well as the response offline.
It is recommended to read Forcing Authentication to Relay first to understand where challenges can come from, and how we can trigger them.
One common exploit on domain-joined Windows servers is that when connecting to an SMB share, they will answer any authentication requests. The NetNTML challenge-response mechanism allows the attacker to be in between the victim, and the target server. When the client connects to the attacker, the attacker can ask a different server for a challenge as well, and then relay that challenge back to the client. The client will then solve that challenge, and send it back to the attacker, who can finally send the correct response to the target server. This authenticates them as the victim!
Because many services accept NTLM authentication in this way, most commonly SMB and LDAP. A tool was developed that can listen for authentication requests, and relay them to a target server like explained. Because the protocol is so simple, this can go cross-service meaning an SMB request could be relayed to LDAP.
Letting it listen with sudo ntlmrelayx.py
a bunch of ports will be opened for connections. Try ways of Forcing Authentication to Relay, and when you do, the tool will automatically relay the authentication to a target specified with -t
and a protocol:
-t $IP
: SMB (default)
-t imap://$IP
: IMAP
-t ldaps://$IP
: LDAP
Another useful option is -i
which will spawn a listener on every success for interactive tooling like SMB or LDAP client where you can write commands yourself.
By default, the tool will perform useful actions like trying to execute files through SMB, or even adding a Domain Admin account if enough privileges are gained.
With the -c
argument you can specify a custom command that it will execute if it is a local admin, otherwise, it dumps the SAM hashes in memory by default. Using -t
as shown above you specify a single target, and -tf
specifies a target file containing all addresses it should try to relay to:
The above pass-the-hash technique works great for protocols like SMB which use the legacy NTLM authentication, but newer Kerberos authentication schemes like for HTTP don't seem vulnerable at first. That is where "Overpass the Hash" comes in where we turn an NTLM hash into a valid Kerberos ticket. This turns out to be very simple using Mimikatz:
The above will start a new powershell.exe
process in a new window, which is useful in a visual RDP connection, but often you'll want to execute a reverse shell instead, like from MSFVenom (.exe).
When having reached Post-Exploitation: Mimikatz, Kerberos tickets may be found in memory, which you can check and export to the current directory using sekurlsa::tickets /export
.
This will generate many files with the following format:
[0;12bd0]-0-0-40810000-$USERNAME@$PROTOCOL-$COMPUTER.kirbi
where the username, protocol, and computer are filled in with some place the user tried to access. The protocol cifs
is just SMB in this case, meaning a file share was accessed. We can import these tickets into our current session to get the same privileges that they had:
Closing mimikatz.exe
, the klist
command should now show this injected ticket:
Another powerful thing we can access through SMB if the user has local administrator rights there is #psexec-smb. This will get us a full system shell on that system, but be careful that you use the HOSTNAME instead of the IP address! Otherwise, it will force an NTLM authentication:
All service accounts like a webserver have a Service Principal Name (SPN), which we abuse more in Kerberoasting. But if through Post-Exploitation: Mimikatz, for example, we find the NTLM hash of an SPN, we can go one step further. With this secret known, we can forge a Kerberos ticket for any user to the service! This works because this hash normally verifies the integrity, but now it is known and can be used to break the trust.
mimikatz.exe
can best be used to craft such tickets and inject them into the current session. For this we need to supply a few pieces of information:
/domain
: regular domain name.
(eg. corp.com
)
/sid
: Security Identifier of the domain, easily found using whoami /user
and trimming the last number. PowerView.ps1 also has a ConvertTo-SID '$DOMAIN\$USER'
function.
(eg. S-1-5-21-5386719015-7638691639-2457330780
)
/target
: Domain name of the service.
(eg. web01.corp.com
)
/service
: Type of the service, one of cifs
(SMB), rpcss
, http
, mssql
.
(eg. http
)
/rc4
: NTLM hash of the SPN you are targeting.
(eg. 4d28cf5252d39971419580a51484ca09
)
/user
: Username of who to create the ticket for, which will decide your access.
(eg. admin
)
After executing this command and closing Mimikatz, you should see the new forged ticket in klist
. This can now be used on the webserver for example by invoking a request with the current credentials:
Every Service on AD that requires Kerberos authentication registers a Service Principal Name (SPN). This allows clients to request Tickets for the service. The Ticket Granting Ticket (TGT) is encrypted using the service account's password hash, which is given to the client. Using this encrypted data, an attacker can brute force the password offline until it successfully decrypts, then knowing the correct password for the service account.
Query the AD to identify service accounts with registered SPNs
Request a Ticket Granting Service (TGS) ticket for the identified service account using any compromised user. In response, receive the encrypted TGS with the password hash
Attempt to crack the password hash offline, and when found, take over the service account
The first step can be checked easily in BloodHound under the Analysis tab as List all Kerberoastable Accounts. After which, you can use GetUserSPNs.py
from impacket to request a ticket and receive the crackable password hash.
These can then be cracked offline with tools like Hashcat:
Note: Complete domain credentials are not required for this attack to work. NTLM hashes (using -H
) or even for accounts vulnerable to ASREPRoasting (reference)
This attack can be done by speaking to the domain controller, not even a valid account is needed. You can use a list of users you found to check if they are vulnerable even without authenticating. But authentication allows you to query the LDAP server to get every existing user for sure:
Hashes resulting from this attack can then be cracked using Hashcat: