bpftrace 和 sys_read 系统调用

bpftrace and sys_read syscall

我正在尝试编写一个 bpftrace 脚本,它获取从后缀进程传递的字符串和用于身份验证部分的 saslauthd。目标是检测我公司的妥协帐户。 strace 命令给我一些不错的结果:

strace -p PID -s 100 -e 'read'
read(7, "[=11=]", 2)                     = 2
read(7, "xxxxxxxxxx", 10)               = 10
read(7, "[=11=]\t", 2)                      = 2
read(7, "YYYYYYYYY", 9)                 = 9
read(7, "[=11=]", 2)                      = 2
read(7, "smtp", 4)                      = 4

我可以恢复 login/password 并检测是否存在暴力破解 运行。

但我尝试使用 bpftrace 获得相同的结果:

$ bpftrace -e 'kprobe:sys_read /comm=="saslauthd"/ {printf("%<%s>\n",str(arg1,arg2));}'
<>
<login>
<>
<>
<>
<smtp>

在这种情况下,我可以读取一些 sys_read 系统调用字符串,但不是全部。我不明白为什么我的 bpftrace 没有相同的结果。 我还考虑了空字符以及为什么我使用 str(arg1,arg2) 来强制数组的大小。我也尝试过使用 tracepoint,这是相同的结果。

也许有人可以帮助我了解我的错误在哪里?因此,我们将不胜感激任何意见

TL;DR. 这实际上是 str(buf, len) 的预期行为。它检索 buf 指向的字符串,限制为 len 个字符,包括 NULL 字符。因此,由于在您的情况下某些字符串以 NULL 字符开头,因此 str() 将复制一个空字符串。


Sources. bpftrace translates str() into a call to the BPF_FUNC_probe_read_str BPF helper. In the kernel,那个助手本身调用 strncpy_from_unsafe.

我认为 bpftrace 还没有实现您正在寻找的功能。如果你想要你描述的语义,你可以在 bpftrace 中请求一个 copy() 函数。不过,看看 the commit that introduced str(),为此编写补丁应该不会太难。不要犹豫,发送请求请求!