Saturday, September 26, 2015

More artifacts through PowerShell - Part 6

MsiInstaller events.

Applications that use Windows Installer logs both installation and removal events; these are available on the 'application' event log. These are extremely useful in identifying malicious application installs.

Get-WinEvent -ea 0 -FilterHashtable @{Logname='application';ID=11707} | select TimeCreated,ID,Message |ft -auto -wrap

Get-WinEvent -ea 0 -FilterHashtable @{Logname='application';ID=11724} | select TimeCreated,ID,Message |ft -auto -wrap

There are many other events related to MsiInstaller; if you need to see all, filter the application log for event source of MsiInstaller.

Get-EventLog -LogName application -Source MsiInstaller

Service start and state change events.

If you want track the services when they started, here is a one liner:

Get-WinEvent -ea 0 -FilterHashtable @{Logname='system';ID=7045} | select TimeCreated,ID,Message |ft -auto -wrap

Note that configuration changes and state changes for a service is tracked by event ID 7036; this is already part of the LRUP code.

Get-WinEvent -ea 0 -FilterHashtable @{Logname='system';ID=7036} | select TimeCreated,ID,Message |ft -auto -wrap

Symantec Risk log.

Symantec logs the risks identified in application event log; to get the specific log, issue this one liner:

Get-WinEvent -ea 0 -FilterHashtable @{Logname='application';ID=51} | select TimeCreated,ID,Message |ft -auto -wrap

Volume Shadow Copy shutdown events.

Some of the malware may shutdown the VSS; the below one liner will give you more information on this log.

Get-WinEvent -ea 0 -FilterHashtable @{Logname='application';ID=8224} | select TimeCreated,ID,Message |ft -auto -wrap

LRUP code has a one liner to show the shadow copies created in a system; it's given below as well.

Gwmi -ea 0 Win32_ShadowCopy | select DeviceObject,@{NAME='CreationDate';EXPRESSION={$_.ConvertToDateTime($_.InstallDate)}} 

Monday, August 3, 2015

More artifacts through PowerShell - Part 5

MS Office Trust Records.

When documents are downloaded from untrusted sources, a "trust" prompt is shown to the user when the user wants to edit the document. The full path of the document is saved under the below registry key when this happens.

Software\Microsoft\Office\*\PowerPoint\Security\Trusted Documents\TrustRecords (* should be replaced with the version of the MS Office installed in the system but for PowerShell gathering, we can still use the * as shown below:)

gp hkcu:'\Software\Microsoft\Office\*\Excel\Security\Trusted Documents\TrustRecords' | select * -ExcludeProperty PS*
gp hkcu:'\Software\Microsoft\Office\*\PowerPoint\Security\Trusted Documents\TrustRecords' | select * -ExcludeProperty PS*
gp hkcu:'\Software\Microsoft\Office\*\Word\Security\Trusted Documents\TrustRecords' | select * -ExcludeProperty PS*

Want to see all with one command?

gci -r hkcu:'\Software\Microsoft\Office\*\*\Security\Trusted Documents' | select -ExpandProperty Property


Decrypting UserAssist key entries.

Forensic use of UserAssist keys are well known. It primarily stores information about actions the user took with the Shell; actions such as starting applications, double clicking shortcuts, etc. Entries in the UserAssist keys are ROT13 encrypted, the encrypted entries can be viewed by issuing the following one liner.

gp "hkcu:\Software\Microsoft\Windows\Currentversion\Explorer\Userassist\*\Count" | ft -auto -wrap

In order to decrypt the entries, we can use the function provided in this blog.


Chrome Local Storage entries.

Local storage in Chrome browser is part of HTML5 specification; it is designed to store persistent data (even after the browser is closed) local to the system such as the cookies. This is in SQLite format but can be accessed through PowerShell to get a rough idea about the web sites visited.

Here is the one liner for this:

dir $env:LOCALAPPDATA\'Google\Chrome\User Data\Default\Local Storage' | Sort-Object LastWriteTime -desc


Saturday, July 4, 2015

More artifacts through PowerShell - Part 4

Typed URLs - alternate location.

