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,90 @@
---
name: decrypting-embedded-configuration
description: 'Decrypts statically embedded malware configuration blobs by trying common schemes
(single-byte and multi-byte XOR, RC4, base64 layers) and scoring decoded output for config-like
content. Activates for requests to decrypt an embedded config, recover hardcoded settings from a
blob, or brute-force a configuration encryption scheme.'
domain: cybersecurity
subdomain: reverse-engineering
tags:
- reverse-engineering
- config-extraction
- decryption
- xor
- rc4
version: 1.0.0
author: analyst-ai-pack
license: Apache-2.0
mitre_attack:
- T1140
- T1027
- T1071
d3fend:
- D3-SDA
- D3-DA
references:
- 'MITRE ATT&CK T1140 Deobfuscate/Decode Files or Information — https://attack.mitre.org/techniques/T1140/'
- 'RC4 algorithm (RFC-equivalent public description) — https://en.wikipedia.org/wiki/RC4'
---
# Decrypting Embedded Configuration
## When to Use
- You have an extracted config blob (from a resource, `.data` section, or overlay) that is XOR/RC4/
base64-obfuscated and want to recover plaintext settings.
- You need a quick brute-force over common schemes before writing a family-specific decryptor.
**Do not use** this on a live-decrypted-in-memory config — for that use the memory config skill.
This works statically on the extracted blob and executes nothing.
## Prerequisites
- The extracted ciphertext blob and (optionally) a candidate key.
## Safety & Handling
- Treat decoded endpoints as live C2; defang before sharing.
## Workflow
### Step 1: Try single-byte XOR
```bash
python scripts/analyst.py xor blob.bin
```
Brute-forces all 256 single-byte keys and scores each output for printable ratio and config tokens
(`http`, `.php`, IP patterns, `id=`).
### Step 2: Try RC4 / multi-byte XOR with a key
```bash
python scripts/analyst.py rc4 blob.bin --key mysecret
python scripts/analyst.py xorkey blob.bin --key 0x11,0x22,0x33
```
### Step 3: Peel base64 / repeat
If output is base64, decode and re-run the scheme search on the result.
### Step 4: Extract and defang
Pull URLs/IPs/keys from the best-scoring plaintext and defang.
## Validation
- The chosen scheme yields a high printable ratio and real config tokens.
- Recovered endpoints parse as valid hosts/URLs.
- Output is defanged before sharing.
## Pitfalls
- Single-byte XOR coincidentally producing some ASCII — require config tokens, not just printables.
- RC4 key drop-bytes variants (RC4-drop) needed by some families.
- Nested layers (base64 over XOR over RC4) requiring multiple passes.
## References
- See [`references/api-reference.md`](references/api-reference.md) for the decryptor.
- ATT&CK T1140 and the RC4 description (linked in frontmatter).

View File

@@ -0,0 +1,42 @@
# API Reference: Decrypting Embedded Configuration
## Overview
`scripts/analyst.py` brute-forces single-byte XOR, applies repeating-key XOR or RC4 with a supplied
key, and scores each candidate plaintext by printable ratio and config tokens, defanging recovered
endpoints. It reads the ciphertext blob statically and executes nothing.
## Dependencies
| Package | Version | Purpose |
|---------|---------|---------|
| (stdlib) | — | regex, JSON, file IO |
## Core functions
### `xor_brute(data)`
Tries all 256 single-byte keys; returns the top-scoring candidates with endpoints and a preview.
### `rc4(data, key)`
Standard RC4 keystream decryption.
### `xor_key(data, key)`
Repeating multi-byte XOR with a supplied key list.
## Scoring
Printable ratio (0–100) + 10 per config token + 5 per IP match. Higher = more config-like.
## Usage
```bash
python scripts/analyst.py xor blob.bin
python scripts/analyst.py rc4 blob.bin --key mysecret
python scripts/analyst.py xorkey blob.bin --key 0x11,0x22,0x33
```
## Sources
- MITRE ATT&CK T1140 Deobfuscate/Decode Information — https://attack.mitre.org/techniques/T1140/
- RC4 keystream algorithm (public description) — https://en.wikipedia.org/wiki/RC4
- XOR/base64/RC4 config patterns from public malware config-extractor write-ups

