Skip to main content

Command Palette

Search for a command to run...

Hunting Infostealers with PowerShell: A Practical Guide to Building a Forensic Triage Script

Updated
5 min read
Hunting Infostealers with PowerShell: A Practical Guide to Building a Forensic Triage Script
Y

My mission is to empower organizations and professionals to build secure, resilient, and compliant digital ecosystems. Through thought leadership in security operations, architecture, compliance, and advisory, this blog serves as a trusted platform to illuminate best practices, share strategic insights, and advance the maturity of modern information systems!

Introduction

Infostealers remain one of the most prevalent malware families in the wild. They aim to harvest browser credentials, cookies, crypto wallets, and sensitive files before exfiltrating them to command-and-control (C2) infrastructure.
In enterprise environments, where endpoints are diverse and visibility might be partial, having a lightweight, PowerShell-based triage tool is invaluable for security analysts and forensic responders.

In this article, I’ll share the full process I followed to design, troubleshoot, and refine a PowerShell script that detects infostealer behavior, collects forensic artefacts, and generates HTML/JSON reports that analysts can immediately consume.


Why PowerShell?

  • Native availability: PowerShell is installed on all modern Windows systems — no extra agents or binaries required.

  • Rapid prototyping: Easy to iterate, test, and extend.

  • Enterprise fit: Can run locally or remotely (Invoke-Command), integrates with Active Directory environments, and outputs both machine-readable (JSON) and human-readable (HTML) formats.

  • Minimal dependencies: The final version does not rely on external tools like YARA, making it portable.


Step 1 — Defining the Scope

I wanted the script to cover key forensic questions relevant to infostealers:

  1. What processes are running?
    Are any executing from suspicious locations (AppData, Temp, etc.)?

  2. What network connections are active?
    Are there external (non-private) established connections?

  3. What persistence mechanisms exist?
    Registry Run keys, suspicious services, scheduled tasks.

  4. What evidence is on disk?
    Recent files in drop zones, suspicious extensions (.exe, .dll, .bat, .ps1, etc.).

  5. What system metadata is useful?
    Hostname, boot time, user, OS version, DNS cache.

  6. How do we make this consumable?
    Produce an HTML dashboard and a JSON artefact, alongside raw CSVs and copied files.


Step 2 — Building the Script Core

The initial draft gathered processes, connections, autoruns, services, event logs, and files. It also exported CSVs for easy analysis in Excel.

Evidence collection logic included:

  • Copy suspicious files to an Evidence directory.

  • Optionally compute SHA256 hashes for each file.

  • Support matching against a known bad hash list if available.

At this stage, the script already worked but needed refinement.


Step 3 — Overcoming PowerShell Gotchas

As I iterated, I hit common PowerShell pitfalls:

1. Reserved variables

  • $Host and $PID are built-in read-only variables.

  • Attempting to reuse them caused errors:

    • “Cannot overwrite variable Host because it is read-only or constant”

    • “Cannot overwrite variable PID because it is read-only or constant”

  • Fix: rename to $Hostname, $OwningPid, $nsPid.

2. StrictMode property errors

  • Accessing .EvidencePath on objects where the property hadn’t been set caused:
    “The property ‘EvidencePath’ cannot be found…”

  • Fix: initialize optional properties (EvidencePath, SHA256, KnownBadMatch) during object creation.

3. Long path copying

  • Copy-Item failed on certain Windows paths.

  • Fix: fallback to robocopy for long path support.

Key lesson: Forensic automation is as much about robustness as detection. A script that fails mid-run in the field is unusable.


Step 4 — Adding Reporting

For analysts, raw CSVs are valuable, but reports drive action. I implemented:

  • HTML report:

    • Summary counts (suspicious processes, external connections, suspicious files).

    • IOC table (type, value, description, confidence, evidence path).

    • Sectioned tables for processes, services, autoruns, etc.

    • Analyst notes and recommended next steps.

  • JSON report:
    Machine-readable format for pipeline integration or later aggregation across hosts.

  • Evidence ZIP:
    Auto-compressed archive of the full evidence folder for easy transfer.


Step 5 — Executing the Script

To run on a host:

.\InfostealerHunt_PSOnly.ps1 `
  -OutputHtmlPath "C:\Users\Administrator\Desktop\HuntReport.html" `
  -EvidenceRoot   "C:\Users\Administrator\Desktop\Evidence"

The script outputs:

  • HuntReport.html → open in a browser for IOC insights.

  • HuntReport.json → structured data for advanced queries.

  • Evidence\ → folder with CSVs, logs, copied files, and metadata.

  • Evidence.zip → compressed archive of the above.

Sample console output:

HTML report: C:\Users\Administrator\Desktop\HuntReport.html
JSON report: C:\Users\Administrator\Desktop\HuntReport.json
Evidence dir: C:\Users\Administrator\Desktop\Evidence
Evidence ZIP : C:\Users\Administrator\Desktop\Evidence.zip
Suspicious Processes: 12; External Conns: 27; Suspicious Files: 41; IOCs: 80

Step 6 — Visualizing & Triaging

  1. Open the HTML report: quick overview of suspicious artifacts.

  2. Investigate High-confidence IOCs:

    • Processes/services in AppData/Temp.

    • Files matching known bad hashes.

    • External connections to untrusted IPs.

  3. Review raw CSVs: deeper pivoting in Excel or PowerShell.

  4. Inspect collected files: hash them, analyze in a sandbox, or escalate to a malware lab.

  5. At the end you’ll have something like this :

  6. Demo


Key Lessons Learned

  • PowerShell quirks matter: reserved variables and strict property access can break scripts in production.

  • Robustness > detection: triage scripts must fail gracefully, initialize properties, and handle long paths.

  • Reporting is half the battle: a clear HTML report makes evidence accessible for managers and SOC analysts, not just forensics.

  • Iterative debugging is essential: each error refined the tool into a resilient utility.


Conclusion

By walking through the process of design → debugging → reporting → execution, I ended up with a portable, PowerShell-only hunting script.
It allows forensic analysts to quickly triage a potentially compromised endpoint, gather high-value evidence, and generate actionable reports — all with no external dependencies.

In an age where infostealers evolve rapidly, having such lightweight forensic tools at hand empowers incident responders to contain threats faster and with greater confidence.


What’s Next

Future improvements could include:

  • Remote execution across multiple hosts with aggregated reporting.

  • Integration with SIEM/EDR APIs to enrich IOC context.

  • Automated submission of suspicious hashes/files to internal sandbox systems.


Do you use PowerShell for forensic triage or malware hunting? Let me know your experience in the comments, I’d love to hear how others adapt lightweight scripts in their workflows.