# Investigating PowerShell Attacks #### Defcon 2014 (Pre-Conference Draft) ----- ## Background Case Study ###### Attacker Client ### � Fortune 100 organization � Compromised for > 3 years #### � Active Directory � Authenticated access to corporate VPN ###### WinRM, SMB, NetBIOS Victim workstations, servers ### � Command-and-control via #### � Scheduled tasks � Local execution of PowerShell scripts � PowerShell Remoting **Victim** ###### SMB, **VPN** ###### WinRM, SMB, NetBIOS ----- ## Why PowerShell? ### It can do almost anything… ###### Execute commands Download files from the internet Reflectively load / inject code Interface with Win32 API Enumerate files Interact with the registry Interact with services Examine processes Retrieve event logs Access .NET framework ###### Download files from the internet ###### Interface with Win32 API ###### Reflectively load / inject code ###### Interact with services ###### Execute commands ###### Interface with Win32 API ###### Interact with the registry ###### Retrieve event logs ###### Execute commands ###### Retrieve event logs ----- ## PowerShell Attack Tools #### � PowerSploit ##### � Reconnaissance � Code execution � DLL injection � Credential harvesting � Reverse engineering #### � Nishang #### � Posh-SecMod � Veil-PowerView � Metasploit � More to come… ----- ----- ## Investigation Methodology ###### WinRM ###### WinRM ###### evil.ps1 ###### Local PowerShell script ###### WinRM ###### PowerShell Remoting Event Logs Sources of Evidence ###### backdoor.ps1 ###### backdoor.ps1 ###### Persistent PowerShell ###### Network Registry File System Event Logs Memory Traffic ###### evil.ps1 ----- ## Attacker Assumptions ### � Has admin (local or domain) on target system � Has network access to needed ports on target system � Can use other remote command execution methods to: #### � Enable execution of unsigned PS scripts � Enable PS remoting ----- |Version Reference|Col2|Col3|Col4| |---|---|---|---| ||2.0|3.0|4.0| ||Default (SP1) Default (R2 SP1)|Requires WMF 3.0 Update Requires WMF 3.0 Update Default|Requires WMF 4.0 Update Requires WMF 4.0 Update Requires WMF 4.0 Update Default| ## Version Reference ###### 2.0 ----- ## Memory Analysis ----- ## Memory Analysis ### � Scenario: Attacker interacts with target host through PowerShell remoting � What’s left in memory on the accessed system? � How can you find it? � How long does it persist? ----- ###### svchost.exe (DcomLaunch) wsmprovhost.exe evil.exe wsmprovhost.exe Get-ChildItem C:\ svchost.exe (WinRM) Kernel Invoke-Command {c:\evil.exe} Invoke-Mimikatz.ps1 ###### Remote Host ## WinRM Process Hierarchy ----- ###### svchost.exe (DcomLaunch) Cmd history wsmprovhost.exe evil.exe Cmd history wsmprovhost.exe Get-ChildItem C:\ svchost.exe (WinRM) Kernel ## Remnants in Memory ###### evil.exe ----- ## Example: In-Memory Remnants ###### SOAP in WinRM service memory, after interactive PsSession with command: echo teststring_pssession > c:\testoutput_possession.txt ----- ## Example: In-Memory Remnants ###### WinRM service memory - Invoke-Mimikatz.ps1 executed remotely on target host ----- ## What to Look For? ### � XML / SOAP strings ###### /wsman.xsd prompt""/rsp:Comma nd>AAAAAAAAAFkAAAAAAAAAAAMAAAa jAgAAAAYQAgC2Yc+EDBrbTLq08PrufN+rij8VmjyqZEaG AKwYZTnxB++7vzxPYmogUmVmSWQ9IjAiPjxNUz48T2JqI E49IlBvd2VyU2hlbGwiIFJlZklkPSIxIj48TVM+PE9iai BOPSJDbWRzIiBSZWZJZD0iMiI+PFROIFJlZklkPSIwIj4 8VD5TeXN0ZW0uQ29sbG . . . ----- ## How Long Will Evidence Remain? ###### • Best source of intact evidence wsmprovhost.exe • Only lasts until PS session exits • Fragments of evidence svchost.exe for • Retention depends on # of remoting sessions WinRM • May last until reboot • Fragments of evidence Kernel pool • Brief lifespan, depends on system utilization • Fragments of evidence Pagefile • Brief lifespan, depends on system utilization ###### • Fragments of evidence • Brief lifespan, depends on system utilization • May last beyond reboot ###### • Best source of intact evidence • Only lasts until PS session exits ----- ## Memory Analysis Summary ### � Timing is everything � Challenging to recover evidence � Many variables #### � System uptime � Memory utilization � Volume of WinRM activity ----- ## Event Logs ----- ## Event Logs ### � Scenario: Attacker interacts with target host through #### � Local PowerShell execution � PowerShell remoting ### � Which event logs capture activity? � Level of logging detail? � Differences between PowerShell 2.0 and 3.0? ----- ## PowerShell Event Logs ### � Application Logs #### � Windows PowerShell.evtx � Microsoft-Windows- PowerShell/Operational.evtx � Microsoft-Windows- WinRM/Operational.evtx ### � Analytic Logs #### � Microsoft-Windows- PowerShell/Analytic.etl � Microsoft-Windows- WinRM/Analytic.etl ----- ## PowerShell 2.0 Event Logging ### � What you do get #### � Start & stop times of activity � Loaded providers � User account context ### � What you don’t get #### � Detailed history of executed commands � Console input / output ### � Analytic logs help (somewhat) #### � Disabled by default � High volume of events � Encoding & fragmentation ----- ## Local PowerShell Execution ###### EID 400: Engine state is changed from None to Available. ###### PowerShell ###### EID 403: Engine state is changed from Available to Stopped. ###### Start & stop times of PowerShell session ----- ## Local PowerShell Execution ###### EID 40961: PowerShell console is starting up ###### Start time of PowerShell session ###### PowerShell Operational** ###### EID 4100: Error Message = File C:\temp\test.ps1 cannot be loaded because running scripts is disabled on this system ###### Error provides path to PowerShell script ###### ** Events exclusive to PowerShell 3.0 or greater ###### Error provides path to PowerShell script ----- ## Local PowerShell Execution ###### EID 7937: Command test.ps1 is Started. ###### EID 7937: Command test.ps1 is Started. ###### PowerShell Analytic** ###### What executed? (arguments not logged) ###### EID 7937: Command dropper.exe is Started ###### EID 7937: Command dropper.exe is Started ###### ** Events exclusive to PowerShell 3.0 or greater ###### EID 7937: Command Write-Output is Started. ----- ## Remoting (Accessed Host) ###### Start time of PowerShell session ###### Start time of PowerShell session ###### PowerShell ###### EID 400: Engine state is changed from None to Available. ###### Indicates use of PowerShell remoting ----- ## Remoting (Accessed Host) ###### EID 169: User CORP\MattH authenticated successfully using NTLM ###### EID 169: User CORP\MattH authenticated successfully using NTLM ###### Who connected via remoting ###### Who connected via remoting ###### WinRM Operational ###### EID 134: Sending response for operation DeleteShell ###### EID 134: Sending response for operation DeleteShell ###### Timeframe of remoting activity ----- ## Remoting (Accessed Host) ###### EID 32850: Request 7873936. Creating a server remote session. UserName: CORP\JohnD ###### Who connected via remoting ###### Who connected via remoting ###### PowerShell Analytic ###### EID 32867: Received remoting fragment […] Payload Length: 752 Payload Data: 0x020000000200010064D64FA51E7C784 18483DC[…] ###### EID 32867: Received remoting fragment […] Payload Length: 752 Payload Data: 0x020000000200010064D64FA51E7C784 18483DC[…] ###### Encoded contents of remoting I/O ###### Encoded contents of remoting I/O ----- ###### Invoke-Command {Get-ChildItem C:\} ----- ###### Invoke-Command {Get-ChildItem C:\} ----- ###### Invoke-Command {Get-ChildItem C:\} ----- ## Other Logging Solutions for PS 2.0 ### � Set global profile to log console command activity %windir%\system32\WindowsPowerShell\v1.0\ profile.ps1 � Use Start-Transcript cmdlet #### � Records all session input / output to text file ### � Overwrite default prompt function #### � Intercept commands and add to event log ### � Only works for local PowerShell execution � Can run PowerShell without loading profiles ----- ## Other Logging Solutions for PS 2.0 ----- ## PowerShell 3.0: Module Logging ###### Solves (almost) all our logging problems! ###### Computer Configuration → Administrative Templates → Windows Components → Windows PowerShell → Turn on Module Logging ----- ## Module Logging Examples ###### Get-ChildItem c:\temp -Filter *.txt -Recurse | Select-String password ###### Microsoft-Windows-PowerShell/Operational (EID 4103) ParameterBinding(Get-ChildItem): name="Filter"; value="*.txt" ParameterBinding(Get-ChildItem): name="Recurse"; value="True" ParameterBinding(Get-ChildItem): name="Path"; value="c:\temp" ParameterBinding(Select-String): name="Pattern"; value="password" ParameterBinding(Select-String): name="InputObject"; ##### ... ###### Command Name = Get-ChildItem **Logged upon command execution** ###### ParameterBinding(Out-Default): name="InputObject"; value="C:\temp\creds.txt:2:password: secret" ParameterBinding(Out-Default): name="InputObject"; value="C:\temp\creds.txt:5:password: test" **L** **d** **d** **t** **t** ###### ParameterBinding(Get-ChildItem): name="Filter"; value="*.txt" ParameterBinding(Get-ChildItem): name="Recurse"; value="True" ParameterBinding(Get-ChildItem): name="Path"; value="c:\temp" ParameterBinding(Select-String): name="Pattern"; value="password" ParameterBinding(Select-String): name="InputObject"; value="creds.txt" ##### ... ###### Command Name = Get-ChildItem User = CORP\MHastings ###### ParameterBinding(Out-Default): name="InputObject"; value="C:\temp\creds.txt:2:password: secret" ParameterBinding(Out-Default): name="InputObject"; value="C:\temp\creds.txt:5:password: test" ###### Get-ChildItem c:\temp -Filter *.txt -Recurse | Select-String password ----- ## Module Logging Examples ###### Invoke-Mimikatz.ps1 via remoting ###### Detailed “per- command” logging ----- ###### Invoke-Mimikatz.ps1 via remoting ----- ## Persistence ----- ## PowerShell Persistence ### � Scenario: Attacker configures system to load malicious PS upon startup / logon � Why persist? #### � Backdoors � Keyloggers ### � What are common PS persistence mechanisms? � How to find them? ----- ## Common Techniques ### � Registry “autorun” keys � Scheduled tasks � User “startup” folders � Easy to detect #### � Autorun review � Registry timeline analysis � File system timeline analysis � Event log review ###### At1.job At1.job **At1.job** ----- ## Persistence via WMI ###### Use WMI to automatically launch PowerShell upon a common event ###### Namespace: “root\subscription” EventFilter Filter name, event query CommandLineEventConsumer Consumer name, path to powershell.exe FilterToConsumerBinding Filter name, consumer name ###### Set-WmiInstance ----- ## Event Filters ### � Query that causes the consumer to trigger ###### SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325 Run within minutes of startup SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hour = 12 AND TargetInstance.Minute = 00 GROUP WITHIN 60 Run at 12:00 ###### SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325 ###### SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hour = 12 AND TargetInstance.Minute = 00 GROUP WITHIN 60 ----- ## Event Consumers ### � Launch “PowerShell.exe” when triggered by filter � Where does the evil PS code load from? ###### sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64 String('7L0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyq BymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP3 58Hz8ivlsXbb795bpdrdv0o2/nZVml363qcvbR/xMAAP//'),[IO.Compression.Co mpressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd() ##### Stored in user or system-wide “profile.ps1” ###### Set-WmiInstance -Namespace "root\subscription" -Class 'CommandLineEventConsumer' -Arguments @{ name='TotallyLegitWMI';CommandLineTemplate="$($Env:SystemRoot)\Syst em32\WindowsPowerShell\v1.0\powershell.exe - NonInteractive";RunInteractively='false'} ##### Added to Consumer Command-Line Arguments (length limit, code must be base64’d) ###### sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64 String('7L0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyq BymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP3 58Hz8ivlsXbb795bpdrdv0o2/nZVml363qcvbR/xMAAP//'),[IO.Compression.Co mpressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd() ###### Set-WmiInstance -Namespace "root\subscription" -Class 'CommandLineEventConsumer' -Arguments @{ name='TotallyLegitWMI';CommandLineTemplate="$($Env:SystemRoot)\Syst em32\WindowsPowerShell\v1.0\powershell.exe - NonInteractive";RunInteractively='false'} ----- ## Enumerating WMI Objects with PowerShell ### � Get-WMIObject –Namespace root\Subscription -Class __EventFilter � Get-WMIObject -Namespace root\Subscription -Class __EventConsumer � Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding ----- ## PS WMI Evidence: File System **sal a New-Object;iex(a IO.StreamReader((a** **IO.Compression.DeflateStream([IO.MemoryStr** **eam][Convert]::FromBase64String('7L0HYBxJl** **iUmL23Ke39K9UrX4HShCIBgEyTYkEA...** ----- |Key|Col2|Value|Col4|Data| |---|---|---|---|---| |HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\ ESS\//./root/CIMV2\Win32ClockProvider||[N/A]||[N/A]| |Key Last Modified||||| |06/04/14 01:30:03 UTC||||| ## PS WMI Evidence: Registry ###### Created only when setting a time-based WMI filter (many other types of triggers may be used) ----- ## PS WMI Evidence: Other Sources ### � SysInternals AutoRuns (v12) � Memory: WMI filter & consumer names #### � svchost.exe (WinMgmt service) � WmiPrvse.exe ### � Event logs: WMI Trace #### � Too noisy ----- ## Conclusions ----- ## Other Sources of Evidence ### � Refer to whitepaper � Prefetch file for “PowerShell.exe” #### � Local execution only � Scripts in Accessed File list ### � Registry #### � PowerShell “ExecutionPolicy” setting ### � Network traffic analysis (WinRM) #### � Port 5985 (HTTP) / port 5986 (HTTPS) � Payload always encrypted � Identify anomalous netflows ----- ## Lessons Learned ### � Upgrade to PS 3.0 and enable Module Logging if possible � Baseline legitimate usage in environment #### � ExecutionPolicy setting � Remoting enabled � Script naming conventions, paths � Which users � Source systems � Destination systems ### � Recognize artifacts of anomalous usage ----- ## Acknowledgements ### � Matt Graeber � Joseph Bialek � Chris Campbell � Lee Holmes � David Wyatt ### � David Kennedy � Josh Kelley � All the other PowerShell authors, hackers, and researchers! ----- ## Questions? ### ryan.kazanciyan@mandiant.com @ryankaz42 matt.hastings@mandiant.com @HastingsVT -----