View File

@@ -0,0 +1,101 @@
#!/usr/bin/env python3
"""Brute-force common embedded-config encryption schemes and score config-like output.
Supports single-byte XOR brute force, multi-byte repeating-key XOR, and RC4. Scores each candidate
plaintext by printable ratio and presence of config tokens, and defangs recovered endpoints. Reads
the ciphertext blob statically; executes nothing.
"""
from __future__ import annotations
import argparse
import json
import re
import sys
from pathlib import Path
CONFIG_TOKENS = [b"http", b".php", b"id=", b"botnet", b"campaign", b".onion", b"User-Agent",
b"POST", b"Mozilla"]
RE_IP = re.compile(rb"\b(?:\d{1,3}\.){3}\d{1,3}\b")
RE_URL = re.compile(rb"https?://[\x21-\x7e]{4,}")
def _score(data: bytes) -> int:
printable = sum(1 for b in data if 0x20 <= b <= 0x7e or b in (9, 10, 13))
ratio = printable / max(len(data), 1)
score = int(ratio * 100)
score += 10 * sum(1 for t in CONFIG_TOKENS if t in data)
score += 5 * len(RE_IP.findall(data))
return score
def _defang(s: str) -> str:
return s.replace("http", "hxxp").replace(".", "[.]")
def _endpoints(data: bytes) -> list[str]:
out = {_defang(m.decode("ascii", "ignore")) for m in RE_URL.findall(data)}
out |= {_defang(m.decode("ascii", "ignore")) for m in RE_IP.findall(data)}
return sorted(out)
def rc4(data: bytes, key: bytes) -> bytes:
s = list(range(256))
j = 0
for i in range(256):
j = (j + s[i] + key[i % len(key)]) & 0xFF
s[i], s[j] = s[j], s[i]
out = bytearray()
i = j = 0
for b in data:
i = (i + 1) & 0xFF
j = (j + s[i]) & 0xFF
s[i], s[j] = s[j], s[i]
out.append(b ^ s[(s[i] + s[j]) & 0xFF])
return bytes(out)
def xor_brute(data: bytes) -> dict:
best = []
for key in range(256):
dec = bytes(b ^ key for b in data)
best.append((_score(dec), key, dec))
best.sort(reverse=True, key=lambda t: t[0])
top = best[:3]
return {"candidates": [
{"key": hex(k), "score": s, "endpoints": _endpoints(d),
"preview": d[:80].decode("ascii", "replace")} for s, k, d in top]}
def xor_key(data: bytes, key: bytes) -> dict:
dec = bytes(b ^ key[i % len(key)] for i, b in enumerate(data))
return {"score": _score(dec), "endpoints": _endpoints(dec),
"preview": dec[:120].decode("ascii", "replace")}
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="Decrypt embedded config blobs")
sub = parser.add_subparsers(dest="cmd", required=True)
px = sub.add_parser("xor")
px.add_argument("file")
pr = sub.add_parser("rc4")
pr.add_argument("file")
pr.add_argument("--key", required=True)
pk = sub.add_parser("xorkey")
pk.add_argument("file")
pk.add_argument("--key", required=True, help="comma list e.g. 0x11,0x22")
args = parser.parse_args(argv)
data = Path(args.file).read_bytes()
if args.cmd == "xor":
print(json.dumps(xor_brute(data), indent=2))
elif args.cmd == "rc4":
dec = rc4(data, args.key.encode())
print(json.dumps({"score": _score(dec), "endpoints": _endpoints(dec),
"preview": dec[:120].decode("ascii", "replace")}, indent=2))
else:
key = bytes(int(x, 0) for x in args.key.split(","))
print(json.dumps(xor_key(data, key), indent=2))
return 0
if __name__ == "__main__":
sys.exit(main())