npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
When to Use
- Determining which programs have existed or executed on a Windows system during incident response
- Correlating SHA-1 hashes from Amcache against known malware databases (VirusTotal, CIRCL, MISP)
- Building an application installation and execution timeline for forensic investigations
- Identifying deleted executables that leave traces in Amcache even after file removal
- Investigating insider threats by documenting which portable or unauthorized applications were present
- Analyzing driver loading history to detect rootkits or malicious kernel modules
Do not use as sole proof of program execution. Amcache proves file existence and metadata registration, but ShimCache (AppCompatCache) and Prefetch provide stronger execution evidence. Use all three artifacts together for conclusive analysis.
Prerequisites
- A forensic image or live triage copy of
C:\Windows\appcompat\Programs\Amcache.hve(and associated.LOG1,.LOG2transaction logs) - Eric Zimmerman's AmcacheParser (
AmcacheParser.exe) downloaded from https://ericzimmerman.github.io/ - Eric Zimmerman's Timeline Explorer for viewing parsed CSV output
- Optionally: Registry Explorer for manual hive inspection
- A SHA-1 whitelist of known-good executables (e.g., NSRL hashset) for filtering
- .NET 6+ runtime installed (required by current EZ tools)
- Write access to an output directory for CSV results
Workflow
Step 1: Acquire the Amcache.hve File
Extract the Amcache hive from a forensic image or live system:
# From a live system (requires elevated privileges and raw copy tool)
# Amcache.hve is locked by the system; use a raw disk copy tool
# Option A: FTK Imager - mount image and navigate to:
# C:\Windows\appcompat\Programs\Amcache.hve
# Also collect: Amcache.hve.LOG1, Amcache.hve.LOG2
# Option B: Using KAPE for automated triage collection
kape.exe --tsource C: --tdest D:\Evidence\%m --target Amcache
# Option C: From a mounted forensic image (E: = mounted image)
copy "E:\Windows\appcompat\Programs\Amcache.hve" D:\Evidence\
copy "E:\Windows\appcompat\Programs\Amcache.hve.LOG1" D:\Evidence\
copy "E:\Windows\appcompat\Programs\Amcache.hve.LOG2" D:\Evidence\Always collect the transaction log files (.LOG1, .LOG2) alongside the hive. AmcacheParser replays uncommitted transactions from these logs to recover the most complete data.
Step 2: Parse Amcache with AmcacheParser
Run AmcacheParser against the acquired hive:
# Basic parsing with CSV output
AmcacheParser.exe -f "D:\Evidence\Amcache.hve" --csv "D:\Evidence\Output"
# Parse with a SHA-1 whitelist to exclude known-good entries (NSRL)
AmcacheParser.exe -f "D:\Evidence\Amcache.hve" -w "D:\Whitelists\nsrl_sha1.txt" --csv "D:\Evidence\Output"
# Parse with a SHA-1 inclusion list (only show matches against known-bad hashes)
AmcacheParser.exe -f "D:\Evidence\Amcache.hve" -b "D:\IOCs\malware_sha1.txt" --csv "D:\Evidence\Output"
# Include deleted entries with high-precision timestamps
AmcacheParser.exe -f "D:\Evidence\Amcache.hve" --csv "D:\Evidence\Output" -i --mpAmcacheParser produces multiple CSV files in the output directory:
| Output File | Contents |
|---|---|
Amcache_AssociatedFileEntries.csv |
File entries with SHA-1 hashes, paths, sizes, and timestamps |
Amcache_UnassociatedFileEntries.csv |
Orphaned file entries from older Amcache format |
Amcache_ProgramEntries.csv |
Installed program metadata (name, publisher, version, install date) |
Amcache_DeviceContainers.csv |
USB and device connection history |
Amcache_DevicePnps.csv |
Plug-and-Play device driver information |
Amcache_DriverBinaries.csv |
Loaded driver binaries with paths and hashes |
Step 3: Analyze File Entries for Suspicious Programs
Open the AssociatedFileEntries.csv in Timeline Explorer and examine key columns:
Key columns to review:
- ProgramId : Links file to its parent program entry
- SHA1 : Hash for threat intel lookups
- FullPath : Original file location on disk
- FileSize : Size of the executable
- FileKeyLastWriteTimestamp : When the Amcache entry was last updated
- Name : File name
- Publisher : Code signing publisher (blank = unsigned)
- BinProductVersion : Version string from the PE header
- LinkDate : PE compilation timestamp (useful for detecting timestomping)Filter for suspicious indicators:
# In Timeline Explorer, apply these filters:
# 1. Find unsigned executables (potentially malicious)
Publisher column = (empty)
# 2. Find executables from suspicious paths
FullPath contains: \temp\, \appdata\, \downloads\, \public\, \programdata\
# 3. Find executables with recent timestamps during incident window
FileKeyLastWriteTimestamp between: 2026-03-15 00:00:00 and 2026-03-16 00:00:00
# 4. Find executables with suspicious compilation dates (timestomping)
LinkDate year < 2015 AND FileKeyLastWriteTimestamp year = 2026Step 4: Correlate SHA-1 Hashes with Threat Intelligence
Extract SHA-1 hashes and check against malware databases:
# Extract unique SHA-1 hashes from the parsed output
# Using PowerShell to extract the SHA1 column
Import-Csv "D:\Evidence\Output\Amcache_AssociatedFileEntries.csv" |
Select-Object -ExpandProperty SHA1 -Unique |
Where-Object { $_ -ne "" } |
Out-File "D:\Evidence\Output\extracted_hashes.txt"
# Check hashes against VirusTotal using vt-cli
foreach ($hash in Get-Content "D:\Evidence\Output\extracted_hashes.txt") {
vt file $hash --format json | Select-Object -Property meaningful_name, last_analysis_stats
}
# Check hashes against CIRCL hashlookup
foreach ($hash in Get-Content "D:\Evidence\Output\extracted_hashes.txt") {
Invoke-RestMethod -Uri "https://hashlookup.circl.lu/lookup/sha1/$hash"
}
# Cross-reference with NSRL to identify known-good vs. unknown
# Unknown hashes that are not in NSRL warrant closer investigationStep 5: Analyze Program Entries for Unauthorized Installations
Review the ProgramEntries.csv for software the attacker may have installed:
Key columns in ProgramEntries:
- ProgramName : Display name of installed application
- ProgramVersion : Version string
- Publisher : Software publisher
- InstallDate : When the program was installed
- Source : Installation source (msi, exe, etc.)
- UninstallKey : Registry uninstall path
- PathsList : Installation directoriesLook for:
- Remote access tools (AnyDesk, TeamViewer, ngrok, Chisel)
- Hacking tools (Mimikatz, PsExec, Cobalt Strike)
- Tunneling utilities (plink, socat, WireGuard)
- Programs installed during the incident window
- Programs installed to non-standard locations
Step 6: Analyze Driver Binaries for Rootkit Evidence
Review the DriverBinaries.csv for suspicious loaded drivers:
Key columns in DriverBinaries:
- DriverName : Name of the driver
- DriverInBox : Whether it shipped with Windows (false = third-party)
- DriverSigned : Whether the driver has a valid signature
- DriverTimeStamp : Compilation timestamp
- Product : Product associated with the driver
- ProductVersion : Driver version
- SHA1 : Hash of the driver binaryFilter for DriverInBox = false and DriverSigned = false to find unsigned third-party drivers that may be rootkits or vulnerable drivers used in BYOVD (Bring Your Own Vulnerable Driver) attacks.
Step 7: Build a Timeline from Amcache Data
Combine Amcache data with other artifacts for a comprehensive timeline:
# Merge Amcache CSV with other EZ Tools output using Timeline Explorer
# Load the following CSVs into Timeline Explorer:
# - Amcache_AssociatedFileEntries.csv (file evidence)
# - Amcache_ProgramEntries.csv (install evidence)
# - Prefetch output from PECmd.exe (execution evidence)
# - ShimCache output from AppCompatCacheParser.exe (execution evidence)
# Sort all entries by timestamp to reconstruct the attack sequence
# Timeline Explorer supports multi-file loading and column-based sorting
# Export the combined timeline
# File > Save to CSV > combined_timeline.csvKey Concepts
| Term | Definition |
|---|---|
| Amcache.hve | A Windows registry hive at C:\Windows\appcompat\Programs\Amcache.hve that stores metadata about applications, files, and drivers for application compatibility purposes |
| Associated File Entry | An Amcache record linked to a specific program installation, containing file path, size, hash, and timestamps |
| Unassociated File Entry | An orphaned Amcache record from an older format that is not linked to a program entry; common on Windows 7/8 systems |
| Program Entry | Amcache record containing installation metadata: program name, version, publisher, install date, and uninstall key |
| SHA-1 Hash | Cryptographic hash stored in Amcache for each registered file, enabling malware identification through threat intelligence lookups |
| LinkDate | The PE compilation timestamp embedded in the executable header; discrepancy with file system timestamps may indicate timestomping |
| Transaction Logs | .LOG1 and .LOG2 files containing uncommitted registry transactions that AmcacheParser replays for complete data recovery |
| NSRL (National Software Reference Library) | NIST-maintained database of SHA-1 hashes for known commercial software, used as a whitelist to filter benign entries |
Verification
- Amcache.hve and transaction logs (LOG1, LOG2) were collected from the forensic image
- AmcacheParser produced all expected CSV output files without errors
- SHA-1 hashes were extracted and checked against VirusTotal or CIRCL hashlookup
- Unsigned executables in suspicious paths have been flagged for further analysis
- Program entries show all software installations within the incident window
- Driver binaries have been checked for unsigned or out-of-box entries
- LinkDate vs. FileKeyLastWriteTimestamp comparison has been performed to detect timestomping
- Amcache findings are correlated with Prefetch and ShimCache for execution confirmation
- Final timeline integrates Amcache data with other forensic artifacts
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 1
api-reference.md2.0 KB
API Reference: Analyzing Windows Amcache Artifacts
Amcache.hve Location
C:\Windows\AppCompat\Programs\Amcache.hveRegistry Keys
| Key Path | Contents |
|---|---|
| Root\InventoryApplicationFile | File execution evidence with SHA-1 |
| Root\InventoryApplication | Installed application metadata |
| Root\InventoryDevicePnp | PnP device connection history |
| Root\InventoryDriverBinary | Driver binary metadata |
regipy Python Library
pip install regipyfrom regipy.registry import RegistryHive
reg = RegistryHive('/path/to/Amcache.hve')
for subkey in reg.get_key('Root\\InventoryApplicationFile').iter_subkeys():
values = {v.name: v.value for v in subkey.iter_values()}
print(values.get('Name'), values.get('LowerCaseLongPath'))AmcacheParser (Eric Zimmerman)
# Parse Amcache.hve to CSV
AmcacheParser.exe -f C:\evidence\Amcache.hve --csv C:\output\
# Include device and driver entries
AmcacheParser.exe -f Amcache.hve --csv output\ -iOutput CSV Columns
| Column | Description |
|---|---|
| Name | Application/file name |
| LowerCaseLongPath | Full lowercase path |
| Publisher | Software publisher |
| FileId | SHA-1 hash (prefixed with 0000) |
| Size | File size in bytes |
| LinkDate | PE compilation timestamp |
| Version | File version string |
| ProgramId | Associated program GUID |
Forensic Value
| Artifact | Evidence |
|---|---|
| SHA-1 hash | File identification even after deletion |
| LowerCaseLongPath | Execution path including USB/temp |
| LinkDate | PE compile time (timestomping detection) |
| Publisher | Legitimacy verification |
| Last Modified | Registry key update timestamp |
Suspicious Indicators
| Pattern | Concern |
|---|---|
| Path contains \Temp\ | Execution from temp directory |
| Path contains \Downloads\ | User-downloaded execution |
| Missing Publisher | Unsigned/unknown binary |
| LinkDate far from file date | Possible timestomping |
| Known tool names (mimikatz, psexec) | Attacker tooling |
Scripts 1
agent.py6.1 KB
#!/usr/bin/env python3
"""Windows Amcache.hve forensic analysis agent.
Parses Amcache.hve registry hive to extract program execution history,
file metadata, and device information using the regipy library.
"""
import argparse
import json
import sys
import datetime
try:
from regipy.registry import RegistryHive
HAS_REGIPY = True
except ImportError:
HAS_REGIPY = False
AMCACHE_FILE_KEY = "Root\InventoryApplicationFile"
AMCACHE_APP_KEY = "Root\InventoryApplication"
AMCACHE_DEVICE_KEY = "Root\InventoryDevicePnp"
AMCACHE_DRIVER_KEY = "Root\InventoryDriverBinary"
SUSPICIOUS_PATHS = [
"\\temp\\", "\\tmp\\", "\\appdata\\local\\temp",
"\\downloads\\", "\\public\\", "\\programdata\\",
"\\recycle", "\\users\\public",
]
SUSPICIOUS_NAMES = [
"mimikatz", "psexec", "lazagne", "procdump", "rubeus",
"sharphound", "bloodhound", "cobalt", "beacon",
"powershell_ise", "certutil", "mshta",
]
def parse_amcache_files(hive_path):
"""Parse InventoryApplicationFile entries from Amcache.hve."""
if not HAS_REGIPY:
return {"error": "regipy not installed. pip install regipy"}
try:
reg = RegistryHive(hive_path)
entries = []
for subkey in reg.get_key(AMCACHE_FILE_KEY).iter_subkeys():
values = {v.name: v.value for v in subkey.iter_values()}
entries.append({
"name": values.get("Name", ""),
"lower_case_path": values.get("LowerCaseLongPath", ""),
"publisher": values.get("Publisher", ""),
"version": values.get("Version", ""),
"sha1": values.get("FileId", "").lstrip("0000").lower() if values.get("FileId") else "",
"size": values.get("Size", 0),
"link_date": values.get("LinkDate", ""),
"program_id": values.get("ProgramId", ""),
"last_modified": subkey.header.last_modified.isoformat() if subkey.header.last_modified else "",
})
return entries
except Exception as e:
return {"error": str(e)}
def parse_amcache_apps(hive_path):
"""Parse InventoryApplication entries."""
if not HAS_REGIPY:
return {"error": "regipy not installed"}
try:
reg = RegistryHive(hive_path)
apps = []
for subkey in reg.get_key(AMCACHE_APP_KEY).iter_subkeys():
values = {v.name: v.value for v in subkey.iter_values()}
apps.append({
"name": values.get("Name", ""),
"version": values.get("Version", ""),
"publisher": values.get("Publisher", ""),
"install_date": values.get("InstallDate", ""),
"source": values.get("Source", ""),
"uninstall_string": values.get("UninstallString", ""),
"registry_key_path": values.get("RegistryKeyPath", ""),
})
return apps
except Exception as e:
return {"error": str(e)}
def detect_suspicious(entries):
"""Flag suspicious entries based on path and name patterns."""
findings = []
for entry in entries:
if isinstance(entry, dict) and "error" not in entry:
path = entry.get("lower_case_path", "").lower()
name = entry.get("name", "").lower()
reasons = []
for sp in SUSPICIOUS_PATHS:
if sp in path:
reasons.append(f"Suspicious path: {sp}")
for sn in SUSPICIOUS_NAMES:
if sn in name:
reasons.append(f"Suspicious name: {sn}")
if not entry.get("publisher"):
reasons.append("Missing publisher metadata")
if reasons:
findings.append({
"name": entry.get("name", ""),
"path": entry.get("lower_case_path", ""),
"sha1": entry.get("sha1", ""),
"reasons": reasons,
})
return findings
def main():
parser = argparse.ArgumentParser(description="Amcache.hve forensic analysis agent")
parser.add_argument("hive", nargs="?", help="Path to Amcache.hve file")
parser.add_argument("--apps", action="store_true", help="Parse InventoryApplication entries")
parser.add_argument("--suspicious-only", action="store_true", help="Show only suspicious entries")
parser.add_argument("--output", "-o", help="Output JSON report path")
args = parser.parse_args()
print("[*] Amcache.hve Forensic Analysis Agent")
print(f" regipy available: {HAS_REGIPY}")
if not args.hive:
print("\n[DEMO] Amcache.hve location: C:\\Windows\\AppCompat\\Programs\\Amcache.hve")
print(" Usage: python agent.py Amcache.hve [--apps] [--suspicious-only]")
print(" Extracts: file paths, SHA-1 hashes, publisher, timestamps, install info")
print(json.dumps({"demo": True, "regipy_available": HAS_REGIPY}, indent=2))
sys.exit(0)
report = {"timestamp": datetime.datetime.utcnow().isoformat() + "Z", "hive": args.hive}
files = parse_amcache_files(args.hive)
if isinstance(files, list):
report["file_entries"] = len(files)
suspicious = detect_suspicious(files)
report["suspicious_count"] = len(suspicious)
if args.suspicious_only:
report["findings"] = suspicious
else:
report["entries"] = files[:100]
report["suspicious"] = suspicious
print(f"[*] File entries: {len(files)}")
print(f"[*] Suspicious: {len(suspicious)}")
for s in suspicious[:10]:
print(f" [!] {s['name']}: {', '.join(s['reasons'])}")
else:
report["error"] = files
if args.apps:
apps = parse_amcache_apps(args.hive)
if isinstance(apps, list):
report["app_entries"] = len(apps)
print(f"[*] Application entries: {len(apps)}")
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(json.dumps({"file_entries": report.get("file_entries", 0),
"suspicious": report.get("suspicious_count", 0)}, indent=2))
if __name__ == "__main__":
main()