我在linux中使用mutt命令,它在定期运行时可以工作。
mutt myOwnMail@server.com -s "some_subject" -a file.log < file.log #WORKS
当使用";strace";它也起作用:
strace mutt myOwnMail@server.com -s "some_subject" -a file.log < file.log # WORKS
但是当使用";strace-f";,它失败了。为什么?
strace -f mutt myOwnMail@server.com -s "some_subject" -a file.log < file.log # FAILS MISERABLY
输出:
[pid 24140] open("maildrop/816765.24140", O_RDWR|O_CREAT|O_EXCL, 0644) = -1 EACCES (Permission denied)
[pid 24140] write(2, "postdrop: warning: mail_queue_en"..., 90postdrop: warning: mail_queue_enter: create file maildrop/816765.24140: Permission denied
) = 90
[pid 24140] sendto(3, "<20>Aug 22 20:49:03 postfix/post"..., 124, MSG_NOSIGNAL, NULL, 0) = 124
[pid 24140] rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD TSTP], 8) = 0
[pid 24140] nanosleep({10, 0}, 0x7ffd7e940140) = 0
[pid 24140] open("maildrop/817709.24140", O_RDWR|O_CREAT|O_EXCL, 0644) = -1 EACCES (Permission denied)
[pid 24140] write(2, "postdrop: warning: mail_queue_en"..., 90postdrop: warning: mail_queue_enter: create file maildrop/817709.24140: Permission denied
) = 90
[pid 24140] sendto(3, "<20>Aug 22 20:49:13 postfix/post"..., 124, MSG_NOSIGNAL, NULL, 0) = 124
[pid 24140] rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD TSTP], 8) = 0
[pid 24140] nanosleep({10, 0}, 0x7ffd7e940140) = 0
[pid 24140] open("maildrop/818761.24140", O_RDWR|O_CREAT|O_EXCL, 0644) = -1 EACCES (Permission denied)
[pid 24140] write(2, "postdrop: warning: mail_queue_en"..., 90postdrop: warning: mail_queue_enter: create file maildrop/818761.24140: Permission denied
) = 90
[pid 24140] sendto(3, "<20>Aug 22 20:49:23 postfix/post"..., 124, MSG_NOSIGNAL, NULL, 0) = 124
[pid 24140] rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD TSTP], 8) = 0
[pid 24140] nanosleep({10, 0}, ^Cstrace: Process 24137 detached
为什么fork(-f选项(会破坏它?谢谢
编辑:运行命令时:
sh -c 'find / -name *postdrop* -ls 2> /dev/null'
输出为:
2333274 216 -rwxr-sr-x 1 root postdrop 218632 Oct 30 2018 /usr/sbin/postdrop
9426253 4 -rw-r--r-- 1 root root 1629 Oct 30 2018 /usr/share/man/man1/postdrop.1.gz
strace
日志显示,实际失败的操作是尝试创建名为maildrop/816765.24140
的文件(可能在/var/spool
中的某个目录中(。当mutt
在strace -f
下运行时,此操作或类似操作将失败,而当mutt
在strace
下运行时(不带-f
选项(,此操作将成功。我们可以从这些事实推断,失败的不是mutt
本身,而是mutt
创建的一些子流程。此外,失败代码是EACCES
,这意味着问题是某个东西没有所需的访问权限,当且仅当正在调试时(strace
使用调试器API跟踪执行(。
好吧,那么,当运行一个附加了调试器的进程时,会导致它失去访问权限吗?当进程正在执行setuid或setgid程序时。这些是经过特殊标记的程序,通常使用用户的访问权限和/或可执行文件所有者的组标识运行。这使它们能够做调用用户通常不能做的事情。这种程序的典型例子是su
实用程序,如果你知道其他用户的密码,它可以让你以其他用户的身份运行shell。
然而,当setuid或setgid程序在附加调试器的情况下运行时,内核不会授予它通常的访问权限,因为这会破坏安全性。想象一下,您可以在gdb
下运行具有所有正常超能力的su
——这将允许您绕过密码检查,并在任何时候以任何用户的身份运行shell。
根据错误消息,有问题的程序名为postdrop
,因此您可以找到可执行文件,并通过以下命令确定它是否具有以下特殊标记之一:
sh -c 'find / -name *postdrop* -ls 2> /dev/null'
编辑:(的一部分(报告的系统上此命令的输出是
2333274 216 -rwxr-sr-x 1 root postdrop 218632 Oct 30 2018 /usr/sbin/postdrop
数字和日期对这个问题并不重要,所以让我们只看四个关键列:
-rwxr-sr-x root postdrop /usr/sbin/postdrop
首先,/usr/sbin/postdrop
是一个名为postdrop
的程序的合理完整路径名,该程序由mutt
内部调用,因此我们知道我们正在寻找正确的方法。(find
命令报告输出的其他行引用文件/usr/share/man/man1/postdrop.1.gz
。/usr/share/man
中的所有内容(应该是(文档,而不是程序,所以我们可以忽略这一行。(
第二,-rwxr-sr-x
给出访问控制";模式";程序的——谁被允许读取、写入和/或执行程序;s";是关键。在该位置,这意味着该程序是setgid:它将使用拥有该文件的组的访问控制组标识运行,而不是使用运行该程序的用户的组标识运行。这正是我推测的情况。(一个普通程序将具有访问控制模式-rwxr-xr-x
,而像sudo
这样的setuid程序将具有模式-rwsr-xr-x
。(
第三;根后缀";告诉我们拥有该文件的用户和组。该程序以访问控制组标识"执行;postdrop";。这与程序本身的名称相同,这可能意味着该组致力于为该程序提供其工作所需的权限(即排队发送电子邮件(。
因此,结论:您不能使用strace -f
来观察排队发送电子邮件的整个过程,因为这将涉及在调试器下运行setgid程序,这违反了系统安全策略。
Unix安全策略的这一特定方面被硬编码到内核中,在20世纪70年代的分时系统中更有意义。如果您可以使用postdrop
组的访问权限运行任意代码(调试程序API允许您这样做,如果调试setgid程序没有取消setgid效果(,那么您可能会读取同一系统上其他用户正在发送的电子邮件。没有人想要那样。
如果您在个人工作站上,只有您才能使用,那么您应该能够通过以root身份运行strace -f mutt
而不是以普通用户帐户的身份绕过此规则。根已经可以读取每个人的邮件,因此不会对他们强制执行该策略。