Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
elfpack — ELF二进制段对接工具包,用于无阶段载荷投递,支持现场载荷附加、签名绕过以及通过自定义ELF段操作实现静态/动态加载抵抗。 | Kitploit
工具/GitHubGitHub/dsnezhkov/elfpack
Payload生成漏洞利用恶意软件分析渗透测试二进制分析红队Payload 开发
GitHubdsnezhkov/elfpack

elfpack

ELF二进制段对接工具包,用于无阶段载荷投递,支持现场载荷附加、签名绕过以及通过自定义ELF段操作实现静态/动态加载抵抗。

查看仓库
5110134年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

ElfPack:用于无阶段有效负载投递的ELF二进制节段对接

亮点

  • 有效负载捆绑机制概述:编译、链接和加载。
  • 二进制兼容性及创建与投递机制松散耦合的有效负载。
  • 避免节段的自动内存加载。
  • 使用结构化节段类型。
  • 现场通过ELF节段将有效负载(重新)附加到加载器。自带有效负载。
  • 利用分离的预编译ELF节段进行签名规避。
  • 通过负载生成管道进行有效负载的“路过式”附加。
  • 创建胖有效负载二进制文件及避免使用二进制打包器的情形。
  • 打包复杂有效负载。
  • 有效负载混淆和密钥保护选项。
  • 静态和动态负载加载跟踪抵抗。Binwalk和eBPF。

嵌入有效负载

通过编译和链接进行十六进制二进制包含

  1. 直接放在默认数据节段或文本节段: 通常,编译器将其生成的对象放置在像.data这样的节段中。

payload.h:

const data[3432] = {
    0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
    ...
    0x00, 0xff, 0x23 
};

通过手动或使用bin2c或xxd -i payload.bin > payload.h等工具实现,然后包含头文件。

将有效负载以通用方式存储在.text和.data中也是一个坏主意,因为容易进行加载跟踪,并且容易对加载数据以供执行的行为语义进行内省。

  1. 放在独立的节段中。 你可以将有效负载数据放在额外的节段中,或者你需要某些特定变量出现在特殊节段中。这通过编译器相关的机制实现。在gcc中,通过__attribute__实现。这样稍好一些,但由于ELF的创建和加载方式,仍然很容易被追踪。
char stack[10000] __attribute__ ((section ("binstack"))) = { 
    0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
    ...
    0x00, 0xff, 0x23 };
int init_data __attribute__ ((section ("bindata"))) = 0;

main()
{
    /* 初始化栈指针 */
    init_sp (stack + sizeof (stack));

    /* 初始化已初始化的数据 */
    memcpy (&init_data, &data, &edata - &data);
}
  1. 链接器二进制包含

类似于汇编器依赖的.incbin指令可以创建一个节段并嵌入有效负载。 例如:gcc -c payload.s 或 ld -r -b payload.bin -o payload.o

.section .bindata

.global payload_start
.type payload_start, @object

.section .binddata
.balign 64

payload_start:
    .incbin "payload.bin"
    .balign 1
payload_end:
    .byte 0

随后在加载器中如下获取:

int main(void) {
    extern uint8_t payload_start;
    uint8_t *ptrPayload = &payload_start;
    ...
}

注: 我们可以在payload.bin中包含一个完全功能的ELF,这在创建包含多个工具包元素的“胖”二进制文件时非常重要。

注: 存在更符合人体工程学的工具来完成此任务,例如@graphitemaster的INCBIN [链接]

该主题的变体是内联汇编,如下所示:

