Unix的TTY机制的明文输入密码的安全问题

本文探讨了在Unix系统中,通过SSH连接执行命令时,如何因TTY机制导致密码明文显示的问题。当使用getpass函数在没有TTY的环境中获取密码时,密码可能会在网络中明文传输。分析了问题的原因,即stdin被重定向至网络套接字,使得getpass无法屏蔽回显。建议避免依赖getpass获取密码,而是采用自定义方法或回调程序确保密码安全性。
问题的提出
网上一位网友提出了如下的问题:
代码:
ssh root@a.b.c.cn mysqldump abcd emp > emptoeee -u root -p
root@a.b.c.cn password:
Enter password:

第一个系统密码是看不见的,而第二个mysql的密码竟明文显示了...
第一个密码显然是ssh密码验证所需要的密码,第二个密码应该是远程mysqldump所需要的密码,但是为什么第二个密码就显示明文的了呢?
问题的分析
在Unix编程中,获取密码一般使用getpass(3)函数。他的定义是这样的:
代码:
#include <unistd.h>

char *getpass( const char * prompt );
其中prompt就是输入密码前面的提示语如“PassWord:”之类类的短语,在getpass的手册册页中说:
代码:
For glibc2, if /dev/tty cannot be opened, the prompt is written to
stderr and the password is read from stdin. There is no limit on the
length of the password. Line editing is not disabled.
也就是说,通常情况下getpass的都是使用stdin来获取密码的,而且《Advanced Unix Programming》一书中我们知道,一般stdin,stdout和stderr是有TTY信息的。在这种情况下,glibc的getpass使用 如下的方法:
代码:
if (__tcgetattr (fileno (in), &t) == 0)
{
/* Save the old one. */
s = t;
/* Tricky, tricky. */
t.c_lflag &= ~(ECHO|ISIG);
tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0);
}

在stdin具有终端属性的时候,这段代码会成功的屏蔽掉终端的回显功能。我们的输入就不会被显示出来。
但是,当我们使用netcat等工具,使用管道从网络另一端转发输入输出信息时,远端程序一般会将程序的stdin和stdout,stderr重定向到网络。此时,stdin和stdout等的文件描述符已经被替换:
代码:
/* duplicate the socket for the child program */
dup2(ncsock->fd, STDIN_FILENO);
close(ncsock->fd);
dup2(STDIN_FILENO, STDOUT_FILENO);
dup2(STDIN_FILENO, STDERR_FILENO);
上面是netcat的代码,此时的stdin等的描述符已经是一个套接字。getpass的终端操作无法进行,输入的密码会直接的显示在远程的终端上。对于一次性执行的远程ssh命令,同样仅仅是stdin等被赋值为网络套接字。而且,从ssh的输出来看:
代码:
[gnap@osiris ~]$ ssh ftp bash -i
[gnap@ftp ~]$ su
standard in must be a tty
[gnap@ftp ~]$ exit
exit
[gnap@osiris ~]$
远程的bash没有提示"no job control",估计stderr没有被重定向。所以,建议不要使用这种方式执行需要操作终端的程序。
解决方法:
出于安全的考虑,建议尽量避免使用glibc的getpass来获取密码。建议自己实现密码的获取,并且在无法获取tty是提示并退出程序(su)或者编 写callback程序向X索取输入密码(ssh)。另外,作为安全的建议,任何调用getpass的程序都建议放到拥有终端的环境中去执行,以避免密码 明文显示的安全隐患。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值