digital forensics

Triaging Windows with KAPE

Run targeted forensic artifact collection and module parsing with KAPE.

artifact-collectiondfirdigital-forensicseric-zimmermanincident-responsekapetriagewindows-forensics
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Authorized Use Only: KAPE collects forensic artifacts from systems. Only run KAPE against systems you own or are explicitly authorized in writing to acquire and analyze. Preserve chain of custody and follow your organization's evidence-handling procedures.

Overview

KAPE (Kroll Artifact Parser and Extractor) is a free, Windows-native triage tool authored by Eric Zimmerman and distributed by Kroll. It performs two distinct phases controlled by separate configuration sets:

  • Targets (.tkape files) define what to collect. KAPE uses the raw NTFS file system (via direct volume access) to copy locked/in-use files such as registry hives, $MFT, event logs, prefetch, browser databases, and LNK files without triggering anti-tamper protections. Targets can be chained into "compound" targets (for example KapeTriage, !SANS_Triage) that pull a forensically rich subset in minutes.
  • Modules (.mkape files) define how to process collected (or live) data. Modules wrap external binaries — primarily Eric Zimmerman's tools (PECmd, MFTECmd, RECmd, etc.) — and emit normalized CSV/JSON output. The !EZParser compound module runs the full EZ Tools suite against a target collection.

KAPE ships with both a CLI (kape.exe) and a GUI front end (gkape.exe). Because of its speed, KAPE lets responders prioritize which hosts warrant deep forensic imaging, making it a cornerstone of modern remote/at-scale DFIR triage.

When to Use

  • During the early containment/triage phase of an incident when you need execution, persistence, and account artifacts from one or many hosts quickly.
  • When full disk imaging is impractical (large disks, remote sites, time pressure) but you still need a defensible, parseable artifact set.
  • When automating collection across a fleet via remote execution (PSExec, EDR live response, SOAR) using batch-mode _kape.cli files.
  • When you need to collect from Volume Shadow Copies to recover historical artifact states.

Prerequisites

  • Windows host (KAPE runs on Windows; EZ Tools modules require the .NET runtime bundled with the tools).
  • Download KAPE from the official source (free, registration required): https://www.kroll.com/kape
  • Administrator privileges (required for raw volume access and VSS).
  • Update Targets, Modules, and the bundled binaries:
    REM From the KAPE directory, sync community Targets/Modules from GitHub
    kape.exe --sync
     
    REM Download/update the EZ Tools binaries that Modules invoke
    Get-KAPEUpdate.ps1
  • A clean, write-protected destination (external drive or network share) separate from the evidence source.

Objectives

  • Collect a forensically sound triage artifact set from a target volume.
  • Optionally include Volume Shadow Copies for historical recovery.
  • Package output as a VHDX/ZIP container with hashing for chain of custody.
  • Run modules to parse the collection into analyst-ready CSV/JSON.
  • Build a repeatable batch-mode collection for fleet deployment.

MITRE ATT&CK Mapping

ID Official Technique Name Relevance to this skill
T1005 Data from Local System KAPE reads artifacts directly from the local file system; defenders use the same capability to forensically acquire that data for analysis.

KAPE is a defensive DFIR tool. The mapping reflects the data-source artifacts (local file system) that adversary actions leave behind and that KAPE preserves for investigation.

Workflow

1. Sync configurations and update binaries

Always work from current Targets/Modules and EZ Tools binaries so parsers match the latest artifact formats.

cd C:\KAPE
kape.exe --sync

2. Inventory available Targets and Modules

List what is available before building a collection so you scope precisely.

REM Show all Targets
kape.exe --tlist
 
REM Show all Modules
kape.exe --mlist

3. Collect a triage target set

Targets require the three switches --tsource, --target, and --tdest. --tflush clears the destination first. Use a compound target such as KapeTriage for a fast, broad pull.

kape.exe --tsource C: ^
         --target KapeTriage ^
         --tdest E:\kape_out\HOST01\tdest ^
         --tflush

4. Include Volume Shadow Copies

Add --vss to also process every VSS snapshot on the source volume, recovering historical artifact states.

kape.exe --tsource C: ^
         --target !SANS_Triage ^
         --tdest E:\kape_out\HOST01\tdest ^
         --vss --tflush

5. Package the collection as a container with hashing

