reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -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

View File

@@ -0,0 +1,113 @@
---
name: analyzing-ransomware-encryption-behavior
description: 'Analyzes how a ransomware sample encrypts files: identifying the crypto scheme
(symmetric/asymmetric/hybrid), key handling, file targeting and extension/marker changes,
shadow-copy deletion, and ransom-note artifacts. Activates for requests to analyze
ransomware encryption, assess decryptability, or study ransomware behavior.'
domain: cybersecurity
subdomain: malware-analysis
tags:
- malware
- ransomware
- cryptography
- encryption
- file-marker
- impact
version: 1.0.0
author: analyst-ai-pack
license: Apache-2.0
mitre_attack:
- T1486
- T1490
- T1083
- T1027
d3fend:
- D3-FA
- D3-DA
references:
- 'No More Ransom project — https://www.nomoreransom.org/'
- 'NIST cryptographic standards (AES/RSA) — https://csrc.nist.gov/'
---
# Analyzing Ransomware Encryption Behavior
## When to Use
- You need to understand how a ransomware sample encrypts data and whether recovery without
the key is feasible.
- You are documenting file targeting, markers, and the ransom workflow for an IR report.
- You want to identify the crypto primitives to assess decryptability and detection points.
**Do not use** this to attempt key recovery on production data without backups; analyze in the
lab on disposable test files only.
## Prerequisites
- Isolated lab with disposable test files of varied types/sizes.
- Static/RE tools (see the Ghidra and crypto-identification skills) and the dynamic-analysis
setup.
- A clean snapshot to revert.
## Safety & Handling
- Detonate only against **throwaway** files in the isolated victim VM; never real data.
- Treat the sample and any dropped components as live; revert after each run.
## Workflow
### Step 1: Identify the crypto scheme statically
Locate crypto constants and APIs to classify the scheme:
```text
Symmetric only (AES/ChaCha/RC4) -> key may be derivable/recoverable if mishandled
Asymmetric (RSA/ECC) wrapping -> per-file symmetric key wrapped with attacker pubkey
Hybrid (typical) -> AES per file, RSA-wrapped key in the encrypted file/footer
```
Look for AES S-boxes, ChaCha constants ("expand 32-byte k"), and `CryptImportKey`/`BCrypt*`.
### Step 2: Trace key generation and handling
Determine where the symmetric key comes from (CSPRNG vs weak source), whether it is stored,
and how it is protected. Weak/reused keys or keys left in memory are recovery opportunities.
### Step 3: Map file targeting
Identify which directories/extensions are targeted or skipped (allowlist of system paths),
size thresholds, and partial-vs-full encryption (many encrypt only the first N bytes/blocks
for speed).
### Step 4: Capture markers and metadata
Most families append an extension, write a per-file footer/magic marker, and store the
wrapped key or IV there. The script fingerprints before/after test files to extract markers.
```bash
python scripts/analyst.py compare plain/ encrypted/
```
### Step 5: Document recovery-relevant facts
Note shadow-copy/backup deletion (`vssadmin delete shadows`), the ransom note, and any
cryptographic mistakes that affect decryptability.
## Validation
- The identified scheme matches observed file changes (e.g. hybrid → high-entropy body + a
fixed-size footer).
- File markers/extensions are consistent across encrypted test files.
- Shadow-copy deletion and note-drop are confirmed dynamically.
## Pitfalls
- Assuming decryptability from the algorithm name; correct AES/RSA usage is not recoverable.
Recovery hinges on implementation flaws or leaked keys.
- Missing partial-encryption schemes, leading to wrong impact assessment.
- Running against real files instead of disposable test data.
## References
- See [`references/api-reference.md`](references/api-reference.md) for the file-marker
comparison tool.
- No More Ransom and NIST crypto standards (linked in frontmatter).

View File

@@ -0,0 +1,41 @@
# API Reference: Analyzing Ransomware Encryption Behavior
## Overview
`scripts/analyst.py` compares original test files against their encrypted counterparts to
extract the appended extension, measure entropy change, and recover a common trailing footer
(where families often store a wrapped key or IV). It runs on disposable test files only.
## Dependencies
| Package | Version | Purpose |
|---------|---------|---------|
| (stdlib) | — | Entropy, file IO |
## External tools
| Tool | Purpose |
|------|---------|
| Ghidra / radare2 | Identify crypto routines and key handling |
| Detect-It-Easy / capa | Crypto-constant detection |
## Core functions
### `compare(plain_dir, enc_dir)`
Returns added extensions, a common encrypted footer, per-file entropy, size deltas, and an
encryption-coverage estimate (full vs partial).
### `_common_suffix(blobs)`
Finds the longest shared trailing bytes across encrypted files (candidate footer/marker).
## Usage
```bash
python scripts/analyst.py compare ./plain ./encrypted
```
## Sources
- No More Ransom project — https://www.nomoreransom.org/
- NIST cryptographic standards (AES, RSA) — https://csrc.nist.gov/
- Hybrid-encryption ransomware design (per-file AES + RSA-wrapped key), widely documented

View File

@@ -0,0 +1,87 @@
#!/usr/bin/env python3
"""Compare plaintext vs ransomware-encrypted test files to extract markers and assess scheme.
Given a directory of original test files and a directory of their encrypted counterparts, it
reports added extensions, entropy change, and any common trailing footer/magic (often where a
wrapped key or IV is stored). Operates on inert test files only.
"""
from __future__ import annotations
import argparse
import json
import math
import sys
from collections import Counter
from pathlib import Path
def entropy(data: bytes) -> float:
if not data:
return 0.0
counts = Counter(data)
n = len(data)
return -sum((c / n) * math.log2(c / n) for c in counts.values())
def _common_suffix(blobs: list[bytes], max_len: int = 512) -> bytes:
if not blobs:
return b""
shortest = min(len(b) for b in blobs)
limit = min(shortest, max_len)
suffix = bytearray()
for i in range(1, limit + 1):
col = {b[-i] for b in blobs}
if len(col) == 1:
suffix.insert(0, col.pop())
else:
break
return bytes(suffix)
def compare(plain_dir: str, enc_dir: str) -> dict:
plain = {p.stem: p for p in Path(plain_dir).iterdir() if p.is_file()}
enc = [p for p in Path(enc_dir).iterdir() if p.is_file()]
added_ext = sorted({"".join(p.suffixes) for p in enc})
enc_blobs = [p.read_bytes() for p in enc]
footer = _common_suffix(enc_blobs)
per_file = []
for p in enc:
base = p.name
# strip a possible appended extension to match the plaintext stem
stem = p.stem
orig = plain.get(stem)
row = {
"encrypted": base,
"encrypted_entropy": round(entropy(p.read_bytes()), 3),
}
if orig:
row["original"] = orig.name
row["original_entropy"] = round(entropy(orig.read_bytes()), 3)
row["size_delta"] = p.stat().st_size - orig.stat().st_size
per_file.append(row)
likely_full = all(r.get("encrypted_entropy", 0) > 7.5 for r in per_file)
return {
"added_extensions": added_ext,
"common_footer_len": len(footer),
"common_footer_hex": footer.hex(),
"encryption_coverage": "full/high-entropy" if likely_full else "partial/mixed",
"files": per_file,
}
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="Compare plain vs encrypted test files")
sub = parser.add_subparsers(dest="cmd", required=True)
p = sub.add_parser("compare")
p.add_argument("plain_dir")
p.add_argument("enc_dir")
args = parser.parse_args(argv)
print(json.dumps(compare(args.plain_dir, args.enc_dir), indent=2))
return 0
if __name__ == "__main__":
sys.exit(main())