Threat Hunting with Kape Across the Enterprise

Gökhan Aydın
6 min readFeb 22, 2021

--

If you are doing digital forensics investigation or threat hunting you probably know one of the key source is execution artifacts. My aim was collecting and processing execution artifacts for many machines and analyze these all together.

Before we start, I am going to put some useful link regarding with what I will write about. I will not deep dive everything what I did. So you can use these links to study the topics comprehensively.

Shimcache(AppCompactCache) and Amcache [1]

OBJECTS.DATA [1][2]

KAPE [1][2]

Method;

Collecting execution artifacts with Kape, processing these artifacts and then analyze these outputs all together.

Some requirements;

  • KAPE

Kape is a free command line and GUI utility for collecting triage data on the live systems or mounted images. Download link

  • SCCM or EDR

SCCM or EDR agents can be used for uploading or executing KAPE on the target machines. I will use CarbonBlack Response api for this. (Maybe you can put KAPE on a UNC path in that case you just need to execute it with EDR or SCCM)

  • SFTP Server

Kape has the ability to send the collected files to the sftp server. Maybe EDR can be used to download these files, but using sftp is much easier. Kape will do this for you.

Note: If you are going to use kape with sftp server like me. Make sure that the machine has firewall permissions to reaching the sftp server, if not kape will not be executed.

  • Munin

Munin is a python based command line utility for querying Virustotal api. Download link

  • WSL or bash

I am going to use some basic bash commands for analyzing csv files. Basically with WSL you can use Linux binaries in Windows OS.

Let’s prepare a KAPE zip for collecting and processing execution artifacts.

We don’t need all of the KAPE files. We are going to collect SYSTEM Registry file, Amcache.hve and OBJECTS.DATA. That’s why we are gonna keep the necessary files and parser for execution artifacts we are going to collect.

Before — After
Before — After

Now we have approximately 20 MB zip file.

After we create zip for kape, we need a cli file in order to executing kape with predefined arguments.

We can just open gkape.exe and select needed arguments and copy the arguments to “_kape.cli” file.

Selecting arguments on gkape
--tsource C: --tdest C:\Windows\CarbonBlack\artifacts --target Amcache,RegistryHivesSystem,WBEM --scs 192.168.198.140 --scp 22 --scu sftpuser --scpw p@ssw0rd --zip %m --mdest C:\Windows\CarbonBlack\outputs --zm true --module AmcacheParser,AppCompatCacheParser,CCM-RUA --zpw zippassword

When the kape executed it will take the arguments from this file.

If you are executing kape from UNC path you can’t use _kape.cli because after the first execution kape will change the file name something like YYYYDDMM_kape.cli when second computer execute kape it will search for _kape.cli but the first computer change the file name so it will exit without collect any data. Long story short if you are executing kape on UNC path you need to execute with arguments.

Uploading KAPE and 7z to target machines

import logging
import shutil
from cbapi.response import *
import cbapi
root = logging.getLogger()
root.addHandler(logging.StreamHandler())
logging.getLogger("cbapi").setLevel(logging.DEBUG)
cb = CbResponseAPI(timeout=30)
file = open("id.txt")
data = [row for row in file]
for d in data:
try:
with cb.select(Sensor, d).lr_session() as lr_session:
lr_session.put_file(open("KAPE.zip", "rb"), r"C:\Windows\CarbonBlack\KAPE.zip")
print("KAPE.zip Uploaded Sensor ID:{}".format(d))
with cb.select(Sensor, d).lr_session() as lr_session:
lr_session.put_file(open("7za.exe", "rb"), r"C:\Windows\CarbonBlack\7za.exe")
print("7za.exe Uploaded Sensor ID:{}".format(d))
except cbapi.errors.TimeoutError:
print("Timeout Error Sensor ID:{}".format(d))
except cbapi.live_response_api.LiveResponseError:
print("File Exists Sensor ID:{}".format(d))

This script will take sensor id of the target machines from the id.txt then upload the KAPE.zip and 7za.exe to the target machine.

Executing Kape

import logging
import shutil
from cbapi.response import *
import cbapi
root = logging.getLogger()
root.addHandler(logging.StreamHandler())
logging.getLogger("cbapi").setLevel(logging.DEBUG)
cb = CbResponseAPI(timeout=30)
file = open("id.txt")
data = [row for row in file]
for d in data:
try:
with cb.select(Sensor, d).lr_session() as lr_session:
lr_session.create_process(r'cmd.exe /c "7za.exe x KAPE.zip && C:\Windows\CarbonBlack\KAPE\kape.exe"')
print("KAPE Executed Sensor ID:{}".format(d))
except cbapi.errors.TimeoutError:
print("Timeout Error Sensor ID:{}".format(d))

I am going to use the script I shared above. It will unzip kape.zip and execute kape.exe.

After that we just need to wait. A few minutes later kape will start sending files to the SFTP server.

Sftp server will looks like this

After download files completed we need to unzip *ModulesOutput.zip files in the all folders.

I will use WSL for unzipping and analyzing outputs.

It’s important that every file has to be located under the folder named with own hostname. If you found something suspicious, you can just grep recursively the suspicious file. At the end you can understand which computers has executed that suspicious file. You will understand clearly what I meant when I show the examples.

for dir in */; do cd $dir; 7z x *_ModulesOutput.zip -pzippasword; cd - ;done

This command will unzip the processed files to the its own folder.

Let’s start analyzing the outputs.

Amcache

Eric Zimmerman’s amcache parser not only parsing Amcache.hve it also categorizing the executables. So I will only look for unassociated file entries. This blog post explaining more if you interested.

cat */ProgramExecution/*_Amcache_Unassociated* | cut -d , -f 4 | sort -u | grep -v SHA1 > sha1.txt

I like starting with the Amcache because it has SHA1 hash value for executables. Let’s grab SHA1 hashes for the executables and with munin we can check Virustotal results for these hash values. It will take some time because Virustotal has a limit 4 api query for 1 min. We will just start this and resume the analysis. It’s just a background job while we are analyzing.

After this I am gonna look for full path for executables. I have 940 unique value for 41 machines.

cat */ProgramExecution/*_Amcache_Unassociated* | cut -d , -f 6| sort -u

Let’s say ‘appcmd.exe’ looks malicious and you want to check Virustotal or somewhere else and which systems has executed this malicious executable.

cat */ProgramExecution/*_Amcache_Unassociated* | cut -d , -f 4,6| grep -ia appcmd.exe
grep -ia appcmd.exe */ProgramExecution/* |cut -d '/' -f 1 |sort -u

grep doesn’t like weird characters that’s why I’m using -a flag and using -i flag for caseinsensivity.

Looks like 6 machines has executed this executable.

Now we can just go back these machines collect some other triage data by using kape, if necessary we can take memory image and start deep dive analysis.

Shimcache or AppCompatCache

cat */ProgramExecution/*_AppCompatCache.csv | cut -d , -f 3 | sort -u

We have full path of executables from shimcache.

Shimcache is written to SYSTEM registry only after the computer is shutdown. So some shimcache entries will be stored on the memory until the shutdown.

OBJECTS.DATA

Cool thing about OBJECTS.DATA is, it has information like last user executed, last execution time, path of executable, launch count and some metadata about executable. Usually legal executables has metadata but malicious ones has not.

cat */ProgramExecution/SCCM* | cut -d$'\t' -f 2,3 | sed 's/["[:space:]"]//g' |sort -u

Conclusion

We’ve taken a look at a couple of execution artifacts that can be very useful during an investigation or a threat hunting. If you have any suggestions or question about this study you can reach me on twitter.

Happy hunting.

--

--