--vhdx (or --zip) wraps the output into a single mountable/transportable container. --vhdx takes a base name (an identifier), NOT a filename. KAPE writes a console log and copy log you should retain.

kape.exe --tsource C: ^
         --target KapeTriage ^
         --tdest E:\kape_out\HOST01\tdest ^
         --vhdx HOST01 --tflush --gui

6. Process the collection with Modules

Modules require --module and --mdest. Point --msource at the collected target output and run !EZParser to parse everything into CSV/JSON.

kape.exe --msource E:\kape_out\HOST01\tdest\C ^
         --mdest E:\kape_out\HOST01\mdest ^
         --module !EZParser ^
         --mflush

7. One-shot collect + parse

You can collect and process in a single invocation by supplying both Target and Module switches.

kape.exe --tsource C: ^
         --target KapeTriage ^
         --tdest E:\kape_out\HOST01\tdest ^
         --mdest E:\kape_out\HOST01\mdest ^
         --module !EZParser ^
         --tflush --mflush --vss

8. Build a batch-mode _kape.cli for fleet deployment

KAPE reads a _kape.cli file (one argument set per line) placed next to kape.exe and executes each line in sequence — ideal for pushing identical collection via EDR/PSExec. Generate the exact CLI from the GUI's "Copy command line" button, then drop it into _kape.cli.

REM Contents of _kape.cli (each line = one full KAPE run):
--tsource C: --target KapeTriage --tdest %%d\Disk\%%m --vhdx %%m --zv false

%%d resolves to the KAPE directory and %%m to the machine name, so a single CLI auto-names output per host. Launch by running kape.exe with no arguments.

9. Verify integrity

Confirm KAPE's CopyLog, ConsoleLog, and SkipLog CSVs are present in the target output, and validate the SHA-1 hashes KAPE records for each copied file against the source where possible.

Tools and Resources

Resource Purpose Link
KAPE download Official Kroll distribution (free) https://www.kroll.com/kape
KAPE Documentation MDwiki docs for switches and config https://ericzimmerman.github.io/KapeDocs/
KapeFiles repo Community Targets and Modules https://github.com/EricZimmerman/KapeFiles
EZ Tools Parsers invoked by KAPE Modules https://ericzimmerman.github.io/
KAPE on SANS Background, history, methodology https://www.sans.org/tools/kape/

Key Switches

Switch Phase Purpose
--tsource Target Source volume/drive to collect from
--target Target Target or compound target name
--tdest Target Destination for collected files
--tflush Target Empty --tdest before collecting
--vss Target Process all Volume Shadow Copies
--vhdx / --zip Target Package output into a container (base name)
--module Module Module or compound module name
--msource Module Source data for module processing
--mdest Module Destination for parsed output
--mflush Module Empty --mdest before processing
--sync Both Update Targets/Modules from GitHub
--tlist / --mlist Both List available Targets / Modules

Validation Criteria

  • KAPE Targets/Modules and EZ Tools binaries synced to current versions
  • Triage target collected with --tsource, --target, --tdest
  • Volume Shadow Copies included where historical state is needed
  • Output packaged as VHDX or ZIP for transport/chain of custody
  • CopyLog/ConsoleLog/SkipLog present and reviewed
  • Modules run (!EZParser) producing CSV/JSON in --mdest
  • File hashes recorded and verified against source
  • Batch _kape.cli validated for fleet deployment where applicable
Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 2

api-reference.md3.1 KB

KAPE Command Reference

KAPE has two execution phases: Target (collection) and Module (processing). Switches use -- prefix. kape.exe is the CLI; gkape.exe is the GUI.

Target (collection) switches

Switch Required Description
--tsource yes Source drive/volume to copy from (e.g. C:, D:, F:\)
--target yes Target/compound target name(s), comma-separated (e.g. KapeTriage, !SANS_Triage, RegistryHives,EventLogs)
--tdest yes Destination directory for collected files
--tflush no Delete contents of --tdest before copy
--vss no Process all Volume Shadow Copies on --tsource (default false)
--vhdx <name> no Create a VHDX container from --tdest; value is a base identifier, not a filename
--vhd <name> no Create a VHD container instead of VHDX
--zip <name> no Create a ZIP of the collection
--zv no Add --tdest to container then delete originals (true/false)

Module (processing) switches