The main script LRUP already contain many IE related artifacts; here is one more that we can add to the list.
Under APPDATA, the system keeps a log of the URLs typed into the address bar to provide auto suggestion of the URLs that are being typed in. This log can be viewed using the Get-Content CmdLet.
     gc $env:LOCALAPPDATA\temp\structuredquery.log

DLLs and vendor information.

If you need to filter out the DLLs identified in the system that are non-Microsoft related, use the below one liner. For more information, check Trevor Sullivan's article.

$ProcExes = Get-WmiObject -Class CIM_ProcessExecutable; foreach ($item in $ProcExes) {[wmi]"$($item.Antecedent)" | ? { $_.Manufacturer -ne 'Microsoft Corporation' } | select FileName,Extension,Manufacturer,Version |ft -auto -wrap}

Application Compatibility related.

Application compatibility is a feature that can make older programs that have compatibility problems work better in Windows 7 and Windows 2008 operating systems.

System tracks the programs installed under the below registry key. Note that it "stores the list of all programs for which it came up under the following key for each user, even if no compatibility modes were applied (e.g. in the case where the user reported that the program worked correctly)"  - MSDN link 

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Persisted

In PowerShell, this can be gathered through the following one liner:

gp hkcu:'\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Persisted' | select * -ExcludeProperty PS*

Since it is taken from HKCU location, it is an indication that the particular user ran these programs. 


Sunday, June 28, 2015

More artifacts through PowerShell - Part 3

The main LRUP code lists many event logs that are useful in an incident response scenario. In this section, let's look some additional event logs that are going to be useful to collect.

Firewall related.

The below log shows the firewall rule changes and other actions such as profile changes.

Get-winevent -logname "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall" | ft -auto -wrap 

Network related.

The below log shows the time when a network is changed from a home network to office network.

Get-winevent -logname Microsoft-Windows-BranchCache/Operational  | ft -auto -wrap

The below log shows when a network connection was made. 

Get-winevent -logname Microsoft-Windows-NetworkProfile/Operational  | ft -auto -wrap

Below log should be checked to see the RDP logins. More information on the event IDs is available at this MS link.

Get-winevent -logname Microsoft-Windows-TerminalServices-LocalSessionManager | ft -auto -wrap

Driver related.

Looking at the below log helps identify code integrity issues related to bad drivers or unsigned drivers. More information is available at this MSDN link.

Get-winevent -logname Microsoft-Windows-CodeIntegrity/Operational | ft -auto -wrap

Speaking of drivers, we can use the below command to get a listing of PnP related driver information.

Get-WmiObject -Class Win32_PnPEntity | select Caption,Name,Service

When a device is attached the computer, Windows attempts to detect the device type and install the appropriate driver so that it can communicate and control the device.

Completion of a device driver installation attempt gets recorded as an event ID 20001 message in the 'System' event log. The message provides device identification information and a status code for the device installation process. Devices that install successfully log an Event ID 20001 message with a status code of 0. To see this event, we can use the below one liner.

Get-WinEvent -ea 0 -FilterHashtable @{Logname='system';ID=20001} | select TimeCreated,ID,Message |ft -auto -wrap

Sunday, June 21, 2015

More artifacts through PowerShell - Part 2

Quickly identify a login event.

    Get-WinEvent -FilterHashtable @{Logname='security';ID=4624} | ft -auto -wrap

Quickly identify a login event for a particular user.

   Get-WinEvent -FilterHashtable @{Logname='security';ID=4624} | where {$_.message -like ‘*john*’ } | ft -auto –wrap

Quickly identify a login event for multiple users.

   Get-WinEvent -FilterHashtable @{Logname='security';ID=4624} | where {$_.message -like ‘*john*’ -or $_.message -like ‘*jane*’} | ft -auto –wrap

Quickly identify login events between two dates.

  Get-WinEvent -FilterHashtable @{Logname='security';ID=4624 ;StartTime="5/1/15";EndTime="5/31/15"} | ft -auto –wrap

Login events for a particular user between two dates.

  Get-WinEvent -FilterHashtable @{Logname='security';ID=4624 ;StartTime="5/25/15";EndTime="5/30/15"} | where {$_.message -like ‘*john*’ } | ft -auto –wrap

Quickly identify error events for previous day.

  Get-EventLog -LogName System -EntryType error -After (Get-Date).AddDays(-1) | ft -auto -wrap

