reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
Apache License 2.0 — see the repository root LICENSE file for the full text.
|
||||
|
||||
Copyright the AnalystAIPack contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
name: performing-dynamic-analysis-in-a-sandbox
|
||||
description: 'Runs a sample in an instrumented sandbox to observe behavior: process tree, file
|
||||
and registry changes, network activity, and persistence, then summarizes the behavioral
|
||||
report into capabilities and IOCs. Activates for requests to detonate a sample, do dynamic
|
||||
or behavioral analysis, or interpret sandbox output.'
|
||||
domain: cybersecurity
|
||||
subdomain: malware-analysis
|
||||
tags:
|
||||
- malware
|
||||
- dynamic-analysis
|
||||
- sandbox
|
||||
- behavioral
|
||||
- procmon
|
||||
- detonation
|
||||
version: 1.0.0
|
||||
author: analyst-ai-pack
|
||||
license: Apache-2.0
|
||||
mitre_attack:
|
||||
- T1055
|
||||
- T1071
|
||||
- T1547
|
||||
- T1497
|
||||
d3fend:
|
||||
- D3-DA
|
||||
- D3-PSA
|
||||
references:
|
||||
- 'CAPE Sandbox — https://github.com/kevoreilly/CAPEv2'
|
||||
- 'Sysinternals Process Monitor — https://learn.microsoft.com/sysinternals/downloads/procmon'
|
||||
---
|
||||
|
||||
# Performing Dynamic Analysis in a Sandbox
|
||||
|
||||
## When to Use
|
||||
|
||||
- Static analysis is blocked by packing/obfuscation and you need to observe runtime behavior.
|
||||
- You want a behavioral picture: spawned processes, dropped files, registry edits, and C2.
|
||||
- You are confirming capabilities hypothesized from static analysis.
|
||||
|
||||
**Do not use** dynamic analysis as the only method — evasive samples may sleep, detect the
|
||||
sandbox, or require arguments. Pair it with static/RE work.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- An isolated lab with a victim VM and simulated internet (see the lab-setup skill).
|
||||
- A sandbox stack (CAPE/Cuckoo) or manual instrumentation: Process Monitor, Process Explorer,
|
||||
Regshot, and a packet capture on the services guest.
|
||||
- A clean base snapshot to revert to.
|
||||
|
||||
## Safety & Handling
|
||||
|
||||
- Detonate only inside the isolated victim VM; revert the snapshot after each run.
|
||||
- Route all network through the simulated-internet guest; never allow live egress.
|
||||
- Defang any captured URLs/IPs before they leave the lab.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Prepare instrumentation
|
||||
|
||||
Start Process Monitor (filtered to the target), Regshot baseline, and packet capture on the
|
||||
services guest. Snapshot the victim as clean.
|
||||
|
||||
### Step 2: Detonate with the right context
|
||||
|
||||
Many samples need a parent (Office, rundll32), an export (`rundll32 dll,Export`), or arguments.
|
||||
Match the original delivery context or the sample stalls.
|
||||
|
||||
### Step 3: Observe for the full behavior window
|
||||
|
||||
Watch process creation, file drops, registry Run keys/services, scheduled tasks, and network
|
||||
beacons. Give it several minutes; some samples sleep first.
|
||||
|
||||
### Step 4: Summarize the report
|
||||
|
||||
Feed the sandbox JSON (or your collected logs) to the summarizer to group events into
|
||||
capabilities and IOCs:
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py summarize report.json
|
||||
```
|
||||
|
||||
### Step 5: Diff the system state
|
||||
|
||||
Compare Regshot/file baselines pre- and post-run to capture persistence and dropped artifacts.
|
||||
|
||||
## Validation
|
||||
|
||||
- The observed process tree and network match the static-analysis hypothesis.
|
||||
- Persistence mechanisms found dynamically are confirmed in registry/task artifacts.
|
||||
- Re-running from the clean snapshot reproduces the core behavior.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Detonating without the required parent/args, so the sample exits early ("sandbox evasion"
|
||||
that is really a context problem).
|
||||
- Too-short observation windows that miss sleeping or staged payloads.
|
||||
- Trusting a single sandbox verdict; tune and corroborate.
|
||||
- Allowing real network egress and contaminating live infrastructure.
|
||||
|
||||
## References
|
||||
|
||||
- See [`references/api-reference.md`](references/api-reference.md) for the report summarizer.
|
||||
- CAPE Sandbox and Process Monitor (linked in frontmatter).
|
||||
@@ -0,0 +1,39 @@
|
||||
# API Reference: Performing Dynamic Analysis in a Sandbox
|
||||
|
||||
## Overview
|
||||
|
||||
`scripts/analyst.py` summarizes a CAPE/Cuckoo-style behavioral JSON report into a process tree,
|
||||
triggered signatures, network IOCs, and dropped files. It parses an existing report and never
|
||||
detonates a sample.
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| (stdlib) | — | JSON parsing |
|
||||
|
||||
## External tools
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| CAPE / Cuckoo | Automated detonation and behavioral reporting |
|
||||
| Process Monitor / Process Explorer | Manual behavioral instrumentation |
|
||||
| Regshot | Pre/post system-state diffing for persistence |
|
||||
|
||||
## Core functions
|
||||
|
||||
### `summarize(report)`
|
||||
Extracts the process tree, signatures, network IOCs (hosts/domains/URLs), and dropped files
|
||||
from a behavioral report, tolerating partial schemas.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
python scripts/analyst.py summarize report.json
|
||||
```
|
||||
|
||||
## Sources
|
||||
|
||||
- CAPE Sandbox — https://github.com/kevoreilly/CAPEv2
|
||||
- Sysinternals Process Monitor — https://learn.microsoft.com/sysinternals/downloads/procmon
|
||||
- Cuckoo/CAPE report JSON structure (project documentation)
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Summarize a sandbox behavioral report (CAPE/Cuckoo-style JSON) into capabilities and IOCs.
|
||||
|
||||
Reads an already-produced JSON report — it does not detonate anything. Tolerant of partial
|
||||
schemas: it looks for common keys (processes, signatures, network, dropped) and degrades
|
||||
gracefully when fields are missing.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _get(d: dict, *path, default=None):
|
||||
cur = d
|
||||
for key in path:
|
||||
if isinstance(cur, dict) and key in cur:
|
||||
cur = cur[key]
|
||||
else:
|
||||
return default
|
||||
return cur
|
||||
|
||||
|
||||
def summarize(report: dict) -> dict:
|
||||
processes = _get(report, "behavior", "processes", default=[]) or \
|
||||
_get(report, "processes", default=[]) or []
|
||||
proc_tree = [{
|
||||
"pid": p.get("pid"),
|
||||
"name": p.get("process_name") or p.get("name"),
|
||||
"command": p.get("command_line") or p.get("commandline"),
|
||||
"ppid": p.get("ppid") or p.get("parent_id"),
|
||||
} for p in processes][:200]
|
||||
|
||||
signatures = _get(report, "signatures", default=[]) or []
|
||||
sigs = [{"name": s.get("name"), "description": s.get("description"),
|
||||
"severity": s.get("severity")} for s in signatures]
|
||||
|
||||
net = _get(report, "network", default={}) or {}
|
||||
hosts = net.get("hosts", []) or []
|
||||
domains = [d.get("domain") if isinstance(d, dict) else d
|
||||
for d in net.get("domains", []) or []]
|
||||
http = [h.get("uri") or h.get("url") for h in net.get("http", []) or []
|
||||
if isinstance(h, dict)]
|
||||
|
||||
dropped = _get(report, "dropped", default=[]) or []
|
||||
drops = [{"name": d.get("name"), "sha256": d.get("sha256"),
|
||||
"type": d.get("type")} for d in dropped][:200]
|
||||
|
||||
return {
|
||||
"process_count": len(processes),
|
||||
"process_tree": proc_tree,
|
||||
"signatures": sigs,
|
||||
"iocs": {
|
||||
"hosts": [h.get("ip") if isinstance(h, dict) else h for h in hosts],
|
||||
"domains": [d for d in domains if d],
|
||||
"urls": [u for u in http if u],
|
||||
},
|
||||
"dropped_files": drops,
|
||||
}
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Summarize a sandbox report")
|
||||
sub = parser.add_subparsers(dest="cmd", required=True)
|
||||
p = sub.add_parser("summarize")
|
||||
p.add_argument("report", help="path to sandbox JSON report")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
report = json.loads(Path(args.report).read_text(encoding="utf-8", errors="replace"))
|
||||
print(json.dumps(summarize(report), indent=2))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user