Switch Required Description
--module yes Module/compound module name(s) (e.g. !EZParser, PECmd, MFTECmd)
--mdest yes Destination for parsed module output (CSV/JSON/HTML)
--msource no Source data for processing (defaults to --tdest if collecting+processing)
--mflush no Delete contents of --mdest before processing
--mef no Module export format override

Global / utility switches

Switch Description
--sync Update Targets and Modules from the KapeFiles GitHub repo
--tlist List all available Targets
--mlist List all available Modules
--gui Open progress in GUI window when launched from CLI
--debug Verbose debug logging
--trace Even more verbose tracing

Example command lines

REM Triage collection
kape.exe --tsource C: --target KapeTriage --tdest E:\out\tdest --tflush
 
REM Collection with VSS + VHDX container
kape.exe --tsource C: --target !SANS_Triage --tdest E:\out\tdest --vss --vhdx HOST01 --tflush
 
REM Process an existing collection with all EZ Tools
kape.exe --msource E:\out\tdest\C --mdest E:\out\mdest --module !EZParser --mflush
 
REM Collect and parse in one run
kape.exe --tsource C: --target KapeTriage --tdest E:\out\tdest --mdest E:\out\mdest --module !EZParser --tflush --mflush

Batch mode

Place a _kape.cli file beside kape.exe. Each non-comment line is one full argument set; run kape.exe with no args to execute all lines. Variables: %d = KAPE directory, %m = machine name.

--tsource C: --target KapeTriage --tdest %d\Disk\%m --vhdx %m

Config file types

Extension Purpose
.tkape Target definition (what to collect)
.mkape Module definition (how to process)
_kape.cli Batch command file

Output logs (chain of custody)

  • <timestamp>_CopyLog.csv — every file copied with source/dest and SHA-1
  • <timestamp>_ConsoleLog.txt — full console output
  • <timestamp>_SkipLog.csv — files skipped and why
standards.md1.1 KB

Standards and Framework Mapping — Triaging Windows with KAPE

NIST Cybersecurity Framework 2.0

ID Name Rationale
RS.AN-03 Analysis is performed to establish what has taken place during an incident and the root cause of the incident KAPE rapidly collects and parses host artifacts (execution, persistence, account, file-system) that establish the sequence of attacker activity and root cause during incident response.

MITRE ATT&CK

ID Name Rationale
T1005 Data from Local System KAPE acquires forensic data directly from the local file system; this same data source is what adversaries target with T1005 and what responders must preserve and analyze.

Supporting References

Scripts 1

agent.py6.2 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
KAPE triage helper.

Builds and (optionally) executes validated KAPE command lines for collection
and module processing, generates batch _kape.cli files for fleet deployment,
and verifies CopyLog hashes for chain of custody.

KAPE is Windows-only; this helper builds the commands and runs them via
subprocess when executed on Windows with kape.exe available. It also works as
a pure command generator on any platform (--dry-run).

