【问题标题】:Shell script password security of command-line parameters命令行参数的Shell脚本密码安全
【发布时间】:2011-09-30 06:19:10
【问题描述】:

如果我使用密码作为命令行参数,它在系统上使用ps 公开。

但如果我在一个 bash shell 脚本中并且我执行以下操作:

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

这还会出现在进程列表中吗?或者这样安全吗?

  • 子流程如何:(...)?不安全吧?
  • 协同处理?

【问题讨论】:

    标签: linux bash command-line command-line-arguments password-protection


    【解决方案1】:

    命令行将始终可见(如果仅通过 /proc)。

    所以唯一真正的解决方案是:不要。您可以在标准输入或专用 fd 上提供它:

    ./my_secured_process some parameters 3<<< "b@dP2ssword"
    

    使用类似(简单第一)的脚本

    #!/bin/bash
    cat 0<&3
    

    (此示例只会将错误密码转储到标准输出)

    现在你需要关心的是:

    • MITM(窃取密码的欺骗脚本,例如通过破坏 PATH)
    • 在命令行中保留密码的 bash 历史记录(例如,查看 HISTIGNORE 以获取 bash)
    • 包含密码重定向的脚本的安全性
    • 使用的 tty 的安全性;键盘记录器; ...如您所见,我们现在已进入“一般安全原则”

    【讨论】:

    • 上面的3是错字吗?它应该只是
    • 好的,我想我明白了。那是参数的数量?我认为它应该是 2,但不是 3。第一个参数是 0,第二个 1,第三个 2。这样对吗?
    • 不。 &lt;&lt;&lt; 表示:将此文本流式传输到标准输入。 3&lt;&lt;&lt; 表示:将此文本流式传输到 filedescriptor 3。正如您在演示脚本中看到的那样,您可以从脚本中读取fd 3。这是默默无闻的安全性,因为 stdin/stdout/stderr 是唯一的标准(通常的)shell 管道文件描述符。
    • 坦率地说,这并没有真正让你买多少,因为输入最终仍会被发送到标准输入上的cat(在示例中)......(filedescriptor我>0)。但至少它不会出现在pstop、/proc/...中的命令行上。
    • Apparently, "这里 bash 中的字符串被实现为已删除的临时文件"。如果这意味着他们可以将其写入磁盘,这是另一个安全考虑。使用进程替换可能会更好like here: ./my_secured_process some parameters 3&lt; &lt;(printf '%s\n' b@dP2ssword)
    【解决方案2】:

    被调用的程序可以通过简单地覆盖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

      【讨论】:

        【解决方案4】:

        避免显示在进程列表中的唯一方法是重新实现要在纯 Bash 函数中调用的程序的全部功能。函数调用不是单独的进程。不过,这通常是不可行的。

        【讨论】:

          猜你喜欢
          • 2013-03-03
          • 1970-01-01
          • 1970-01-01
          • 2021-02-04
          • 2014-04-03
          • 2010-09-07
          • 2021-07-20
          • 2015-01-18
          • 2017-11-19
          相关资源
          最近更新 更多