为了模拟某些行为,我希望将探针附加到syscall上,并在传递某些参数时修改返回值。另外,在处理函数之前修改函数的参数也就足够了。
BPF可以吗?
-e
更改系统调用的返回值。引用the manual page:-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr]
Perform syscall tampering for the specified set of syscalls.
[此外,如果您有兴趣,可以在[F0dem 2017]上进行a presentation和故障注入。这是幻灯片中的一个示例命令:strace -P precious.txt -efault=unlink:retval=0 unlink precious.txt
编辑:如Ben所述,有关kprobes和跟踪点的eBPF绝对是只读的,用于跟踪和监视用例。我也在IRC上得到了有关此的确认。
允许的运行时修改为:
[SECCOMP_RET_KILL
:立即杀死SIGSYS
SECCOMP_RET_TRAP
:发送可捕获的SIGSYS
,从而有机会模拟系统调用]SECCOMP_RET_ERRNO
:强制errno
值SECCOMP_RET_TRACE
:决定ptracer的产量或将errno
设置为-ENOSYS
SECCOMP_RET_ALLOW
:允许SECCOMP_RET_TRACE
方法可修改执行的系统调用,参数或返回值。这是依赖于体系结构的,对强制性外部引用的修改可能会导致ENOSYS错误。 通过将执行传递给等待的用户空间ptrace来执行,该函数可以修改跟踪的进程内存,寄存器和文件描述符。
跟踪器需要先调用ptrace,然后再等待。一个例子:
ptrace(PTRACE_SETOPTIONS, tracee_pid, 0, PTRACE_O_TRACESECCOMP);
waitpid(tracee_pid, &status, 0);
http://man7.org/linux/man-pages/man2/ptrace.2.html
当waitpid
返回时,根据status
的内容,可以使用PTRACE_GETEVENTMSG
ptrace操作检索seccomp返回值。这将检索seccompSECCOMP_RET_DATA
值,该值是BPF程序设置的16位字段。示例:
ptrace(PTRACE_GETEVENTMSG, tracee_pid, 0, &data);
Syscall参数可以在继续操作之前在内存中进行修改。您可以执行单个syscall进入或通过PTRACE_SYSCALL
步骤退出。可以在恢复执行之前在用户空间中修改Syscall返回值。基础程序将无法看到syscall返回值已被修改。
示例实现:Filter and Modify System Calls with seccomp and ptrace
* int bpf_probe_write_user(void *dst, const void *src, u32 len)
* Description
* Attempt in a safe way to write *len* bytes from the buffer
* *src* to *dst* in memory. It only works for threads that are in
* user context, and *dst* must be a valid user space address.
*
* This helper should not be used to implement any kind of
* security mechanism because of TOC-TOU attacks, but rather to
* debug, divert, and manipulate execution of semi-cooperative
* processes.
*
* Keep in mind that this feature is meant for experiments, and it
* has a risk of crashing the system and running programs.
* Therefore, when an eBPF program using this helper is attached,
* a warning including PID and process name is printed to kernel
* logs.
* Return
* 0 on success, or a negative error in case of failure.
跟踪BPF程序可以覆盖当前的用户内存bpf_probe_write_user()执行任务。每次加载此类程序内核将打印警告消息,因此此帮助程序仅有用用于实验和原型。跟踪BPF程序仅是root用户。