Execute dynamic or statically compiled ELF Linux binaries without e execve().
This Python tool is called ulexecve and it stands for *userland execve*. It helps you execute arbitrary ELF binaries on Linux systems from userland without e the *execve()* systemcall. In other words: you can execute arbitrary binaries directly from memory without e to write them to storage. This is very useful from an anti-forensic or red-teaming perspective and enables you to mo more stealthily while still dropping compiled binaries on target machines. The tool works on CPython 3.x as well as CPython 2.7 (and possibly earlier) on the supported Linux platforms (x86, x86-64 and aarch64). Both static and dynamically compiled ELF binaries are supported. Of course there will always be a small subset of binaries which may not work or result in a crash and for these a 100% reliable fallback method is implemented on top of the modern memfd_create() system call.
Linux userland exec have a history that goes back roughly two decades. The first solid writeups on this were made by *the grugq* in *The Design and Implementation of Userland Exec* [1] as well another article in Phrack 62 [2]. Anti-forensic techniques to execute binaries directly from memory are fairly standard. Rapid7's *mettle* for example has a library named libreflect which includes a utility noexec which also attempts to execute an ELF only. However this tool is written in C and it has the implicit requirement that you need to transfer the noexec binary on the target system as well being able to execute this binary.
In modern container en this is definitely not always possible anymore. However a lot of container en do contain a Python installation. Having the ability to simply download a Python script via curl or so on a target machine and then being able to execute this script to then stealthily execute arbitrary binaries is very useful from an anti-forensics perspective.
This is also the reason the tool is all implemented in just one file. This should make it easier to download it on target systems and not have to worry about installing any other dependencies before being able to run it. The tool is tested with Python 2.7 e this Python is deprecated. There are many systems still out there with 2.x so this is useful.
No good other implementations of a Python userland *execve()* existed. There is *SELF* [3] which was not extensively documented, lacked easy debugging options but more importantly didn't work at all. The ulexecve implementation was written from scratch. It parses the ELF file, loads and parses the dynamic linker as well (if needed), maps all segments into memory and ultimately constructs a jump buffer containing CPU instructions to ultimately transfer control from the Python process directly to the newly loaded binary.
All the common ELF parsing logic, setting up the stack, mapping the ELF segments and setting up the jump buffers is abstracted away so it is fairly easy (in the order of a couple of hours) to port to another CPU. Porting it to other ELF based platforms such as the BSDs might be a bit more in but should still be fairly straightforward. For more information on to do so just check the comments in the code.
Please note that it is an explicit design goal to have no external dependencies and to ha implemented in a single source code file. If you need to make smaller payloads it should be fairly trivial to remo for cetain CPU types or rip out all the debug information and other options.
Although this makes little sense from an anti-forensics perspective the tool is installable via pip.
The tool fully supports static and dynamically compiled executables. Simply pass the filename of the binary to ulexecve and any arguments you want to supply to the binary. The en will be directly copied over from the en in which you execute ulexecve.
You can have it read a binary from stdin if you specify - as the filename.
To download a binary into memory and immediately execute it you can use --download. This will interpret the filename argument as a URI.
To debug several options are a. If you get a crash you can show debug information via --debug, the built up stack via --show-stack as well as the generated jump buffer --show-jumpbuf. The --jump-delay option is very useful if you want to parse and map an ELF properly and then attach a debugger to step through the jump buffer and the ultimate executing binary to find the cause of the crash.
There is always the --fallback option. It is not as stealthy as parsing and mapping in the binaries in userland ourselves. The fallback method uses memfd_create() and fexecve() but it should work 100% of time for executing arbitrary static or dynamic binaries. Provided the supplied binaries are the right binaries for the platform you are on ob.
Ob you can always end up with binaries which will not be executed properly. However this implementation is pretty clean and well tested (it includes unit-tests for static and dynamic binaries, PIE-compiled executables and executables with different runtimes such as Rust or Go). For most tools and binaries on the mentioned platforms it should do the trick. But your mileage may vary. Binaries that are produced by installation packers that embed other information inside the ELFs might not work properly depending on the self-referencing tricks they use. For PyInstaller binaries however a specific fallback was added to ulexecve.
Binaries which are created with PyInstaller will not work directly. These binaries require an accompanying package file or, in most cases, embed within the ELF the extra data needed to unpack and run properly after starting the embedded Python interpreter. This means that they cannot be made to work properly. There are a few ways of getting around this. A simple way, that may work in a subset of real world cases, assumes there is a writeable temp filesystem out there. Then we replace the string /proc/self/exe in the binary with /tmp/xxxx. After that we load the binary in memory via memfd_create() and then point the symlink at /tmp/xxxx to /proc/<pid>/fd/<fd> to the in-memory file. To try this option use --pyi-fallback. If you need to specify a specific other temporary directory use --tmpdir. Please note that the resulting path including the tmpdir has to be the exact same amount of bytes long as is the string /proc/self/exe (14 bytes) so longer paths won't work.
When porting to a different platform make sure that the small amount of unit-tests all work. Simply run the included ./test.py on the target platform and fix up e up until all these tests succeed again.
Shoot in a pull-request , post an issue in the issue tracker or simply shoot an email to *g.com*.
1. "The Design and Implementation of Userland Exec", by the grugq.
2. "FIST! FIST! FIST! Its all in the wrist: Remote Exec", by grugq, Phrack 62-0x08, 2004-07-13.
3. Implementation of SELF in Python, by Maciej Kotowicz (mak).
开发语言:Python
Star 数:218
该项目属于红蓝攻防方向的开源资源,代码结构清晰,适合安全研究人员学习参考。项目围绕ulexecve is a userland execve() implementation which helps you execute arbitrary ELF binaries on Linux from userland without the binaries ever having to touch storage. This is useful for red-teaming and anti-forensics purposes.展开,提供了可运行的实现,对理解相关安全机制、工具原理与攻防技术具有较高的研究价值。
从技术实现角度看,此类项目的核心在于对底层原理的深入理解与工程化落地。开发者在研究过程中可以结合官方文档与社区讨论,梳理项目的初始化流程、核心模块职责与数据流转,逐步掌握其中的技术细节与设计思路。
1. 下载源码压缩包,解压到本地环境。
2. 根据项目类型准备对应的运行环境与依赖。
3. 按照 README 中的步骤完成配置与部署。
4. 在隔离的测试环境中运行验证,避免影响生产系统。
本资源来源于开源社区,仅供安全研究、技术学习与合法授权范围内的攻防演练使用,请勿用于任何非法或侵害他人权益的用途。使用本项目产生的一切后果由使用者自行承担。
| 资源标题 | ulexecve - ulexecve is a userland execve() implementation whi |
| 所属分类 | 红蓝攻防 |
| 发布作者 | admin |
| 发布时间 | 2026-10-06 00:46:48 |
| 下载权限 | 免费下载 |
| 附件数量 | 2 个下载链接 |
| 浏览次数 | 263 |
| 讨论数量 | 0 |
| 主题状态 | 正常讨论中 |