在Linux 3.19内核上使用bash 4.4观察以下内容:
# in reality, this may access files "nobody" isn't allowed
get_a_secret() { printf '%s\n' "This is a secret"; }
# attach a process substitution reading the secret to FD 10
exec 10< <(get_a_secret)
# run a less-privileged program that needs the secret, passing it the file descriptor.
chpst -u nobody:nobody -- cat /dev/fd/10
...或更短/更简单:
chpst -u nobody:nobody -- cat <(get_a_secret)
要么以类似于以下的方式失败:
cat: /proc/self/fd/10: Permission denied
所以,这个问题有两个分支:
这里发生了什么?
是否有办法获得所需的行为(将秘密读取的能力传递给单个子进程,该进程以不会将该秘密持续暴露给运行为&的其他进程的方式调用#34; nobody&#34;)没有将FIFO的输出暴露给其他进程?
(是的,我很清楚我需要锁定ptrace和/proc/*/mem
以防止另一个进程正在运行,因为&#34; nobody&#34;不会将秘密拉出正在阅读的客户端;那就是说,我可以做的事情,以及(2)当流程只在任何潜在的攻击者控制的可执行文件被调用之前运行时,允许任何以nobody
运行的进程在该进程的整个持续时间内将秘密从/proc/*/environ
中拉出来。)
答案 0 :(得分:1)
以下解决方法可以避免此问题:
exec 10< <(get_a_secret)
chpst -u nobody:nobody -- sh -c 'cat <&10'
请注意重定向被写为<&10
- 不是 </dev/fd/10
或</proc/self/fd/10
(在提供/dev/fd
的平台上) - 在没有平台的情况下这个工具,bash将其重写为fdup2()
电话。
对行为进行解释的答案(可能是允许不接受FD号作为输入的程序在读取方上行动的解决方法?)将能够取代这一个。 :)