/* 所有嵌入图像的原始图像数据 */
 #undef EMBED
 #define EMBED( _index, _path, _name )                                   \
         extern char embedded_image_ ## _index ## _data[];               \
         extern char embedded_image_ ## _index ## _len[];                \
         __asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t"       \
                   "\nembedded_image_" #_index "_data:\n\t"              \
                   ".incbin \"" _path "\"\n\t"                           \
                   "\nembedded_image_" #_index "_end:\n\t"               \
                   ".equ embedded_image_" #_index "_len, "               \
                         "( embedded_image_" #_index "_end - "           \
                         "  embedded_image_" #_index "_data )\n\t"       \
                   ".previous\n\t" );
 EMBED_ALL
 
 /* 所有嵌入图像的图像结构 */
 #undef EMBED
 #define EMBED( _index, _path, _name ) {                                 \
         .refcnt = REF_INIT ( ref_no_free ),                             \
         .name = _name,                                                  \
         .data = ( userptr_t ) ( embedded_image_ ## _index ## _data ),   \
         .len = ( size_t ) embedded_image_ ## _index ## _len,            \
 },
 static struct image embedded_images[] = {
         EMBED_ALL
 };
 

注: 注意在节段定义中的PROGBITS,它很重要。

基于编译器/链接器的有效负载二进制包含并不理想

存在权衡:

  • 嵌入过程与有效负载加载器的创建紧密耦合。
  • 有效负载格式变更怎么办?
  • 默认情况下,携带数据的节段设置了PROGBITS标志,OS加载器默认会将其PT_LOAD到内存中。我们可能不希望这样。

ELF节段的磁盘/内存表示

ELF PROGBITS 示意图

包含新数据的节段的类型和设置的标志决定了OS加载器在可执行文件启动时是否将其加载到内存中。某些节段默认被自动加载,其他则不会(例如,.symtab, .strtab)。

从攻击角度来看,我们能从中获得什么效率?

嵌入有效负载:第二版

  1. 我们可以避免在节段上设置假设默认加载到内存的标志。

  2. 我们可以使用另一种类型的节段,它不会加载到内存中。

供应商或系统工程师可能需要在目标文件中标记特殊信息,其他程序可以检查这些信息以确认兼容性。类型为SHT_NOTE的节段和类型为PT_NOTE的程序头元素可用于此目的。

在后一种情况下,我们可以在系统二进制文件中看到这种节段类型的用法:

$ readelf --sections /bin/tar | grep NOTE
  [ 2] .note.gnu.bu[...] NOTE             00000000000002c4  000002c4
  [ 3] .note.ABI-tag     NOTE             00000000000002e8  000002e8

并且可以检查其内容:

$ readelf -p .note.ABI-tag /bin/tar

String dump of section '.note.ABI-tag':
  [     c]  GNU

创建一个SHT_NOTE节段的最终结果在ELF中看起来如下: SHT_NOTE

额外好处:SHT_NOTE在我们需要使用时提供了结构(我们将在后续使用): SHT_NOTE结构

ELF节段对接

到目前为止,我们能够创建一个节段,并避免OS加载器将其加载到内存中。该节段当前在ELF镜像中处于休眠状态。我们稍后将讨论如何加载它。 然而,更紧迫的问题是,我们仍然在编译器和链接器层面操作,节段是一个被编织到最终ELF结构中的对象,从而创建了从加载器代码到其内容的引用关系和内存地址。

SHT_NOTE结构

如果我们能够在加载器编译工作流之外创建一个包含嵌入有效负载的ELF节段,并在之后将那个节段附加到加载器二进制文件上,会怎么样?

这将打破加载器代码与节段交互的关系。然后我们教会加载器如何找到并加载它的外来数据节段,从而以松散耦合的方式将有效负载“对接”到加载器上。

从概念上讲,我们的目标是:

  • 加载器不应与有效负载语义纠缠在一起
  • 加载和执行有效负载:
    • 完全不修改加载器代码?
    • 不使用OS加载器ld.so(它会自动将有效负载的段加载到内存中)
  • 现场有效负载(重新)附加。

加载器/有效负载(在节段中)的关系现在看起来像这样:

加载器/有效负载关系

然后我们可以创建一个注入器,它将向加载器引入一个有效负载节段,而两者都不在代码级别操作,仅靠二进制兼容性(并且加载器知道如何加载任何有效负载节段)。

ELF注入器