Error events for a specific source such as NETLOGON

  Get-EventLog -LogName System -EntryType error -Source NETLOGON -After (Get-Date).AddDays(-1) | ft -auto -wrap

As a reminder, you can export any of these into a text file with the 'out-file' option; an example:

  Get-EventLog -LogName System -EntryType error -After (Get-Date).AddDays(-1) | ft -auto -wrap | out-file c:\event.txt

Saturday, June 20, 2015

More artifacts through PowerShell - Part 1

Identify currently logged in user.

If the requirement is to get only the logged in user along with the time of login then use "whoami' or "quser".

To see the privileges assigned for the currently logged in user.

whoami /priv /fo csv | convertfrom-csv | ft -auto -wrap

To identify the user profiles created.

User profiles can be checked by looking at the below registry location using Get-ItemProperty CmdLet.

Get-ItemProperty hklm:'\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' |Select-Object PSChildName, ProfileImagePath | ft -auto -wrap

To identify users and processes that were started.

There are multiple commands that can be used but the builtin command 'qprocess' is the optimal one. It is similar to tasklist, but produces better output. It shows username, session id, pid, and image name.

Another useful command is 'qwinsta'. This builtin command shows RDP sessions as well.

'quser' is another useful command; this shows the logged in users, session name, time, etc. This command is extremely useful in a server environment.

To see if the user is part of administrator group.

net localgroup administrators .This command will show all the users that are part of the group 'administrators'.

Sunday, June 7, 2015

PowerShell updates

Have received many questions offline on the use of PowerShell and how we can get the desired artifacts from Windows system. While I have responded to most of those, I haven't gotten opportunity to update them here. I will try and update them here in a series of posts in the coming days.

The commands and options I will be posting are to be used in addition to the already published commands in the LRUP code and the SANS paper.

LRUP code is available here.

Monday, September 30, 2013

Howto - Creating a ZIP file of LRUP outputs

One of the requests I got was to combine the output of all the text files and compress it so that a single file can be sent by the user from their machine to the IR analyst.

If you want to use an external tool like 7-Zip that can be processed from the command line, it is easy to implement. However, if you want to use an in-built tool or script then there are multiple options.

There is a CodePlex project for this, check out

As an another option, take a look at David Aiken's post from MSDN.

Relevant portions of the code along with the option to combine the various text files is listed below:

function New-Zip
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false

new-zip $UserDirectory\desktop\$CompName-$User-$

function Add-Zip

if(-not (test-path($zipfilename)))
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false

$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)

foreach($file in $input)
            Start-sleep -milliseconds 500

gci $UserDirectory\desktop\$CompName-$User-$Date-Level1.html | add-Zip $UserDirectory\desktop\$CompName-$User-$

gci $UserDirectory\desktop\$CompName-$User-$Date-HostsFile.txt | add-Zip $UserDirectory\desktop\$CompName-$User-$

gci $UserDirectory\desktop\$CompName-$User-$Date-OpenFiles.txt | add-Zip $UserDirectory\desktop\$CompName-$User-$

gci $UserDirectory\desktop\$CompName-$User-$Date-AuditPolicy.txt | add-Zip $UserDirectory\desktop\$CompName-$User-$

gci $UserDirectory\desktop\$CompName-$User-$Date-FirewallConfig.txt | add-Zip $UserDirectory\desktop\$CompName-$User-$

#Clean-up routine

rm $UserDirectory\desktop\$CompName-$User-$Date-Level*.html

rm $UserDirectory\desktop\$CompName-$User-$Date-*.txt

Friday, August 30, 2013

LRUP Code published

Code used in the paper is now available from the CodePlex site.

This is a version 2.0, which is optimized for PowerShell V2. All new updates will be available at the CodePlex site from now on.

Comments and suggestions can be posted here.

Friday, August 23, 2013

SANS Gold paper on PowerShell

I have been working on a paper for the SANS Gold certification. The topic I chose was Live Response using PowerShell.

It was a great experience writing it and learning a great deal of  stuff on Windows operating system and PowerShell.

Finally, early this week I got the confirmation from SANS that it has been approved and published.

Paper is available on SANS reading room web site and direct download is available here.

Look for more details on the code and other developments in later posts.