将密码通过管道回传给passwd是多么危险

时间:2017-10-31 19:10:52

标签: bash processlist

我在多个讨论中看到使用echo to pipe to passwd是危险的,因为可以从进程列表中获取提供的参数。

我目前正在开发一种通过ssh远程更改密码的工具。我使用echo方法,因为我没有root访问权限来使用usermod或chpasswd。

CMD:

echo -e 'old\nnew\nnew' | passwd

要检查它有多容易 - 我试过了。但无法得到它们。

这是我的方法:

#!/bin/bash
filename=$1

while true
do
    echo "$(pgrep -af passwd)" >> "$filename"
    sleep 0.1
done

我几次通过echo更改了密码,却看不到任何东西。我认为 sleep 0.1 可能是个问题。

从流程列表中获取它是多么容易,因此以这种方式使用它是多么不安全。

2 个答案:

答案 0 :(得分:3)

如果您通过echo|passwd调用ssh命令,例如:

client$ ssh example.com "echo -e 'foo\nbar\nbar' | passwd"

然后您需要查看的进程不是passwd,而是远程端sshd调用的用户登录shell:

server$ until pgrep -af bash | grep passwd; do true; done
8387 bash -c echo -e 'foo\nbar\nbar' | passwd

答案 1 :(得分:2)

这取决于您使用的shell是echo作为内置函数,还是使用外部二进制文件(/ bin / echo)。如果它是外部二进制文件,它将作为子进程运行,密码在其参数列表中明显可见(通过pspgrep等)。如果它是内置的,管道中的echo命令将作为子进程运行,但它将是一个子shell,它具有与父shell相同的可见参数列表(即它是安全的)。

所以可能安全,但有几个并发症需要担心。首先,如果您通过ssh在远程计算机上运行它,则不一定知道它的默认shell是什么。如果它是bash,你没问题。如果它破折号,我认为你有问题。其次,您不必担心远程shell和/或echo命令,您必须担心从本地脚本到远程echo命令的路径中的每一步。例如,如果您使用:

ssh user@computer "echo -e 'old\nnew\nnew' | passwd"

...然后远程echo可能是安全的(取决于远程shell),但是@thatotherguy指出密码将在远程shell(bash -c echo -e 'foo\nbar\nbar' | passwd和在本地ssh进程的参数列表中。

还有另一个复杂问题,BTW:echo关于它如何处理选项(如-e)和输出字符串中的转义不一致(例如,参见this question)。你最好使用printf(例如printf '%s\n' "$oldpass" "$newpass" "$newpass"),这也是bash内置的。或者,如果您确定要使用bash,则可以使用here-string(<<<string)代替。它根本不解释转义,但您可以使用bash的$' '构造来解释它们:

passwd <<<"$old"$'\n'"$new"$'\n'"$new"

这根本不涉及子进程(/bin/echo或子shell),所以不用担心进程表。

另一种避免远程shell不确定和ssh参数列表中出现的密码问题的可能性是通过ssh的stdin传递密码:

ssh user@computer passwd <<<"$old"$'\n'"$new"$'\n'"$new"