Friday, June 01, 2012

toolsmith: Security Investigations with PowerShell

Windows, ideally Windows 7 or Windows Server 2008 R2 as PowerShell is native
There are 32-bit & 64bit versions of PowerShell for Windows XP, Windows Server 2003, Windows Vista and Windows Server 2008 as well.

Windows power users have long sought strong fu at the command line. In the beginning, Bill said “Let there be shell.” And lo, there was and cmd.exe. Then Jim said, there must be scripting support and automation, and thus the likes of Windows Script Host and WMIC were brought to light. But alas, there were challenges; no shell integration, no interoperability. Then unto thee was delivered the shell prophet Monad (see the Monad Manifesto), later renamed Window PowerShell in 2006.
In a nutshell, PowerShell is powerful. Alright, enough of the PowerShell parable.
Really though, any sysadmin running modern Windows platforms is likely using or has used PowerShell. Full disclosure: I work for Microsoft. But before you write me off as just being a fan boy, hear me out. Aside from all the administrative horsepower PowerShell provides it also lends significant punch to security-related investigations as part of incident response and/or forensic reviews.
As you know, I always prefer to “ask the expert” when it comes to toolsmith topics so I sought counsel from Ed Wilson (Microsoft Scripting Guy) regarding security investigations with PowerShell.

“Using Windows PowerShell to aid in security forensics is a no-brainer. First of all, Windows PowerShell is installed by default beginning with Windows 7, so the tool is likely to already be available. Second Windows PowerShell makes it extremely easy to collect the data you need to analyze. A very simple Windows PowerShell script (or a few Windows PowerShell commands) can dump the windows logs, take a snapshot of running services, processes, and gather system time. In addition, the script can collect any other logs you wish. The above can be done in just a few lines of easily readable code. When Windows PowerShell remoting is enabled (enabled by default on Windows Server 2012) there is no difference between running a command on one or a thousand different systems.
The real power begins, however, when you decide to parse the collected data. A number of Windows PowerShell cmdlets make trolling through massive amounts of XML, CSV, or even unstructured text a breeze. Whether you are parsing an offline Windows event log, a firewall log, or even a syslog gathered from a remote Unix machine the process remains the same. In short Windows PowerShell is the one tool you do not want to leave home (even virtually) without.”  

I pitch a straight fastball right in Ed’s wheelhouse and he drives it out of the park for me.
We’ll take on both of these scenarios as described by Ed:
·         Using PowerShell to dump Windows logs, assess running services, processes, and gather other useful system data.
·         Using PowerShell to parse collected data
In a case of shameless self-promotion I want to call out the benefits of tools that aid in culling evil from logs as described above. My recently posted SANS Reading Room paper for my GCIA Gold research effort, Evil Through The Lens of Web Logs discusses a number of tools to conduct such parsing activity but it fails to mention PowerShell. This is my chance to correct that shortcoming.

Using PowerShell

There are endless online PowerShell resources via the likes of TechNet, MSDN, CodePlex, and SANS-related content. Also check out Adam Bell’s great list on Lead, Follow, or Move. Rather than rehash such content, I’ll instead walk through an investigation using cmdlets and scripts that are directly relevant to the cause. Do remember that get-help from the PowerShell prompt is definitely your friend.
Caveat: I do not lay claim to any of the strings or commands included hereafter, they are mimicked and modified from the above mentioned resources or yanked right from Get-Help. This work is neither unique nor particularly creative. It is instead intended to help you recognize why PowerShell is so incredibly useful. To those true aficionados who swiftly recognize how much detail I’m leaving out, feel free to share your feedback and I’ll add it the related blogpost and/or accept comments.
Imagine a malicious person has created a backdoor on a Windows system using tini, has renamed tini to a trusted file name, created a service to ensure that it always runs, and has changed the listening port to 31337 (original, I know). I’m operating from the premise that we already know the basic gist of the attacker activity and will focus much more on how to discover it with PowerShell. So, what PowerShell juju can we utilize to rebuild the trail of malfeasance?
First, fire up a PowerShell prompt. Start | Programs | Accessories | Windows PowerShell followed by your preferred PowerShell (x86 or 64-bit) or Integrated Scripting Environment (ISE). Note: when you bring PowerShell scripts on your system that have been created by other users, you may need to check script execution policy. By default, unsigned PS1 files are prevented from execution for reasons of inherent risk to the system as untrusted. As long as you are cognitive of this risk you can do the following, in order, from the PowerShell prompt.
1)  Get-ExecutionPolicy
2)  Set-ExecutionPolicy where policy is one of four options:
a.       Restricted - default execution policy, doesn’t run scripts, interactive only
b.      AllSigned - runs scripts, scripts and configuration files must be signed by trusted publisher
c.       RemoteSigned – Like as AllSigned when script is downloaded apps such as IE and Outlook
d.      Unrestricted – goes without saying

