将核心逻辑放入 memfd_create 中的匿名文件,exec 执行它
这个更狠:不把 payload 放在磁盘上,而是从内存中动态构造出一个 ELF 文件,然后 execve("/proc/self/fd/xxx")
执行它。
int fd = memfd_create("payload", MFD_CLOEXEC);
write(fd, payload_data, payload_size);
fexecve(fd, argv, envp); // 直接 exec 内存 ELF
#include <fcntl.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <linux/seccomp.h>
#include <linux/filter.h>
#include <linux/audit.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/wait.h>
#ifndef MFD_CLOEXEC
#define MFD_CLOEXEC 0x0001
#endif
extern "C" {
unsigned char payload[] = {
// python 加密脚本生成的字节数组替换这里
0xde, 0xad, 0xbe, 0xef
};
unsigned int payload_len = 4;
}
int memfd_create(const char *name, unsigned int flags) {
return syscall(SYS_memfd_create, name, flags);
}
void apply_seccomp() {
struct sock_filter filter[] = {
// 禁止 ptrace、open/openat、write 等 syscall,可按需扩展
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_ptrace, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_open, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_openat, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_write, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
// 允许其他
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
};
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
.filter = filter,
};
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
}
int main() {
const unsigned char xor_key = 0x5A;
int fd = memfd_create("payload_exec", MFD_CLOEXEC);
if (fd < 0) {
perror("memfd_create");
return 1;
}
// 解密 payload
for (unsigned int i = 0; i < payload_len; ++i) {
payload[i] ^= xor_key;
}
// 写入 fd
if (write(fd, payload, payload_len) != payload_len) {
perror("write payload");
return 1;
}
// 设置 seccomp,防止后续注入、patch
apply_seccomp();
// 执行 payload,argv/envp 可为空或自己构造
char *argv[] = {nullptr};
char *envp[] = {nullptr};
fexecve(fd, argv, envp);
perror("fexecve failed");
return 1;
}