Reference: https://ericzimmerman.github.io/KapeDocs/
"""
import argparse
import csv
import hashlib
import os
import subprocess
import sys
from pathlib import Path


def build_collect_cmd(kape, tsource, target, tdest, vss=False, container=None,
                      tflush=False, module=None, mdest=None, mflush=False):
    """Construct a KAPE target (and optional module) command as an argv list."""
    if not tsource or not target or not tdest:
        raise ValueError("collection requires --tsource, --target and --tdest")
    cmd = [kape, "--tsource", tsource, "--target", target, "--tdest", tdest]
    if tflush:
        cmd.append("--tflush")
    if vss:
        cmd.append("--vss")
    if container:
        # container is a base identifier, NOT a filename
        cmd += ["--vhdx", container]
    if module:
        if not mdest:
            raise ValueError("module processing requires --mdest")
        cmd += ["--module", module, "--mdest", mdest]
        if mflush:
            cmd.append("--mflush")
    return cmd


def build_process_cmd(kape, msource, mdest, module, mflush=False):
    """Construct a KAPE module-only processing command."""
    if not msource or not mdest or not module:
        raise ValueError("processing requires --msource, --mdest and --module")
    cmd = [kape, "--msource", msource, "--mdest", mdest, "--module", module]
    if mflush:
        cmd.append("--mflush")
    return cmd


def write_batch_cli(kape_dir, target, container=True):
    """Write a _kape.cli batch file using %d (kape dir) and %m (machine) tokens."""
    line = f"--tsource C: --target {target} --tdest %d\\Disk\\%m"
    if container:
        line += " --vhdx %m"
    cli_path = Path(kape_dir) / "_kape.cli"
    cli_path.write_text(line + "\n", encoding="utf-8")
    return cli_path


def verify_copylog(copylog_path):
    """Re-hash copied files listed in a KAPE CopyLog CSV and compare SHA-1."""
    results = {"ok": 0, "mismatch": 0, "missing": 0}
    with open(copylog_path, newline="", encoding="utf-8-sig") as fh:
        reader = csv.DictReader(fh)
        # KAPE CopyLog columns vary; look for dest path + sha1 columns flexibly
        for row in reader:
            dest = row.get("DestinationFile") or row.get("CopiedTo") or row.get("Destination")
            expected = (row.get("SHA1") or row.get("Sha1") or "").lower().strip()
            if not dest or not expected:
                continue
            if not os.path.isfile(dest):
                results["missing"] += 1
                continue
            h = hashlib.sha1()
            with open(dest, "rb") as f:
                for chunk in iter(lambda: f.read(65536), b""):
                    h.update(chunk)
            if h.hexdigest().lower() == expected:
                results["ok"] += 1
            else:
                results["mismatch"] += 1
                print(f"[!] HASH MISMATCH: {dest}", file=sys.stderr)
    return results


def run(cmd, dry_run):
    print("[*] " + " ".join(f'"{c}"' if " " in c else c for c in cmd))
    if dry_run:
        return 0
    try:
        proc = subprocess.run(cmd, check=False)
        return proc.returncode
    except FileNotFoundError:
        print(f"[!] kape executable not found: {cmd[0]}", file=sys.stderr)
        return 127


def main():
    p = argparse.ArgumentParser(description="KAPE triage helper")
    p.add_argument("--kape", default="kape.exe", help="Path to kape.exe")
    p.add_argument("--dry-run", action="store_true", help="Print commands, do not execute")
    sub = p.add_subparsers(dest="cmd", required=True)

    c = sub.add_parser("collect", help="Collect a target set")
    c.add_argument("--tsource", required=True)
    c.add_argument("--target", required=True)
    c.add_argument("--tdest", required=True)
    c.add_argument("--vss", action="store_true")
    c.add_argument("--container", help="VHDX base identifier")
    c.add_argument("--tflush", action="store_true")
    c.add_argument("--module")
    c.add_argument("--mdest")
    c.add_argument("--mflush", action="store_true")

    pr = sub.add_parser("process", help="Process a collection with modules")
    pr.add_argument("--msource", required=True)
    pr.add_argument("--mdest", required=True)
    pr.add_argument("--module", required=True)
    pr.add_argument("--mflush", action="store_true")

    b = sub.add_parser("batch", help="Write a _kape.cli batch file")
    b.add_argument("--kape-dir", required=True)
    b.add_argument("--target", default="KapeTriage")
    b.add_argument("--no-container", action="store_true")

    v = sub.add_parser("verify", help="Verify CopyLog SHA-1 hashes")
    v.add_argument("--copylog", required=True)

    args = p.parse_args()
    try:
        if args.cmd == "collect":
            cmd = build_collect_cmd(args.kape, args.tsource, args.target, args.tdest,
                                    vss=args.vss, container=args.container,
                                    tflush=args.tflush, module=args.module,
                                    mdest=args.mdest, mflush=args.mflush)
            return run(cmd, args.dry_run)
        if args.cmd == "process":
            cmd = build_process_cmd(args.kape, args.msource, args.mdest,
                                    args.module, mflush=args.mflush)
            return run(cmd, args.dry_run)
        if args.cmd == "batch":
            path = write_batch_cli(args.kape_dir, args.target,
                                   container=not args.no_container)
            print(f"[+] Wrote {path}")
            return 0
        if args.cmd == "verify":
            res = verify_copylog(args.copylog)
            print(f"[+] verified ok={res['ok']} mismatch={res['mismatch']} missing={res['missing']}")
            return 1 if res["mismatch"] else 0
    except ValueError as e:
        print(f"[!] {e}", file=sys.stderr)
        return 2


if __name__ == "__main__":
    sys.exit(main())
Keep exploring