6

如果我使用密碼作爲命令行參數,它在系統上使用ps公開。命令行參數的Shell腳本密碼安全

但是,如果我在bash shell腳本,我做這樣的事情:

... 
{ somecommand -p mypassword } 
... 

是這樣仍然會在進程列表中顯示出來?或者這是安全的?

  • 子流程如何:(...)?不安全的權利?
  • coprocess?

回答

6

命令行將始終可見(如果只通過/ proc)。

所以唯一真正的解決方案是:不要。你可能會提供它在標準輸入,或專用FD:

./my_secured_process some parameters 3<<< "[email protected]" 

與像(簡潔第一)

#!/bin/bash 
cat 0<&3 

(此示例將只轉儲一個錯誤的密碼到標準輸出)

腳本現在你需要關心的是:

  • MITM(欺騙腳本,例如通過破壞PATH甩掉密碼)
  • bash的歷史在命令行保留您的密碼(看HISTIGNORE對於bash,例如)
  • 腳本包含口令重定向使用的TTY的的
  • 安全的保障;鍵盤記錄器; ......你可以看到,我們現在已經陷入「一般安全原則」
+0

是一個錯字了上述3個?它應該是<<<?如果不是,3表示什麼? – q0rban

+0

好吧,我想我明白了。這是爭論的數字?我認爲它應該是2,但不是3.第一個參數是0,第二個1,第三個。這是正確的嗎? – q0rban

+1

沒有。 '<<<'表示:將此文本流式傳輸到標準輸入。 '3 <<<'表示:將此文本流式傳輸至_filedescriptor 3_。正如您在演示腳本中看到的那樣,您可以從腳本中讀取「fd 3」。由於stdin/stdout/stderr是唯一的_standard_(通常)shell管道文件描述符,所以這是安全的。 – sehe

0

從進程列表中被顯示逃脫的唯一方法是,如果你重新實現你想要的程序的全部功能調用純Bash函數。函數調用不是獨立的進程。但通常這是不可行的。

3

被調用的程序可以通過簡單地覆蓋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 
$ 

UPD:我知道,這並不是完全安全的,並可能導致競爭條件,但是很多從命令行接受密碼的程序都會這樣做。

3

如何使用文件描述符的方法:

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 

參見:

Hiding secret from command line parameter on Unix