跟踪没有读取权限的可执行文件

kas*_*erd 17 permissions strace

strace在我没有读取权限的可执行文件上使用时,我在 Ubuntu 14.04 上发现了一些令人惊讶的行为。我想知道这是一个错误,还是某些标准要求这种模糊的行为。

首先让我们看看当我在后台启动一个普通的可执行文件并附加到它时会发生什么。正如预期的那样,这有效:

$ /bin/sleep 100 &
[2] 8078
$ strace -p 8078
Process 8078 attached
restart_syscall(<... resuming interrupted call ...>
Run Code Online (Sandbox Code Playgroud)

接下来我尝试使用一个可执行文件,我没有读取权限:

---x--x--x 1 root root 26280 Sep  3 09:37 sleep*
Run Code Online (Sandbox Code Playgroud)

不允许附加到这个正在运行的进程:

$ ./sleep 100 &
[1] 8089
$ strace -p 8089
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted
Run Code Online (Sandbox Code Playgroud)

这也是我所期望的。如果我可以简单地将调试器附加到进程并有效地以这种方式对可执行文件具有读取权限,那么在没有读取权限的情况下授予执行权限不会有多大好处。

但是,如果我在已经跟踪的进程下启动可执行文件,则可以这样做:

$ strace ./sleep 100
execve("./sleep", ["./sleep", "100"], [/* 69 vars */]) = 0
brk(0)                                  = 0x9b7a000
Run Code Online (Sandbox Code Playgroud)

这对我来说是出乎意料的。这是安全漏洞,还是标准强制要求的功能?

小智 7

这不是答案,而是链接和想法的集合,以防其他人也想学习。因为这是一件非常有趣的事情。

Unix&Linux 上的相关答案提到它可以(或者现在不能用普通内核测试)可以通过这种方式转储只读二进制文件。

Grsecurity 试图修复这个配置选项补丁本身(尽管它可能已经改变了)

这个提交确实让人觉得,内核开发人员真的只关心转储 suid 二进制文件。

但实际上从这一行我猜内核想防止转储不可读的二进制文件,不管 SUID 状态。这一表明不可转储的二进制文件不应该是可追踪的。

因此,乍一看,您似乎在内核中发现了一个具有安全隐患的错误。但我不是内核开发人员,所以我不能肯定。我会问 LKML。

编辑:关于调试器的另一个发现,在对原始帖子的评论中提到 - 从快速跟踪(再次)在我看来,gdb 使用跟踪的二进制文件和/proc/<pid>/mem. 一旦运行的二进制文件不可读,则cat /proc/<pid>/mem返回EPERM. 如果二进制文件可读,则返回EIO. (在运行多个安全补丁的 Ubuntu 14.10 上对此进行了测试,因此这可能与普通内核不同。同样,我没有在任何方便的地方运行普通内核 :()