这种通用ELF节段对接设置带来的一些成果:

  1. 静态ELF加载器可以单独发布,没有有效负载,只有按需加载节段并从其中引导有效负载的机制。
  2. 有效负载可以单独打包,并在任何时候作为静态阶段捆绑到加载器上,或者稍后通过注入器进行捆绑。有效负载通常可以被加密,如果需要,通常可以是一个ELF可执行文件本身,只要加载器不知道有效负载的结构,只知道它的打包能力。
  3. 注入器可以中介来自多个二进制文件(休眠阶段)的节段附加,以构建一个节段并注入到加载器中。
  4. 在节段级别构建方面有优势,相对于在可执行文件中打包多个资源。不会因打包器处理代码而产生检测开销。在携带多个节段以配合其他依赖内存启动且不易打包的工具(可执行节段打包器将二进制文件提取到文件系统中时会有困难)方面具有优势。(详见胖二进制节段部分)

ELF对接组件:

让我们更详细地讨论ELF节段对接组件。

节段型ELF注入器:

部署位置:后端或现场 优势:

  • 无关加载器到有效负载的代理
  • 精简的有效负载生成管道
  • 现场将有效负载附加到加载器,无需编译器(如果需要)

节段型ELF加载器:

部署位置:现场 优势:

  • 与附加的有效负载无关
  • 通过读取和解析自己的二进制文件来加载完整的ELF或shellcode(更多可能性)
  • 如果你需要shellcode,你可以从中创建一个运行的ELF(例如Metasploit的mettle)
  • 追踪看不到mprotect()调用
  • 在有效负载所在位置和正常的.DATA数组之间实现空气间隙隔离
  • 这为追踪器实现了抽象
  • 能够接受参数并将其转发给有效负载本身

二进制有效负载:

优势:

  • 有效负载是一个完全功能的程序,约束更少,数据、段LDD完整
  • 可以独特地混淆,而不考虑空间(.NOTE记录大小可变)
  • 可以提取到文件系统,或作为目录的一部分运行(胖有效负载加载器)
  • 不需要重定位,可以链接到其他加载器
  • 交叉附加和检测规避示例:加载器A读取加载器B的有效负载

规避机会

加强ELF节段型注入器/打包器:

  • XOR'd有效负载,但也可以实现AES
  • XOR密钥元数据存储在带外水印中
  • XOR密钥不公开
  • 额外的XOR'd数据混淆可能

加强ELF加载器:

  • 默认XOR'd有效负载,但也可以实现AES
  • XOR密钥元数据从带外水印中挖掘
  • 加载器启动时间与有效负载加载时间分离(如果需要)
  • 守护进程化能力(能够与用户态exec和memfd_create配合)
  • 可能规避有效负载熵计算和反雕刻:Binwalk默认看不到有效负载,无法雕刻(演示示例:打包msfvenom生成的有效负载)

ELF节段对接工具包特定加载器讨论:

关于ELF节段加载器与有效负载启动器协作的一些说明:

加载器可以利用两种内存中有效负载执行机制之一:

  • 选项A:SYS_Memfd_create ()

    • 通过libreflect[链接]实现,但也可以通过zombieant预加载器[链接]实现
    • 在以下级别更容易被检测:
      • /proc/self/fd/中的匿名文件
      • 使用sys_memfd_create(系统调用#319)
    • 执行fork/exec,BPF跟踪execve()将记录。
  • 选项B:用户态Exec (https://grugq.github.io/docs/ul_exec.txt)

    • 目前通过libreflect实现。接口不错。
    • 挖空加载器并用有效负载覆盖。
    • 无sys_enter_exec / sys_exit_exec调用。BPF跟踪execve()无法捕获
    • 缺点:无法通过加载器守护进程化(加载器内存被覆盖后失效) 但是有效负载可以在启动时自身守护进程化: 发送ELF二进制文件与发送shellcode相比的美妙之处😊

工作流运行: ELF注入器 ELF注入器

ELF节段化有效负载与MSF有效负载相比,Binwalk的规避机会: ELF注入器

eBPF规避与ELF节段打包器对比: ELF注入器

检测工具:

YARA验证器和测试: ELF注入器

ELF注入器

STIX工具定义:

ELF注入器

下载工具