Let’s start with running services. You have reason to believe that the attacker’s backdoor is running as a known service name. Begin with get-service. Results are a little busy so let’s narrow it down. Get-Service | Where-Object {$_.status -eq "running"} thins the crowd a bit by presenting only running services, but still nothing leaps right out. Sometimes the service description or lack thereof is revealing.  There is no parameter defined via get-service to pull a service description but it can be done via get-wmiobject win32_service | format-list Name, Description. The result is again busy but I found my culprit as seen in Figure 1.

Figure 1: Service description gone wild
Now that we know the name of our faux service in this imaginary scenario, let’s explore possibly related processes with Get-Process | Out-Gridview. This will spawn a second window with a conveniently interactive table view of the results. If we operate on the premise that a malicious process name TapiSrv might be in play, we can filter the grid view or we can drill in for it specifically with Get-Process TapiSrv as seen in Figure2.  

Figure 2: Malicious process
Let’s determine the TapiSrv file information and process owner. Get-Process TapiSrv –fileversioninfo tells us the TapiSrv resides in C:\tmp\TapiSrv.exe. Helpful, but wait, there’s more. (get-wmiobject win32_process | where{$_.ProcessName -eq 'TapiSrv.exe'}).getowner() | Select -property domain, user will tell us that I am he who propagates the evil and write-host ([WMI]'').ConvertToDateTime((Get-WmiObject win32_process | where{$_.ProcessName -eq 'TapiSrv.exe'}).creationdate) will tell us the date and time I created it as seen in Figure 3 (no you do not get to see my domain name).

Figure 3: Process owner, creation date & time
The Get-Member cmdlets will help you determine which properties and methods are available to you where the likes of get-wmiobject win32_process | get-member told us that getownerConvertToDateTime, and creationdate were all available to us via get-wmiobject.

Figure 2 gave us something useful to explore further in the Id, also known as the PID.
We can take information such as 9512 and throw Microsoft MVP Shay Levy’s Get-NetworkStatistics at it. When you want to add PowerShell modules such as Shay’s that aren’t native you can use import-module as follows after saving the code from your preferred resource as a PSM1 file:
import-module -name D:\tools\powershell\Get-NetworkStatistics.psm1 –verbose
Thereafter, Get-NetworkStatistics will simply be available on demand. Issuing Get-NetworkStatistics | where{$_.PID -eq '9512'} | format-table reveals all our suspicions and closes the loop as seen in Figure 4.

Figure 4: Mapping PID to port and process
TapiSrv is PID 9512 and listening on port 31337. There’s the evil backdoor.

Ed also described using PowerShell for log analysis. In the above mentioned Evil Through The Lens of Web Logs research paper, I used Log Parser-related tools. Early stages of this research were also included in the April 2012 toolsmith column on Log Parser Lizard. Can one conduct similar activity without Log Parser via PowerShell? Of course. Tim Medin, of CommandLine Kung Fu (one of my absolute favorite blogs), wrote the sweet little PowerShell IIS LogObjectifier. Saved as a script or modularized, Tim’s code allows you to search by common IIS log field identifiers such as UriStem, UriQuery, UserAgent, and Win32Status. Utilizing the same log sample analyzed for the research paper, as well as similar principles, I set a PowerShell query using Tim’s script to identify log entries with 500 status codes from a specific SourceIp as an example. Imagine we have reason to suspect that SourceIp of a SQL injection attack. The query, .\objectify.ps1 $log | where{$_.Win32Status -eq '500' -and $_.SourceIp -eq ''} resulted in Figure 5.

Figure 5: IIS log objectified via PowerShell
As you can see, made an attempt to inject a HEX-obfuscated DECLARE statement into the victim application.

The possibilities are endless. I didn’t even touch the concepts of PowerShell remoting or running PowerShell cmdlets at scale. Did I mention the possibilities are endless? Hopefully, this brief synopsis whets your appetite.

In Conclusion

So much data, not enough time or word space. There is clearly so much that can be done with Windows PowerShell. The last resource I’ll share with you may become your PowerShell dashboard: A Task-Based Guide toWindows PowerShell Cmdlets. This resource will send you right down the rabbit hole as you further explore what we’ve started here. No reason not to head there now. Much thanks to Ed Wilson for supporting this exploration.
Ping me via email if you have questions (russ at holisticinfosec dot org).
Cheers…until next month.


Ed Wilson (The Scripting Guy) for content and endless insight on PowerShell.