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,89 @@
---
name: analyzing-rust-malware-internals
description: 'Analyzes Rust-compiled malware by detecting the Rust toolchain signature, demangling
Rust v0/legacy symbol names, and identifying crate dependencies from embedded paths. Activates
for requests to analyze Rust malware, demangle Rust symbols, or identify a Rust binary build and
its crates.'
domain: cybersecurity
subdomain: reverse-engineering
tags:
- reverse-engineering
- rust
- symbol-demangling
- crates
- stripped-binaries
version: 1.0.0
author: analyst-ai-pack
license: Apache-2.0
mitre_attack:
- T1027
- T1587.001
- T1059
d3fend:
- D3-SDA
- D3-DA
references:
- 'Rust symbol mangling (RFC 2603 v0 scheme) — https://rust-lang.github.io/rfcs/2603-rust-symbol-name-mangling-v0.html'
- 'MITRE ATT&CK T1027 Obfuscated Files or Information — https://attack.mitre.org/techniques/T1027/'
---
# Analyzing Rust Malware Internals
## When to Use
- You have a Rust-compiled binary and need to confirm the toolchain, demangle symbol names, and
enumerate crate dependencies.
- Standard analysis is hampered by Rust's name mangling and large static linking.
**Do not use** this for non-Rust binaries — confirm the Rust signature first. This skill reads the
binary statically and executes nothing.
## Prerequisites
- The Rust binary (read inertly).
## Safety & Handling
- Read bytes statically; treat strings as untrusted.
## Workflow
### Step 1: Confirm Rust and toolchain
```bash
python scripts/analyst.py info sample.bin
```
Looks for `rustc`/`cargo` markers, the `rust` panic/unwind strings, and embedded source paths
(`/rustc/<hash>/library/...`, `~/.cargo/registry/...`).
### Step 2: Demangle symbol names
Detects v0 (`_R...`) and legacy (`_ZN...17h<hash>E`) mangled symbols and demangles them to readable
paths.
### Step 3: Enumerate crates
Extract crate names/versions from `.cargo/registry/src/.../<crate>-<ver>/` paths to fingerprint
capabilities (e.g., `reqwest`, `tokio`, `aes`, `winapi`).
### Step 4: Map and document
Map notable crates to behavior and ATT&CK.
## Validation
- The Rust toolchain signature is confirmed before demangling.
- Demangled names are readable module paths (not still-mangled).
- Crate names/versions are plausible registry entries.
## Pitfalls
- Mixing v0 and legacy mangling in one binary — handle both.
- Stripped binaries where only registry path strings remain.
- Static crates inflating the symbol set; focus on the author's crate/`main`.
## References
- See [`references/api-reference.md`](references/api-reference.md) for the analyzer/demangler.
- Rust v0 mangling RFC and ATT&CK T1027 (linked in frontmatter).

View File

@@ -0,0 +1,39 @@
# API Reference: Analyzing Rust Malware Internals
## Overview
`scripts/analyst.py` confirms a Rust build (rustc/cargo markers, `/rustc/<hash>/library/` paths,
panic strings), heuristically demangles legacy `_ZN...E` symbols, detects v0 `_R` symbols, and
extracts crate name/version pairs from `.cargo/registry` paths, mapping notable crates to
capabilities. It reads bytes statically and executes nothing.
## Dependencies
| Package | Version | Purpose |
|---------|---------|---------|
| (stdlib) | — | regex, JSON, file IO |
## Core functions
### `info(path)`
Returns Rust detection, legacy-demangled names, v0 symbols present, crates, and capabilities.
### `_demangle_legacy(sym)`
Decodes the length-prefixed segments of a legacy `_ZN...17h<hash>E` symbol into `a::b::c`.
## Notes
- v0 (`_R`) symbols are detected; full v0 demangling is delegated to a dedicated tool
(e.g., `rustfilt`).
## Usage
```bash
python scripts/analyst.py info sample.bin
```
## Sources
- Rust symbol mangling v0 (RFC 2603) — https://rust-lang.github.io/rfcs/2603-rust-symbol-name-mangling-v0.html
- Legacy `_ZN`/Itanium-style length-prefixed mangling (public Rust ABI docs)
- Cargo registry path layout (`registry/src/<index>/<crate>-<ver>`) from Cargo documentation

View File

@@ -0,0 +1,80 @@
#!/usr/bin/env python3
"""Analyze a Rust-compiled binary: confirm Rust, demangle symbols, enumerate crates.
Detects Rust toolchain markers, demangles legacy (_ZN...E) Rust symbols heuristically, and extracts
crate names/versions from embedded .cargo registry paths. Reads bytes statically; executes nothing.
v0 (_R) demangling is reported as detected but full v0 decoding is delegated to a dedicated tool.
"""
from __future__ import annotations
import argparse
import json
import re
import sys
from pathlib import Path
ASCII_RE = re.compile(rb"[\x20-\x7e]{3,}")
RE_LEGACY = re.compile(r"_ZN([0-9A-Za-z$._]+)17h[0-9a-f]{16}E")
RE_V0 = re.compile(r"_R[0-9A-Za-z_]{4,}")
RE_CRATE = re.compile(r"registry/src/[^/]+/([A-Za-z0-9_-]+)-(\d+\.\d+\.\d+)")
RE_RUSTC_PATH = re.compile(r"/rustc/[0-9a-f]{6,}/library/")
CAP_CRATES = {
"reqwest": "HTTP client", "hyper": "HTTP", "tokio": "async runtime",
"aes": "AES crypto", "rsa": "RSA crypto", "winapi": "Windows API",
"windows": "Windows API", "sysinfo": "host enumeration", "tonic": "gRPC",
}
def _demangle_legacy(sym: str) -> str:
# _ZN<len>name<len>name...17h<hash>E -> name::name::...
body = sym[len("_ZN"):]
parts = []
i = 0
while i < len(body):
j = i
while j < len(body) and body[j].isdigit():
j += 1
if j == i:
break
length = int(body[i:j])
seg = body[j:j + length]
if seg.startswith("17h"):
break
parts.append(seg)
i = j + length
return "::".join(parts) if parts else sym
def info(path: str) -> dict:
data = Path(path).read_bytes()
strings = [m.decode("latin-1", "ignore") for m in ASCII_RE.findall(data)]
blob = "\n".join(strings)
is_rust = bool(RE_RUSTC_PATH.search(blob)) or "cargo/registry" in blob or "rustc" in blob \
or "called `Result::unwrap()`" in blob
legacy = sorted({_demangle_legacy("_ZN" + m) for m in RE_LEGACY.findall(blob)})[:200]
v0_present = sorted(set(RE_V0.findall(blob)))[:50]
crates = sorted({f"{n}-{v}" for n, v in RE_CRATE.findall(blob)})[:100]
caps = sorted({desc for c, desc in CAP_CRATES.items()
if any(cr.startswith(c + "-") for cr in crates)})
return {
"is_rust_binary": is_rust,
"legacy_demangled": legacy,
"v0_symbols_present": v0_present,
"crates": crates,
"capabilities": caps,
}
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="Analyze a Rust binary")
sub = parser.add_subparsers(dest="cmd", required=True)
p = sub.add_parser("info")
p.add_argument("file")
args = parser.parse_args(argv)
print(json.dumps(info(args.file), indent=2))
return 0
if __name__ == "__main__":
sys.exit(main())