Unix的TTY机制的明文输入密码的安全问题
2006-01-21 12:37
357 查看
问题的提出
网上一位网友提出了如下的问题:
代码:
第一个系统密码是看不见的,而第二个mysql的密码竟明文显示了...
第一个密码显然是ssh密码验证所需要的密码,第二个密码应该是远程mysqldump所需要的密码,但是为什么第二个密码就显示明文的了呢?
问题的分析
在Unix编程中,获取密码一般使用getpass(3)函数。他的定义是这样的:
代码:
其中prompt就是输入密码前面的提示语如“PassWord:”之类类的短语,在getpass的手册册页中说:
代码:
也就是说,通常情况下getpass的都是使用stdin来获取密码的,而且《Advanced Unix Programming》一书中我们知道,一般stdin,stdout和stderr是有TTY信息的。在这种情况下,glibc的getpass使用 如下的方法:
代码:
在stdin具有终端属性的时候,这段代码会成功的屏蔽掉终端的回显功能。我们的输入就不会被显示出来。
但是,当我们使用netcat等工具,使用管道从网络另一端转发输入输出信息时,远端程序一般会将程序的stdin和stdout,stderr重定向到网络。此时,stdin和stdout等的文件描述符已经被替换:
代码:
上面是netcat的代码,此时的stdin等的描述符已经是一个套接字。getpass的终端操作无法进行,输入的密码会直接的显示在远程的终端上。对于一次性执行的远程ssh命令,同样仅仅是stdin等被赋值为网络套接字。而且,从ssh的输出来看:
代码:
远程的bash没有提示"no job control",估计stderr没有被重定向。所以,建议不要使用这种方式执行需要操作终端的程序。
解决方法:
出于安全的考虑,建议尽量避免使用glibc的getpass来获取密码。建议自己实现密码的获取,并且在无法获取tty是提示并退出程序(su)或者编 写callback程序向X索取输入密码(ssh)。另外,作为安全的建议,任何调用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的程序都建议放到拥有终端的环境中去执行,以避免密码 明文显示的安全隐患。
相关文章推荐
- CreateUserWizard输入密码和设置安全问题
- ztCreateUserWizard输入密码和设置安全问题
- CreateUserWizard输入密码和设置安全问题
- windows连接代理服务器,总是弹出输入用户名和密码的框的问题
- 网站一打开就显示windows安全,输入用户名和密码
- 看好你的门-确保验证机制的安全(5)-防止滥用密码修改和密码找回功能
- 安卓 密码输入的明文和密文切换
- 微信中关闭网页输入内容时的安全提示 [干掉 “防盗号或诈骗,请不要输入QQ密码”]
- SVN 每次操作都需要重输入用户名密码问题
- 127.0.0.1无法访问,需要输入用户名和密码的问题
- 重启机器解决SSL都要输入密码问题
- 就mysql command line client刚输入密码立马闪一下退出问题的解决方案
- 怎样实现 Windows 7/Vista 开机自动登录而不用输入密码的问题
- shell脚本中针对sudo等密码输入的问题解决方案
- Android权限机制带来的一些安全问题介绍
- 如何解决连接共享打印机时需要输入密码的问题
- Linux/Unix编程中的线程安全问题
- 解决rman备份脚本中密码明文的问题--wallet
- weblogic11g 启动时提示输入密码的问题
- 程序升级触发阿里云自身安全机制导致的莫名问题