vk-candpython/elfldr

GitHub: vk-candpython/elfldr

一款面向 Linux 的 ELF 内存级混淆与文件less执行保护工具,通过编译时加密与运行时自解密对抗静态分析与调试。

Stars: 1 | Forks: 0

# 👾 elfobf
[![平台](https://img.shields.io/badge/platform-Linux-blue?logo=linux&logoColor=white)](https://www.linux.org/) [![语言](https://img.shields.io/badge/language-Python%203-3776AB?logo=python)](https://www.python.org/) [![许可证](https://img.shields.io/badge/license-MIT-green)](LICENSE) *高级 ELF 二进制保护 — 压缩、加密、多态、无文件执行*
## 📖 目录 | Оглавление - [English](#english) - [📋 概述](#-overview) - [✨ 功能](#-features) - [🔒 完整保护流水线](#-complete-protection-pipeline) - [🚀 快速开始](#-quick-start) - [⚙️ 深入技术分析](#️-deep-technical-analysis) - [📁 输出](#-output) - [⚠️ 环境要求](#️-requirements) - [🔧 故障排除](#-troubleshooting) - [Русский](#русский) - [📋 Обзор](#-обзор) - [✨ Возможности](#-возможности) - [🔒 Полный конвейер защиты](#-полный-конвейер-защиты) - [🚀 Быстрый старт](#-быстрый-старт) - [⚙️ Глубокий технический анализ](#️-глубокий-технический-анализ) - [📁 Результат](#-результат) - [⚠️ Требования](#️-требования) - [🔧 Устранение неполадок](#-устранение-неполадок) # 英文 ## 📋 概述 **ELF-OBF** 是一款军用级别的 ELF 二进制混淆工具,它将标准的 Linux 可执行文件转换为经过严密防护、具有自解密和无文件执行能力的二进制文件。 ### 它的独特之处是什么? | 组件 | 实现方式 | |-----------|----------------| | **单一 SYSCALL 宏** | 一个统一的宏用于处理所有的系统调用 — 减小代码体积,集中进行混淆 | | **混淆的系统调用号** | 编译时使用随机密钥进行 XOR 处理 — 二进制文件中不含明文系统调用号 | | **位移的系统调用号** | `memfd_create` 和 `execveat` 被进行了随机位数的位移 | | **RLE 压缩** | 自定义字节级游程编码 — 通常能减小 30-60% 的体积 | | **XOR 流密码** | 16-128 字节密钥 + 盐值 + 反馈机制 — 每个字节都依赖于之前所有的字节 | | **多态 C 桩代码 (C Stub)** | 每次构建都是 100% 唯一的 — 从包含 129 个字符的字母表中随机选取标识符 | | **死代码注入** | 150+ 种组合 ASM 模式 + 随机的 C 垃圾语句 | | **集成 SSTRIP** | 内嵌预编译的 SSTRIP 二进制文件 — 完全移除 section headers | | **多态签名 (Polyglot)** | 注入了 27 种不同的文件格式头 | | **无文件执行** | 使用带有 `AT_EMPTY_PATH` 的 `memfd_create` + `execveat` — 零磁盘痕迹 | | **反调试** | TracerPid 检查 + PR_SET_PTRACER + PR_SET_DUMPABLE | | **内存保护** | mlockall(MCL_ALL) + F_SEAL_ALL — 防止交换和内存修改 | | **高度优化的构建器** | Memoryviews、预编译 SSTRIP、单次压缩、GC 控制 | ## ✨ 功能 ### 核心保护 | 功能 | 描述 | |---------|-------------| | 🗜️ **RLE 压缩** | 带有 0x80 重复标志的字节级 RLE,通常能减小 30-60% 的体积 | | 🔐 **XOR 流密码** | 盐值 + 带有反馈的密钥变异 — 非线性加密 | | 🎲 **多态桩代码** | 从 129 字符的字母表(拉丁字母 + 西里尔字母 + 乌克兰语)中随机生成函数/变量名 | | 📝 **死 ASM 注入** | 25+ 种模式:`nop`, `pause`, `clc`, `xor`, `lea`, `push/pop` + 寄存器组合 | | 🔧 **死 C 代码注入** | 在 SYSCALL 宏、ANTIDEBUG 和加载器主体中注入随机垃圾语句 | ### 编译与链接 | 功能 | 描述 | |---------|-------------| | 🏗️ **自动检测 MUSL/GCC** | 优先使用 MUSL 以获得更小的输出,失败时回退到 GCC | | 📦 **自定义链接脚本** | 随机基址 (0x400000 + random*0x1000),丢弃所有未使用的 sections | | 🚫 **编译器标志** | `-Os -static-pie -fomit-frame-pointer -fno-stack-protector -Wl,--strip-all` | | 🧹 **SSTRIP** | 完全移除 section headers — 破坏 `objdump`、`readelf`、`gdb` 的解析 | ### 运行时保护 | 功能 | 描述 | |---------|-------------| | 💾 **无文件执行** | `memfd_create` → 写入 → 密封 → 带有 `AT_EMPTY_PATH` 的 `execveat` | | 🛡️ **反调试** | 解析 `/proc/self/status` 查找 `TracerPid`(在二进制文件中已混淆该字符串) | | 🔒 **阻断 PTRACE** | `prctl(PR_SET_PTRACER, 0)` — 仅允许子进程进行 ptrace | | 🚫 **禁用新特权** | `prctl(PR_SET_NO_NEW_PRIVS, 1)` — 防止 setuid 提权 | | 📵 **禁止 Core Dump** | `prctl(PR_SET_DUMPABLE, 0)` — 阻止 gcore 和 core dumps | | 🔐 **内存锁定** | `mlockall(MCL_ALL)` — 防止内存被交换到磁盘 | | 🔏 **密封的内存 FD** | `fcntl(F_ADD_SEALS, F_SEALS_ALL)` — 防止在执行前被修改 | ### 多态签名 (27 种格式) | 签名 | 格式 | |-----------|--------| | `\x7FELF` | ELF (原生) | | `MZ` + `PE` | Windows PE | | `\x89PNG` | PNG 图像 | | `%PDF` | PDF 文档 | | `PK\x03\x04` | ZIP 归档 | | `\x1F\x8B` | GZIP | | `\xFD\x37\x7A\x58\x5A` | XZ/LZMA | | `\x21\x3C\x61\x72\x63\x68\x3E` | AR 归档 | | `\xCA\xFE\xBA\xBE` | Mach-O (32位) | | `\xCF\xFA\xED\xFE` | Mach-O (64位) | | `#!/bin/bash` | Shell 脚本 | | `UPX!` | UPX 壳 | | `\xFF\xD8\xFF\xE0` | JPEG | | `BM` | BMP | | `ID3` | MP3 | | `ftypisom` | MP4 | | `SQLite format 3` | SQLite | | `\xD0\xCF\x11\xE0` | MS Office | | `\x00\x61\x73\x6D` | WebAssembly | | `\xFE\xED\xFA\xCE` | Mach-O (32位, 备选) | | `\xBE\xBA\xFE\xCA` | Java Class | | `\x99\x01` | DOS COM | | `\x00\x01\x00\x00` | TrueType 字体 | | `> 1))) & 0xFF ├── Operations: XOR → rotate left 3 → add (y ^ 0xA5) └── /proc/self/status string also encrypted PHASE 4: POLYMORPHIC LOADER GENERATION ├── Random identifiers: 4-254 chars, 129-char alphabet ├── Obfuscated constants: XORed and shifted syscall numbers ├── Random dead code: 150+ ASM patterns, 11 junk per SYSCALL macro └── Unique linker script: random base address + random polyglot signature PHASE 5: C COMPILATION ├── Compiler: MUSL (preferred) or GCC ├── 20+ aggressive compiler flags for size and stealth └── Custom linker script with discarded sections PHASE 6: SSTRIP ├── Embedded pre-compiled SSTRIP binary (~13KB) ├── Truncates section header table └── Result: "ghost" ELF — runs but has no visible sections ``` ## 🚀 快速开始 ### 📥 下载 ``` git clone https://github.com/vk-candpython/elfobf.git cd elfobf ``` ### 📦 环境要求 ``` # 安装 MUSL(推荐用于生成更小的输出) sudo apt install musl-tools # Debian/Ubuntu sudo pacman -S musl # Arch # 或者使用 GCC(自动检测) sudo apt install gcc ``` ### 🏃 用法 ``` python3 elfobf.py [elf2 ...] ``` **示例:** ``` python3 elfobf.py /bin/ls ``` **输出:** ``` python elfobf.py /usr/sbin/msrtool [ OK ]: architecture is valid (x86_64) [ OK ]: using compiler(/usr/bin/gcc) [ OK ]: make build dir(./_mkelfobf) [ INFO ]: Start processing -> /usr/sbin/msrtool [ INFO ]: obfuscating: ELF(/usr/sbin/msrtool) [ INFO ]: compressing: {--------------------} 100% (DONE) [ OK ]: compressed: (53013584 -> 1114638) bytes | saved: 51898946 bytes (97.9%) [ INFO ]: encrypting: {--------------------} 100% (DONE) [ BUILD ]: file(./_mkelfobf/link.ld) [ BUILD ]: file(./_mkelfobf/payload.bin) [ BUILD ]: file(./_mkelfobf/loader.c) [ BUILD ]: file(./_mkelfobf/sstrip.elf) [ OK ]: compiled ................. (DONE) [ OK ]: striped ................. (DONE) [ INFO ]: time ................. (3.70s) [ OK ]: outfile(./elfobf-msrtool, 1124384 bytes) [ OK ]: obfuscation complete ELF(/usr/sbin/msrtool) [ INFO ]: End processing -> /usr/sbin/msrtool [ OK ]: cleanup build dir(./_mkelfobf) ``` ## ⚙️ 深入技术分析 ### SYSCALL 宏 (通用于所有调用) 加载器中的每一个系统调用都由一个统一的宏来处理。每次宏展开都会注入 11 条随机的垃圾语句。系统调用是通过 `call` 指令跳转到一个 trampoline 函数来实现的,该函数在 `syscall` 指令前后都包含随机的死代码。根据 x86_64 ABI 的规定,它会破坏 `rcx` 和 `r11` 寄存器。 ### 系统调用 Trampoline 一个可见性为 `.hidden` 的专用静态函数包含了实际的 `syscall` 指令,并被随机的垃圾 ASM 代码所包围。这将所有的系统调用集中到了一个混淆过的入口。 ### RLE 解压 (运行时) 解压器逐个字节处理加密的 payload。每个字节首先通过 DEC 宏进行解密,然后被解释为重复序列(设置了 0x80 标志)或原义序列。输出以 4KB 的块为单位写入到密封的内存文件描述符中。 ### DEC 宏 (解密单个字节) 加密函数的逆操作:减去 `(y ^ 0xA5)`,循环右移 3 位,与派生密钥和状态进行 XOR。状态 `g` 通过非线性反馈函数更新:`g = (b ^ ((y << 1) ^ (i >> 1))) & 0xFF`。 ### ANTIDEBUG 宏 字符串 `/proc/self/status` 在二进制文件中是加密的。该宏在运行时将其解密,打开文件,并搜索被混淆过的 `TracerPid:` 模式(每个字符都使用不同的密钥进行了 XOR)。返回 TracerPid 的值:0 = 安全,>0 = 检测到 debugger。所有的缓冲区在返回前都会被安全地清零。 ### 无文件执行 Payload 被解密和解压后,直接写入通过 `memfd_create` 创建的内存文件描述符中。然后使用 `F_SEAL_ALL` 将该 FD 密封,以防止在通过带有 `AT_EMPTY_PATH` 的 `execveat` 执行之前进行任何修改。 ### ZEROS 宏 (安全擦除内存) 使用反向(DF=1)的 `rep stosq` 指令将敏感缓冲区清零。反向操作使得内存取证恢复变得更加困难。 ### 死代码注入模式 25+ 种基础 ASM 模式与 10 个寄存器组合,在构建时生成了 150+ 种独特的死代码组合。此外,C 代码中每行有意义的代码之间都散布着随机语句。 ### 构建器优化 | 优化项 | 实现方式 | |--------------|----------------| | **Memoryviews** | 零拷贝切片,无中间内存分配 | | **预分配缓冲区** | 精确计算 RLE 输出所需的大小 | | **MADV_SEQUENTIAL** | 向内核提示采用顺序访问方式 | | **分块 I/O** | 大文件使用 4KB 的块进行处理 | | **预编译的 SSTRIP** | 作为字节嵌入,每次运行只写入一次 | | **单次压缩** | RLE 在单次遍历中完成压缩 | | **原地加密** | XOR 直接修改缓冲区 | | **GC 控制** | `gc.disable()` + 手动 `gc.collect()` | | **颜色输出缓存** | 缓存 ANSI 颜色代码 | ## 📁 输出 ``` original_elf → elfobf-original_elf ``` **输出二进制文件属性:** - 被剥离了所有的符号和 section headers - 在类似 `.rodata` 的 section 中包含加密的 payload - 完全在内存中执行 - 不在磁盘上留下任何痕迹(二进制文件本身除外) - 通常比原始文件**小 30-60%** ## ⚠️ 环境要求 | 需求 | 版本 | 备注 | |-------------|---------|-------| | **Python** | 3.6+ | 构建器必需 | | **MUSL-GCC** | 任意 | 推荐(输出体积更小) | | **GCC** | 任意 | 备选 | | **Linux 内核** | 3.17+ | 用于 `memfd_create` | | **Linux 内核** | 3.19+ | 用于 `execveat` | | **系统架构** | x86_64 | 仅限 64 位 | ## 🔧 故障排除 | 问题 | 解决方案 | |-------|----------| | `Cannot determine architecture` | 仅支持 x86_64 | | `No suitable compiler found` | 安装 `musl-tools` 或 `gcc` | | `compilation failed` | 检查编译器;如果 MUSL 失败,请尝试 | | `execveat: Function not implemented` | 内核版本 < 3.19 | | `memfd_create: Function not implemented` | 内核版本 < 3.17 | | 混淆后的二进制文件发生段错误 | 原程序可能需要动态链接库 | | `gdb` 仍然能够附加 | 使用 `PR_SET_PTRACER` + TracerPid | | 二进制文件体积变大 | 对于非常小的二进制文件来说这是正常的 | # 俄文 ## 📋 概述 **ELF-OBF** — инструмент обфускации ELF-бинарников военного уровня, который превращает стандартные исполняемые файлы Linux в сильно бронированные, саморасшифровывающиеся бинарники с бесфайловым выполнением. ### 它有什么独特之处? | Компонент | Реализация | |-----------|------------| | **Единый макрос SYSCALL** | Один для ВСЕХ системных вызовов — уменьшает размер кода, централизует обфускацию | | **Обфусцированные номера syscall** | XOR со случайным ключом — в бинарнике нет открытых номеров | | **Сдвинутые номера syscall** | `memfd_create` и `execveat` сдвинуты на случайные биты | | **RLE-сжатие** | Кастомное побайтовое кодирование — типичное сжатие 30-60% | | **Потоковый XOR-шифр** | Ключ 16-128 байт + соль + обратная связь — каждый байт зависит от предыдущих | | **Полиморфный C-стаб** | 100% уникален для каждой сборки — имена из 129-символьного алфавита | | **Впрыск мёртвого кода** | 150+ комбинаторных ASM-паттернов + случайный мусор в C | | **Интеграция SSTRIP** | Встроенный предскомпилированный SSTRIP — полное удаление заголовков секций | | **Полиглот-сигнатуры** | 27 различных заголовков форматов файлов | | **Бесфайловое выполнение** | `memfd_create` + `execveat` с `AT_EMPTY_PATH` — нулевой след на диске | | **Анти-отладка** | Проверка TracerPid + PR_SET_PTRACER + PR_SET_DUMPABLE | | **Защита памяти** | mlockall(MCL_ALL) + F_SEAL_ALL | | **Оптимизированный билдер** | Memoryviews, предскомпилированный SSTRIP, однопроходное сжатие, контроль GC | ## ✨ 功能特性 ### 基础保护 | Возможность | Описание | |-------------|----------| | 🗜️ **RLE-сжатие** | Побайтовое RLE с флагом 0x80, типичное сжатие 30-60% | | 🔐 **Потоковый XOR-шифр** | Соль + мутация ключа с обратной связью — нелинейное шифрование | | 🎲 **Полиморфная заглушка** | Случайные имена из 129-символьного алфавита (латиница + кириллица + украинский) | | 📝 **Впрыск мёртвого ASM** | 25+ паттернов + комбинации с 10 регистрами = 150+ вариантов | | 🔧 **Впрыск мёртвого C** | Случайный мусор в макросе SYSCALL, ANTIDEBUG и теле загрузчика | ### 编译和链接 | Возможность | Описание | |-------------|----------| | 🏗️ **Автовыбор MUSL/GCC** | Предпочитает MUSL для меньшего размера | | 📦 **Кастомный линкер-скрипт** | Случайный базовый адрес, сбрасывает все неиспользуемые секции | | 🚫 **Флаги компилятора** | `-Os -static-pie -fomit-frame-pointer -fno-stack-protector -Wl,--strip-all` | | 🧹 **SSTRIP** | Полное удаление заголовков секций — ломает `objdump`, `readelf`, `gdb` | ### 运行时保护 | Возможность | Описание | |-------------|----------| | 💾 **Бесфайловое выполнение** | `memfd_create` → запись → seal → `execveat` с `AT_EMPTY_PATH` | | 🛡️ **Анти-отладка** | Парсинг `/proc/self/status` для `TracerPid` (строка зашифрована в бинарнике) | | 🔒 **Блокировка PTRACE** | `prctl(PR_SET_PTRACER, 0)` — только потомки могут трассировать | | 🚫 **Запрет новых привилегий** | `prctl(PR_SET_NO_NEW_PRIVS, 1)` | | 📵 **Запрет core-дампов** | `prctl(PR_SET_DUMPABLE, 0)` | | 🔐 **Блокировка памяти** | `mlockall(MCL_ALL)` | | 🔏 **Запечатанный memory FD** | `fcntl(F_ADD_SEALS, F_SEALS_ALL)` | ## 🔒 完整的保护 pipeline *(См. английскую версию для подробной диаграммы)* ## 🚀 快速开始 ``` git clone https://github.com/vk-candpython/elfobf.git cd elfobf python3 elfobf.py /bin/ls ./elfobf-ls ``` ## ⚙️ 深入的技术分析 ### SYSCALL macro(用一个实现全部) Единый унифицированный макрос обрабатывает каждый системный вызов в загрузчике. Каждое раскрытие впрыскивает 11 случайных мусорных инструкций. Системный вызов делается через `call` к функции-трамплину, которая содержит случайный мёртвый код до и после инструкции `syscall`. ### RLE 解压(在运行时) Распаковщик обрабатывает зашифрованные данные побайтово. Каждый байт сначала расшифровывается через макрос DEC, затем интерпретируется как повторяющаяся серия (флаг 0x80) или литеральная серия. Вывод пишется чанками по 4 КБ в запечатанный файловый дескриптор в памяти. ### DEC macro(解密单个字节) Обратная функция шифрования: вычитание `(y ^ 0xA5)`, поворот вправо на 3, XOR с производным ключом и состоянием. Состояние `g` обновляется нелинейной функцией с обратной связью: `g = (b ^ ((y << 1) ^ (i >> 1))) & 0xFF`. ### ANTIDEBUG macro Строка `/proc/self/status` зашифрована в бинарнике. Макрос расшифровывает её во время выполнения, открывает файл и ищет обфусцированный паттерн `TracerPid:` (каждый символ XOR с разными ключами). Возвращает значение TracerPid: 0 = чисто, >0 = обнаружен отладчик. Все буферы безопасно затираются перед возвратом. ### 无文件执行 Полезная нагрузка расшифровывается и распаковывается напрямую в файловый дескриптор в памяти, созданный через `memfd_create`. Затем fd запечатывается с `F_SEAL_ALL` для предотвращения любых модификаций перед выполнением через `execveat` с `AT_EMPTY_PATH`. ### ZEROS macro(安全的内存擦除) Использует `rep stosq` в обратном направлении (DF=1) для затирания чувствительных буферов. Обратное направление усложняет восстановление memory forensics. ### Builder 优化 | Оптимизация | Реализация | |-------------|------------| | **Memoryviews** | Zero-copy слайсинг | | **Предвыделенные буферы** | Точный расчёт размера для RLE | | **MADV_SEQUENTIAL** | Подсказка ядру о последовательном доступе | | **Чанковый I/O** | Блоки по 4 КБ для больших файлов | | **Предскомпилированный SSTRIP** | Встроен как байты, записывается один раз | | **Однопроходное сжатие** | RLE сжимает за один проход | | **Шифрование на месте** | XOR модифицирует буфер напрямую | | **Контроль GC** | `gc.disable()` + ручной `gc.collect()` | | **Кеширование цветов** | Мемоизация ANSI-кодов | ## 📁 结果 ``` оригинальный_elf → elfobf-оригинальный_elf ``` ## ⚠️ 系统要求 | Требование | Версия | Примечания | |------------|--------|------------| | **Python** | 3.6+ | Для билдера | | **MUSL-GCC** | Любая | Рекомендуется | | **GCC** | Любая | Запасной | | **Ядро Linux** | 3.17+ | Для `memfd_create` | | **Ядро Linux** | 3.19+ | Для `execveat` | | **Архитектура** | x86_64 | Только 64-бит | ## 🔧 故障排除 | Проблема | Решение | |----------|---------| | `Cannot determine architecture` | Только x86_64 | | `No suitable compiler found` | Установи `musl-tools` или `gcc` | | `compilation failed` | Проверь компилятор | | `execveat: Function not implemented` | Ядро < 3.19 | | `memfd_create: Function not implemented` | Ядро < 3.17 | | Обфусцированный бинарник падает | Оригинал может требовать динамические библиотеки |
**[⬆ 返回顶部](#-elfobf)** *Linux 的 ELF 混淆*
标签:DNS 反向解析, ELF, Linux, 二进制混淆, 免杀, 内存加载, 系统编程, 红队工具