如果我将密码作为命令行参数使用,那么在使用ps
命令的系统上,密码会变成公共信息。
但是,如果我在bash shell脚本中执行以下操作:
...
{ somecommand -p mypassword }
...
这个进程还会在进程列表中显示吗?还是说它是安全的?
- 子进程呢:(...)?不安全对吧?
- 协同进程?
如果我将密码作为命令行参数使用,那么在使用ps
命令的系统上,密码会变成公共信息。
但是,如果我在bash shell脚本中执行以下操作:
...
{ somecommand -p mypassword }
...
这个进程还会在进程列表中显示吗?还是说它是安全的?
命令行始终可见(即使只是通过/proc可见)。
因此,唯一真正的解决方案是:不要让其可见。您可以将其提供在stdin上或专用的fd上:
./my_secured_process some parameters 3<<< "b@dP2ssword"
#!/bin/bash
cat 0<&3
现在你需要关注的是:
(此示例只会将错误密码转储到stdout)
env -i bash --norc # clean up environment
set +o history
read -s -p "Enter your password: " passwd
exec 3<<<"$passwd"
mycommand <&3 # cat /dev/stdin in mycommand
参见:
argv
来更改其命令行,例如:#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv) {
int arglen = argv[argc-1]+strlen(argv[argc-1])+1 - argv[0];
memset(argv[0], arglen, 0);
strncpy(argv[0], "secret-program", arglen-1);
sleep(100);
}
测试:
$ ./a.out mySuperPassword &
$ ps -f
UID PID PPID C STIME TTY TIME CMD
me 20398 18872 0 11:26 pts/3 00:00:00 bash
me 20633 20398 0 11:34 pts/3 00:00:00 secret-program
me 20645 20398 0 11:34 pts/3 00:00:00 ps -f
$
更新:我知道这并不完全安全,可能会导致竞争条件,但是许多从命令行接受密码的程序都使用此技巧。
唯一的逃避被显示在进程列表中的方法是,如果您在纯Bash函数中重新实现要调用的程序的整个功能。函数调用不是单独的进程。虽然通常这是不可行的。
<<<
的意思是:将此文本流传输到stdin。3<<<
的意思是:将此文本流传输到文件描述符3。正如演示脚本所示,您可以从脚本中读取fd 3
。这是一种安全性通过混淆,因为stdin/stdout/stderr是唯一的标准(通常)shell管道文件描述符。 - sehecat
(在示例中)的标准输入(文件描述符0)... 但至少不会出现在ps
,top
或/proc/...
的命令行中。 - sehe./my_secured_process some parameters 3< <(printf '%s\n' b@dP2ssword)
- tanius