mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-13 19:05:17 +03:00
feat: add 5 new cybersecurity skills - yara hunting, devsecops scanning, amcache, LOtL, privileged session monitoring
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Mahipal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: analyzing-windows-amcache-artifacts
|
||||
description: >
|
||||
Parse and analyze Windows Amcache.hve registry hive to extract program
|
||||
execution evidence, file metadata, SHA-1 hashes, and device connection
|
||||
history for digital forensics and incident response investigations.
|
||||
domain: cybersecurity
|
||||
subdomain: digital-forensics
|
||||
tags: [amcache, windows-forensics, registry-analysis, execution-artifacts]
|
||||
version: "1.0"
|
||||
author: mahipal
|
||||
license: Apache-2.0
|
||||
---
|
||||
|
||||
# Analyzing Windows Amcache Artifacts
|
||||
|
||||
Extract execution evidence from Amcache.hve including application paths,
|
||||
SHA-1 hashes, timestamps, and publisher metadata for DFIR investigations.
|
||||
@@ -0,0 +1,67 @@
|
||||
# API Reference: Analyzing Windows Amcache Artifacts
|
||||
|
||||
## Amcache.hve Location
|
||||
```
|
||||
C:\Windows\AppCompat\Programs\Amcache.hve
|
||||
```
|
||||
|
||||
## Registry 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
|
||||
```bash
|
||||
pip install regipy
|
||||
```
|
||||
|
||||
```python
|
||||
from 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)
|
||||
```bash
|
||||
# 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\ -i
|
||||
```
|
||||
|
||||
### Output 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 |
|
||||
@@ -0,0 +1,166 @@
|
||||
#!/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 os
|
||||
import sys
|
||||
import datetime
|
||||
import struct
|
||||
|
||||
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()
|
||||
Reference in New Issue
Block a user