Skip to content

Instantly share code, notes, and snippets.

@msuiche
Last active May 23, 2020 19:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save msuiche/2324aa8147c483a7a3e7d1b2d23ee407 to your computer and use it in GitHub Desktop.
Save msuiche/2324aa8147c483a7a3e7d1b2d23ee407 to your computer and use it in GitHub Desktop.
Memory Forensics and PowerShell
##
## A good excuse to learn LINQ in WinDbg.
## Author: Matt Suiche (@msuiche) - 18-Jan-2019
##
## References:
## Extracting Forensic Script Content from PowerShell Process Dumps (Lee Holmes) - 17 Jan 2019
## http://www.leeholmes.com/blog/2019/01/17/extracting-forensic-script-content-from-powershell-process-dumps/
## Extracting Activity History from PowerShell Process Dumps (Lee Holmes) - 4 Jan 2019
## https://www.leeholmes.com/blog/2019/01/04/extracting-activity-history-from-powershell-process-dumps/
##
#
# Make sure to run the following command first:
#.loadby sos clr
# .symfix
# .reload
#
########################
# Read HistoryInfo
# PowerShell Command History
########################
dx @$getObject = (x => Debugger.Utility.Control.ExecuteCommand("!do /d " + (x).ToDisplayString("x")))
dx @$getHistoryObjects = Debugger.Utility.Control.ExecuteCommand("!DumpHeap -Type HistoryInfo -short")
dx @$getCmdLineVariable = (x => @$getObject(x).Flatten(n => n).Where(n => n.Contains("_cmdline")).Single().Remove(0, 68).Remove(16))
dx @$getLineContent = (x => @$getObject(x).Flatten(n => n).Where(n => n.Contains("String:")).Single().Remove(0, 12))
dx @$PowerShellHistory = @$getHistoryObjects.Flatten(n => n).Select(x => @$getLineContent(@$getCmdLineVariable(x)))
########################
# Read ConcurrentDictionary
# PowerShell Scripts
########################
dx @$getObject = (x => Debugger.Utility.Control.ExecuteCommand("!do /d " + (x).ToDisplayString("x")))
dx @$getHeap = (x => Debugger.Utility.Control.ExecuteCommand("!dumpheap -mt " + (x).ToDisplayString("x") + " -short"))
dx @$getDictionaries = Debugger.Utility.Control.ExecuteCommand("!dumpheap -type ConcurrentDictionary")
dx @$getScripts = @$getDictionaries.Flatten(n => n).Where(x => x.Contains("System.Collections.Concurrent.ConcurrentDictionary`2+Node[[System.Tuple`2[[System.String, mscorlib],[System.String, mscorlib]], mscorlib],[System.Management.Automation.ScriptBlock, System.Management.Automation]]"))
dx @$getDictionary = @$getHeap(@$getScripts[1].Remove(16)).Flatten(n => n)
dx @$getKeyValue = (x => @$getObject(x).Flatten(n => n).Where(n => n.Contains("m_key")).First().Remove(0, 68).Remove(16))
dx @$getItem1FromKey = (x => @$getObject(x).Flatten(n => n).Where(n => n.Contains("m_Item1")).First().Remove(0, 68).Remove(16))
dx @$getItem2FromKey = (x => @$getObject(x).Flatten(n => n).Where(n => n.Contains("m_Item2")).First().Remove(0, 68).Remove(16))
dx @$getLineContent = (x => @$getObject(x).Flatten(n => n).Where(n => n.Contains("String:")).First().Remove(0, 14))
dx @$PowerShellFilesAndContent = @$getDictionary.Select(n => @$getKeyValue(n)).Select(n => new {FileName = @$getLineContent(@$getItem1FromKey(n)), Content = @$getObject(@$getItem2FromKey(n))})
# dx @$PowerShellFilesAndContent.First().FileName
# dx @$PowerShellFilesAndContent.Last().FileName
# dx @$PowerShellFilesAndContent.Last().Content
# Use @$PowerShellHistory and @$PowerShellFilesAndContent in the Data Model window of WinDbg Preview: https://twitter.com/msuiche/status/1086282970326028289
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment