Using PowerShell and Python to Analyze Amcache

I wanted to write this post on using PowerShell and Python, specifically PowerForensics and the pandas library to remotely copy the Amcache.hve file from multiple computers and then use amcacheparser.exe to parse all the amcache files and then load them all up into a pandas DataFrame for analysis.

What you will need to accomplish this, the way that I am showing are PSRemoting turned on in your environment, Jared Atkinson’s PowerForensics module, Python with the pandas library installed and amcacheparser.exe.

Step 1. Remote Collection of Amcache.hve

This first command will go out to a list of computers in the $comp variable and then using the PowerForensics cmdlet Get-ForensicFileRecord copy the amcache.hve file to the C: directory of the remote computer and name it .hve.

invoke-command -ComputerName $comp -ScriptBlock {add-powerforensicstype;$r = Get-ForensicFileRecord -path C:\Windows\appcompat\Programs\Amcache.hve;
$r.copyfile(“C:\$env:computername.hve”)}

Then we need to copy it back to our analyst box and clean up the copied amcache.hve file from the remote computer. This is accomplished with these commands.

foreach ($c in $comp) {
cp \\$c\c$\$c.hve -Destination C:\Users\PC1\Desktop\amcache\}

invoke-command -ComputerName $comp -ScriptBlock {rm “C:\$env:computername.hve”}

Now that we have all of our amcache files on our analyst machine it is time to start parsing the files with Amcacheparser.exe to produce our tsv files so we can load them up into a pandas DataFrame for analysis.

Step 2. Parse Amcache Files with Amcacheparser.exe

So with these commands I first store all the file names into a variable and then run a foreach command using the variable to run amcacheparser against every file.

$files = ls | select -ExpandProperty name

foreach ($f in $files) {

path\to\AmcacheParser.exe -f $f — csv path\to\hve files

}

Now you have all your amcache files parsed into tsv files and now it’s time to load it up into pandas and start analysis.

Step 3. Load tsv Files into Pandas DataFrame

Here I am importing the pandas library as pd and saving all of the filenames into a python list.

import pandas as pd

filenames = [‘20180201185717_PC1_Unassociated file entries.tsv’,
‘20180201185720_PC2_Unassociated file entries.tsv’,
‘20180201185723_PC3_Unassociated file entries.tsv’]

Next I am creating an empty list to hold my list of DataFrames and then using a for loop to create a pandas DataFrame from each tsv file and then putting it into the dataframes variable.

dataframes = []
for f in filenames:
dataframes.append(pd.read_csv(f,sep=’\t’))

Now we will concatenate all the stored DataFrames in our dataframes variable to create one large DataFrame named df.

df = pd.concat(dataframes)
pd.set_option(‘display.max_rows’,500)

Step 4. Start Analysis of Your Data

The first command will show you the first 5 rows of your DataFrame to get a feel for the data.

df.head()

The next command gives you some idea of the structure of you DataFrame to include types, rows and columns.

df.info()

Now from here you are only limited by your imagination on how you want to analyze the data. I will show you a few queries I used as an example. This first command will show you if you have any svchost.exe processes that are running from somewhere other than c:\windows\system32\svchost.exe.

This command pretty much asks: SELECT df WHERE df[‘Name’] = svchost.exe AND svchost.exe path IS NOT EQUAL TO c:\windows\system32\svchost.exe.

df[(df[‘Name’]==’svchost.exe’) & (df[‘FullPath’] != ‘c:\windows\system32\svchost.exe’)]

This next command is stack counting all my processes and showing me the 100 least used processes.

df[‘Name’].value_counts().tail(100)

This next command will show me the entire row of the selected executable.

df[df[‘Name’]==’adobearmhelper.exe’]

These last few commands are doing stack counting on selected columns and looking at the row where ProductName equals shockwave flash.

df[‘ProductName’].value_counts().tail(50)
df[df[‘ProductName’]==’shockwave flash’]
df[‘FullPath’].value_counts().tail(100)

So I hope this post was useful and please leave a comment if you have any questions.

Happy Hunting,

Marcus

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s