在 PuTTY 中,脚本密码是暴露的密码
PuTTY 是最古老和最流行的 SSH 客户端之一,最初用于 Windows,但现在可在多个平台上使用。它赢得了企业支持和认可,并在多个第三方存储库中准备和捆绑。
不幸的是,0.74 稳定版 PuTTY 未能安全地保护通过 -pw 命令行选项提供给 psftp、pscp 和 plink 实用程序的明文密码,正如文档明确警告的那样。源代码中有证据表明作者意识到了这个问题,但在 Microsoft Windows、Oracle Linux 和 OpenBSD 项目准备的软件包中证实了这种暴露。
在与 PuTTY 的原始作者 Simon Tatham 讨论后,他开发了一个新的 -pwfile 选项,该选项将从文件中读取 SSH 密码,并将其从命令行中删除。此功能可以反向移植到当前的 0.76 稳定版本中。提供了应用反向移植和用于 psftp 的 .netrc 包装器的完整说明,也在 Busybox 下的 Windows 中实现。
虽然 -pw 选项对于需要使用密码(并被禁止使用密钥)进行脚本活动的 SSH 用户很有吸引力,但应理解该功能在任何使用情况下的暴露风险。有安全顾虑的用户应获取 -pwfile 功能,可以通过将补丁应用于 0.76 稳定版本,或使用 PuTTY 网站上的快照版本。
漏洞
psftp、pscp 和 plink 实用程序能够在命令行上接受密码,正如其用法输出所描述的那样
$ psftp -h
PuTTY Secure File Transfer (SFTP) client
Release 0.76
Usage: psftp [options] [user@]host
Options:
-V print version information and exit
-pgpfp print PGP key fingerprints and exit
-b file use specified batchfile
-bc output batchfile commands
-be don't stop batchfile processing if errors
-v show verbose messages
-load sessname Load settings from saved session
-l user connect with specified username
-P port connect to specified port
-pw passw login with specified password
-1 -2 force use of particular SSH protocol version
-ssh -ssh-connection
force use of particular SSH protocol variant
-4 -6 force use of IPv4 or IPv6
-C enable compression
-i key private key file for user authentication
-noagent disable use of Pageant
-agent enable use of Pageant
-no-trivial-auth
disconnect if SSH authentication succeeds trivially
-hostkey keyid
manually specify a host key (may be repeated)
-batch disable all interactive prompts
-no-sanitise-stderr don't strip control chars from standard error
-proxycmd command
use 'command' as local proxy
-sshlog file
-sshrawlog file
log protocol details to a file
-logoverwrite
-logappend
control what happens when a log file already exists
EPEL 软件包中捆绑的 psftp、pscp 和 plink 客户端的手册页清楚地记录了此选项的暴露风险
$ man psftp | sed -n '/pw password/,/commands/p'
-pw password
Set remote password to password. CAUTION: this will likely make
the password visible to other users of the local machine (via
commands such as `w').
请注意,上面 UNIX 手册页中的文档未包含在 Windows MSI 安装程序中。虽然此警告在通用文档中可以找到,但 Windows 用户的风险并不突出
3.11.3.8 -pw:指定密码自动化远程登录的一种简单方法是在命令行上提供您的密码。出于安全原因,不建议这样做。如果可能,我们建议您设置公钥身份验证来代替。
此警告是真实的,在 Linux 上很容易证明
$ psftp -pw foobar4.foobar cfisher@localhost Using username "cfisher". Remote working directory is /home/cfisher psftp> !sh $ ps ax | grep psftp 7490 pts/1 S 0:00 psftp -pw foobar4.foobar cfisher@localhost sh-4.2$ cat /proc/7490/cmdline; echo psftp-pwfoobar4.foobarcfisher@localhost
依赖 -pw 参数来自动化 psftp、pscp 或 plink 的 Shell 脚本以凭据暴露为代价,因为任何 shell 帐户都可以查看进程列表,在 Linux 上通过 /proc/*/cmdline,在 OpenBSD 上通过其他机制。
Windows 用户可能会争辩说此问题不会影响他们的平台;他们错了,因为在任务管理器中点击几下就会显示出来

与 -pw 选项一起使用的密码应被视为已暴露,如果任何非特权用户访问过进程列表,则应更改密码。
不完整的补救措施
虽然这是一个常见但不完美的解决方案,但现代程序似乎通过写入 C 编程语言中定义的“参数向量”来擦除其命令行中的密码。以下是一个示例
$ cat clipurge.c
#include <stdio.h>
#include <string.h>
#define BUF 1024
int main(int argc, char **argv)
{
int c; char junk[BUF];
for(c = 1; c < argc; c++)
if(!strcmp("-pw", argv[c]))
{
int d = 0;
while(*(d + argv[c + 1]))
*(d++ + argv[c + 1]) = '*';
}
fgets(junk, BUF, stdin);
}
我们可以编译和测试此代码以查看删除效果
$ cc -o clipurge clipurge.c $ ./clipurge foo bar -pw baz bada bing
从另一个 shell 中,检查进程列表
$ ps ax | grep clipurge 13500 pts/1 S+ 0:00 ./clipurge foo bar -pw *** bada bing
该技术已在 Oracle Linux 和 OpenBSD 上测试有效(值得注意的是,它在旧版 HP-UX 上不起作用,在旧版 HP-UX 上可以使用旧的 hide.c 代替)。不幸的是,在 Cygwin GCC 编译器上进行的测试中,Windows 未得到补救。
由于所有 PuTTY 实用程序都是用 C 编写的,如果可以使用功能强大的 C 编译器,我们可以将此代码添加到它们的源代码中并准备新的二进制文件。
要在适用的平台上创建 psftp、pscp 和 plink 实用程序的修补版本,请将以下文件放在您的主目录中
$ cat ~/cmdline.patch
--- cmdline.c.orig 2021-09-26 11:15:52.386305592 -0500
+++ cmdline.c 2021-09-26 11:16:08.359152634 -0500
@@ -163,7 +163,7 @@
settings_set_default_port(port);
conf_set_int(conf, CONF_port, port);
}
-
+extern char **globargv; extern int globargc;
int cmdline_process_param(const char *p, char *value,
int need_save, Conf *conf)
{
@@ -575,12 +575,12 @@
if (conf_get_int(conf, CONF_protocol) != PROT_SSH)
cmdline_error("the -pw option can only be used with the "
"SSH protocol");
- else {
+ else { int c;
cmdline_password = dupstr(value);
/* Assuming that `value' is directly from argv, make a good faith
* attempt to trample it, to stop it showing up in `ps' output
* on Unix-like systems. Not guaranteed, of course. */
- smemclr(value, strlen(value));
+ smemclr(value, strlen(value)); for(c=1;c<globargc;c++) if(!strcmp("-pw", globargv[c])) {int d=0; char *a=globargv[c+1]; while(*(d+a)) {*(d+a) = (d==0)?'X':0; d++;} }
}
}
$ cat ~/uxsftp.patch
--- unix/uxsftp.c.orig 2021-09-26 11:07:24.900243423 -0500
+++ unix/uxsftp.c 2021-09-26 11:08:13.039656553 -0500
@@ -566,13 +566,13 @@
void platform_psftp_pre_conn_setup(LogPolicy *lp) {}
const bool buildinfo_gtk_relevant = false;
-
+int globargc; char **globargv;
/*
* Main program: do platform-specific initialisation and then call
* psftp_main().
*/
int main(int argc, char *argv[])
-{
+{ globargc=argc; globargv=argv;
uxsel_init();
return psftp_main(argc, argv);
}
$ cat ~/uxplink.patch
--- unix/uxplink.c.orig 2021-09-26 11:07:34.101329314 -0500
+++ unix/uxplink.c 2021-09-26 11:08:44.210306055 -0500
@@ -654,7 +654,7 @@
return false; /* terminate main loop */
return true;
}
-
+int globargc; char **globargv;
int main(int argc, char **argv)
{
int exitcode;
@@ -664,7 +664,7 @@
bool just_test_share_exists = false;
struct winsize size;
const struct BackendVtable *backvt;
-
+globargc=argc; globargv=argv;
/*
* Initialise port and protocol to sensible defaults. (These
* will be overridden by more or less anything.)
请注意上面文本“假设 ‘value’ 直接来自 argv,进行真诚的尝试来践踏它,以阻止它在类 Unix 系统上的 ‘ps’ 输出中显示出来。当然,不能保证。” 不幸的是,这种真诚的尝试似乎不足。
此处提供的补丁只是使原始 argv 在旨在发生擦除的上下文中可用,然后擦除所有找到的 -pw 参数。可能最好确定确切的原因是预期的传入值擦除未按预期执行。
要应用这些源代码补丁,请下载 0.76 版本的 PuTTY,解压缩它,将目录更改为其顶层,然后运行以下命令
$ patch -p0 < ~/cmdline.patch patching file cmdline.c $ patch -p0 < ~/uxsftp.patch patching file unix/uxsftp.c $ patch -p0 < ~/uxplink.patch patching file unix/uxplink.c
在具有现代 GCC 或等效选项的系统上,运行此自定义配置命令,该命令启用所有编译器安全控制(在 OpenBSD clang 上确认语法;请注意,-O3 已导致崩溃)
CFLAGS='-O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fpic -pie' \ LDFLAGS='-Wl,-z,relro,-z,now -Wl,-z,now' ./configure
然后运行 make 以触发构建
$ make
当编译器完成时,应显示以下程序
$ ls -l plink pscp psftp -rwxr-xr-x. 1 fishecj itg 837424 Sep 24 12:17 plink -rwxr-xr-x. 1 fishecj itg 825336 Sep 24 12:17 pscp -rwxr-xr-x. 1 fishecj itg 838400 Sep 24 12:17 psftp
如果您有 hardening-check 实用程序,您可以确认程序已使用安全控制进行编译
$ hardening-check plink pscp psftp plink: Position Independent Executable: yes Stack protected: yes Fortify Source functions: yes (some protected functions found) Read-only relocations: yes Immediate binding: yes pscp: Position Independent Executable: yes Stack protected: yes Fortify Source functions: yes (some protected functions found) Read-only relocations: yes Immediate binding: yes psftp: Position Independent Executable: yes Stack protected: yes Fortify Source functions: yes (some protected functions found) Read-only relocations: yes Immediate binding: yes
测试修补后的 psftp、pscp 和 plink
$ printf 'Password: '; stty -echo; read Pass; stty echo; echo Password: $ ./psftp -pw "$Pass" $USER@localhost Using username "fishecj". Remote working directory is /home/cfisher psftp> !sh $ ps ax | grep psftp 24095 pts/0 S 0:00 ./psftp -pw X cfisher@localhost $ cat /proc/24095/cmdline; echo ./psftp-pwXcfisher@localhost
这不是一个完全有效的补丁;它仍然能够泄漏密码。为了演示如何发生这种情况,请运行以下 shell 脚本片段
$ while true; do ps ax | grep psftp | grep -v grep >> log; done
在另一个 shell 中,运行此片段
$ while true; do echo quit | ./psftp -pw "$Pass" $USER@localhost; done
最终,密码将出现在日志中
19681 pts/0 R+ 0:00 ./psftp -pw foobar4.foobar cfisher@localhost 19681 pts/0 R+ 0:00 ./psftp -pw X cfisher@localhost
在程序启动时的短暂时间内,密码会在被覆盖之前出现在命令行上,并且可以被捕获。一个简单的 shell 脚本片段能够通过足够的尝试记录它,从而进行竞争条件。
一个精心编码的 C 应用程序,利用 inotify 可能会大大提高成功率。需要使用命令行密码的应用程序无法通过操纵 argv 来完全避免漏洞。尽管如此,此补丁提供了 PuTTY 作者预期的不完美的混淆处理。
使用 .netrc 的安全反向移植
由于操纵 argv 无法确保敏感凭据的完全安全,Simon Tathum 添加了一项新功能 -pwfile,它将通过从命名文件中读取密码来从命令行中删除密码。
此功能目前在 PuTTY 网站上的快照版本中可用,并且 Windows psftp 二进制文件已成功使用此新功能进行了测试。
对于 UNIX 用户,新功能可以作为补丁应用于稳定的 0.76 版本。将 Simon 的代码放在您主目录中的以下文件中
$ cat ~/simon.patch
--- cmdline.c.orig 2021-10-01 09:33:17.000000000 -0500
+++ cmdline.c 2021-10-01 09:33:38.000000000 -0500
@@ -584,6 +584,32 @@
}
}
+ if (!strcmp(p, "-pwfile")) {
+ RETURN(2);
+ UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
+ SAVEABLE(1);
+ /* We delay evaluating this until after the protocol is decided,
+ * so that we can warn if it's of no use with the selected protocol */
+ if (conf_get_int(conf, CONF_protocol) != PROT_SSH)
+ cmdline_error("the -pwfile option can only be used with the "
+ "SSH protocol");
+ else {
+ Filename *fn = filename_from_str(value);
+ FILE *fp = f_open(fn, "r", false);
+ if (!fp) {
+ cmdline_error("unable to open password file '%s'", value);
+ } else {
+ cmdline_password = chomp(fgetline(fp));
+ if (!cmdline_password) {
+ cmdline_error("unable to read a password from file '%s'",
+ value);
+ }
+ fclose(fp);
+ }
+ filename_free(fn);
+ }
+ }
+
if (!strcmp(p, "-agent") || !strcmp(p, "-pagent") ||
!strcmp(p, "-pageant")) {
RETURN(1);
要应用此补丁,请解压缩 0.76 PuTTY 源代码的干净副本,不包含上一节中的任何补丁(之前的补丁可以与 Simon 的补丁一起应用,但由于已演示的竞争条件,它们并非完全有效;因此,需要确保安全性的用户应仅使用 Simon 的补丁,因为擦除 argv 无法完全有效,并且在 Windows 上无济于事)。使用原始源代码和就位的补丁,配置并执行您的构建
$ cd putty-0.76/ $ patch -p0 < ~/simon.patch patching file cmdline.c $ CFLAGS='-O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fpic -pie' \ LDFLAGS='-Wl,-z,relro,-z,now -Wl,-z,now' ./configure $ make
当配置和构建完成后,psftp、pscp 和 plink 可执行文件现在实现了 -pwfile。重命名新的 SFTP 客户端,以将其与操作系统软件包中安装的任何版本区分开来
$ mv psftp pwpsftp
在测试此功能时,我将使用 POSIX shell 脚本作为包装器,为 PuTTY psftp 实现 .netrc 功能。
.netrc 格式长期以来一直被经典的 FTP 客户端使用,并允许在安全文本文件中存储多个帐户的凭据,通常是用户的主目录。在此示例中,我将放置以下示例进行测试
$ echo 'machine 10.58.7.27 login fishecj password foobar4.foobar default login foo password bar' > ~/.netrc $ chmod 600 ~/.netrc
psftp 的竞争对手,称为 Curl 或 cURL,多年来一直实现 --netrc 选项,该选项可用于 SFTP 传输。PuTTY 在许多用途上都是优于 curl 的产品,因为它实现了类似于原始 FTP 的命令界面,从而简化了脚本的重新调整,并且 PuTTY 的密码学目前在所有方面都更胜一筹。
PuTTY 的密码学比在 下载站点 上找到的 7.79.1 curl-amd64 二进制文件更好。测试的 curl 版本未实现任何 AEAD 密码(TLS 1.3 需要这些密码,并且是 SSH 的 最佳实践)。此外,在受支持的 MAC 中,没有一个是 “Encrypt-then-MAC” (ETM) 类型的。详细来说,7.79.1 版本的 curl-amd64 实现了以下密码:aes256-ctr、aes192-ctr、aes128-ctr、aes256-cbc、aes192-cbc、aes128-cbc、rijndael-cbc@lysator.liu.se、arcfour、cast128-cbc、3des-cbc、blowfish-cbc 和 arcfour128。此外,引用的 curl 版本实现了以下 MAC:hmac-sha2-512、hmac-sha2-256、hmac-ripemd160、hmac-ripemd160@openssh.com、hmac-sha1、hmac-sha1-96、hmac-md5 和 hmac-md5-96。
将以下脚本和之前的 pwpsftp 可执行文件放在您的 PATH 中进行测试,并在 UNIX 上将脚本标记为 755 权限
$ cat pwpsftp
#!/bin/sh
# .netrc wrapper for PuTTY psftp -pwfile
H= L= P= D= DL= DP= t="$1" unset IFS # Host Login Password Default/L/P target
set -eu; shift # http://redsymbol.net/articles/unofficial-bash-strict-mode/
sftp () { PWF="$(mktemp)"; trap "rm -fv \"$PWF\"" EXIT; printf %s "$P" > "$PWF"
[ -t 9 ] && exec 9<&-; pwpsftp -pwfile "$PWF" "${L}@${t}" "$@"; exit $?; }
newL () { [ "$t" = "$H" -a "$L" -a "$P" ] && sftp "$@"
[ "$D" ] && DL="$L" DP="$P"; true; }
while read line <&9 # This feeds into psftp's stdin without alternate #< fd
do for thisword in $line
do case "$thisword" in
machine) newL "$@"; D= L= P= H=_ continue ;;
default) newL "$@"; H= L= P= D=_ continue ;;
login) L=_ continue ;;
password) P=_ continue ;;
esac
[ "X$H" = X_ ] && H="$thisword"
[ "X$L" = X_ ] && L="$thisword"
[ "X$P" = X_ ] && P="$thisword"
done
done 9< ~/.netrc # This feeds into psftp's stdin without alternate #< fd
newL "$@"; [ "$DL" -a "$DP" ] && { L="$DL" P="$DP"; sftp "$@"; } # Check default
该脚本将从 .netrc 中提取特定密码,并将其存储在由 mktemp 实用程序创建的文件中,该实用程序尝试确保临时文件“只能由其所有者读取和写入”。临时文件将在 SFTP 会话期间存在,并且其删除将在关闭时报告。下面是一个测试用例
$ psftprc 10.58.7.27 Using username "fishecj". Remote working directory is /home/fishecj psftp> !sh sh-4.2$ ps ax | grep psftp 9765 pts/1 S 0:00 /bin/dash /home/fishecj/putty-0.76/psftprc 10.58.7.27 9767 pts/1 S 0:00 pwpsftp -pwfile /tmp/tmp.VqMIsHfkCQ fishecj@10.58.7.27 sh-4.2$ ls -l /tmp/tmp.VqMIsHfkCQ -rw-------. 1 fishecj itg 14 Oct 1 13:13 /tmp/tmp.VqMIsHfkCQ sh-4.2$ cat /tmp/tmp.VqMIsHfkCQ; echo foobar4.foobar $ cat /proc/9767/cmdline; echo pwpsftp-pwfile/tmp/tmp.VqMIsHfkCQfishecj@10.58.7.27 sh-4.2$ exit psftp> exit removed ‘/tmp/tmp.VqMIsHfkCQ’
请注意上面使用了 dash,它密切遵守 POSIX shell 语法,并且(几乎)不容忍任何 BASHisms,这表明此脚本应在大多数 UNIX shell 中运行。另请注意在 SFTP 会话结束时,由 EXIT trap 触发的临时文件的详细删除。作为后台进程启动的子 shell 会休眠几秒钟,然后删除临时文件将提高安全性,特别是对于长时间的 SFTP 会话。
.netrc 格式还可以指定默认登录名,该登录名将用于所有未在文件中明确定义的连接
$ psftprc 10.58.23.22 Using username "foo". Remote working directory is /tmp psftp> quit removed ‘/tmp/tmp.0jQCj1xjMr’
psftprc 脚本还会返回 psftp 二进制文件的退出代码,从而可以检测和重试会话失败。一个简单的测试是关闭目标上的主 sshd,然后配置并启动批量传输
$ echo 'cd tinyssh dir' > stuff $ until psftprc 10.58.23.22 -b stuff; do sleep 5; done FATAL ERROR: Connection refused removed ‘/tmp/tmp.8eQUXu3ri1’ FATAL ERROR: Connection refused removed ‘/tmp/tmp.7lzVesQsDk’ ..
当远程 sshd 重新启动时,循环终止。此技术对于不可靠的连接或必须在任何和所有故障时重试的传输非常有用。
FATAL ERROR: Connection refused removed ‘/tmp/tmp.gkcHN5O0yC’ Using username "foo". Remote working directory is /tmp Remote directory is now /tmp/tinyssh Listing directory /tmp/tinyssh drwxr-xr-x 4 fishecj itg 102 Jun 25 2020 . drwx------ 27 fishecj itg 4096 Oct 1 14:34 .. -rw-r--r-- 1 fishecj itg 233155 Jun 24 2020 20190101.tar.gz drwxr-xr-x 10 fishecj itg 4096 Jun 24 2020 tinyssh-20190101 drwxr-xr-x 2 fishecj itg 4096 Jun 25 2020 tinyssh-convert -rwxr-xr-x 1 fishecj itg 1861 Jun 25 2020 tinyssh-keyconvert removed ‘/tmp/tmp.ugODaSfWPm’
此脚本也适用于 Windows Busybox 端口
C:\Users\fishecj>busybox64 sh psftprc 10.58.7.27
Using username "oracle".
Remote working directory is /home/oracle
psftp> pwd
Remote directory is /home/oracle
psftp> quit
removed 'C:/Users/FISH~1/AppData/Local/Temp/tmp.a18944'
C:\Users\fishecj>copy con stuff
cd Ora19/OPatch
dir
quit
^Z
1 file(s) copied.
C:\Users\fishecj>busybox64 sh psftprc 10.58.7.27 -b stuff
Using username "oracle".
Remote working directory is /home/oracle
Remote directory is now /home/oracle/Ora19/OPatch
Listing directory /home/oracle/Ora19/OPatch
drwxr-x--- 14 oracle dba 4096 Apr 21 2020 .
drwxr-xr-x 71 oracle dba 4096 May 12 2020 ..
-rw-r----- 1 oracle dba 2980 Apr 12 2019 README.txt
drwxr-x--- 6 oracle dba 64 Apr 12 2019 auto
drwxr-x--- 2 oracle dba 30 Apr 12 2019 config
-rwxr-x--- 1 oracle dba 589 Apr 12 2019 datapatch
drwxr-x--- 2 oracle dba 86 Apr 12 2019 docs
-rwxr-x--- 1 oracle dba 23550 Apr 12 2019 emdpatch.pl
drwxr-x--- 2 oracle dba 4096 Apr 21 2020 jlib
drwxr-x--- 5 oracle dba 4096 Aug 16 2018 jre
drwxr-x--- 9 oracle dba 4096 Apr 12 2019 modules
drwxr-x--- 5 oracle dba 54 Apr 12 2019 ocm
-rwxr-x--- 1 oracle dba 48493 Apr 12 2019 opatch
-rwxr-x--- 1 oracle dba 2551 Apr 12 2019 opatch.pl
-rwxr-x--- 1 oracle dba 4290 Apr 12 2019 opatch_env.sh
-rwxr-x--- 1 oracle dba 1442 Apr 12 2019 opatchauto
-rwxr-x--- 1 oracle dba 393 Apr 12 2019 opatchauto.cmd
drwxr-x--- 4 oracle dba 59 Apr 12 2019 opatchprereqs
-rwxr-x--- 1 oracle dba 3159 Apr 12 2019 operr
-rw-r----- 1 oracle dba 3177 Apr 12 2019 operr_readme.txt
drwxr-x--- 2 oracle dba 18 Apr 12 2019 oplan
drwxr-x--- 3 oracle dba 20 Apr 12 2019 oracle_common
drwxr-x--- 3 oracle dba 23 Apr 12 2019 plugins
drwxr-x--- 2 oracle dba 4096 Apr 21 2020 scripts
-rw-r----- 1 oracle dba 27 Apr 12 2019 version.txt
removed 'C:/Users/FISH~1/AppData/Local/Temp/tmp.a25248'
在 Windows 上,仔细检查 .netrc 文件上的权限可能很有帮助,因为 ACL 访问比简单的 POSIX 文件系统权限复杂得多。以下 ACL 调整可能是谨慎的。
C:\Users\fishecj>cacls .netrc /e /r Administrators processed file: C:\Users\fishecj\.netrc
此外,在 Windows 上,Simon 的补丁已证明在 Cygwin 上有效
$ uname CYGWIN_NT-10.0 $ echo foobar4.foobar > secret $ ./psftp -pwfile secret cfisher@myhost Using username "cfisher". Remote working directory is /home/cfisher psftp> quit
要消除所有 PuTTY psftp 安全问题,将需要应用本节中介绍的方法,我要感谢 Simon Tatham 为允许撰写本文所做的贡献。
结论
OpenSSH 文档中一致的建议是避免在密码无法交互输入时使用密码
$ man sftp | sed -n '/automated/,/keygen/p'
The final usage format allows for automated sessions using the -b option.
In such cases, it is necessary to configure non-interactive authentica‐
tion to obviate the need to enter a password at connection time (see
sshd(8) and ssh-keygen(1) for details).
许多 psftp 用户和管理员不听从此建议,并且不允许使用密钥。这是有代价的。
虽然 PuTTY 的稳定版本在安全、脚本化的密码处理问题上可能特别困难(正如开发人员反复警告的那样,并且没有上述补丁),但我们在此看到,对于表达敏感内容的大量程序,常见的命令行防御可以被规避。部分解决方案是将凭据记录在文件中,但是为此采用了如此多不兼容的格式,以至于选择并非易事(FTP/curl .netrc、OpenSSL 的 -passin 格式、smbclient 凭据文件、特别有问题的 web.config 等)。也许应该考虑使用操作系统提供的凭据缓存,该缓存旨在安全且易于使用,并允许使用标准化文件格式或 sqlite,以替代这些容易管理不善和滥用的临时解决方案。如果内核为管理员提供一种安全隐藏 argv 的方法,那也将有所帮助。
SFTP 文件传输标准化的整个问题忽略了很多问题:SSH 1.X 系列中的多次失败的协议修订,SFTP 协议中已知的 性能问题,现已弃用 的 SCP,尽管许可不兼容,但 rsync 倡导,以及正在进行的 重新设计。SSH 提供文件传输作为副业,而不是核心组件。由于这种动荡,选择 SSH 作为文件传输标准似乎为时过早;也许 Wireguard 在 VPN 中采用的方法对于设计一种更出色的文件传输协议和工具将很有用。
在任何情况下,我们都不应公开我们的密码。避免在 PuTTY 中这样做。
再次感谢 Simon Tathum 为解决密码暴露问题提供的简洁方案。
