Prerequisites
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.
Introduction
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 command.com 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 getowner, ConvertToDateTime, 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 '78.46.28.97'} resulted
in Figure 5.
Figure 5: IIS log objectified via PowerShell |
As you can see, 78.46.28.97 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.
Acknowledgements