0x00:发现时间
2020年1月30日(2020年2月5日更新,其中包含其他开发详细信息)
0x01:简介
当用户输入密码时, Sudo的pwfeedback选项可用于提供视觉反馈。每次按键都会打印一个星号。添加此选项是为了响应用户对标准“ 密码;"提示如何禁用按键回显的困惑.虽然在sudo的上游版本中默认情况下未启用pwfeedback,但某些系统(例如Linux Mint和Elementary OS)的确在其默认sudoers文件中启用了它.
由于存在错误,当在sudoers文件中启用pwfeedback选项时,用户可能会触发基于堆栈的缓冲区溢出。即使未在sudoers文件中列出的用户也可以触发此错误。有没有影响,除非pwfeedback已启用.
0x02:影响范围
仅当在sudoers中启用了pwfeedback选项时,Sudo版本1.7.1到1.8.30才会受影响.最初认为它在sudo版本1.8.26至1.8.30中不可利用,但事实并非如此.
具有sudo特权的用户可以 通过运行以下命令来检查是否启用了pwfeedback:
sudo -l
如果在“Matching Defaults entries”输出中列出了pwfeedback,则sudoers配置将受到影响。在以下示例中,sudoers配置容易受到攻击:
在以下配置中就未受影响
0x03:编号
CVE-2019-18634
0x04:细节
利用漏洞不需要sudo权限,只需启用pwfeedback即可。通过将带有嵌入式终端终止字符的大量输入从而无法写入的伪终端传递给sudo,可以重现该错误.
例如,使用socat实用程序并假设终端kill字符被设置为control-U
$ socat pty,link=/tmp/pty,waitslave exec:"perl -e 'print((\"A\" x 100 . chr(0x15)) x 50)'" &
$ sudo -S -k id < /tmp/pty
Password: Segmentation fault (core dumped)
对于1.8.26之前的sudo版本,以及在具有单向管道的系统上,重现错误更简单。这里,终端终止字符被设置为NUL字符(0x00),因为sudo不是从终端读取的.由于1.8.26中引入的EOF处理的变化,这种方法在较新版本的sudo中并不有效.
$ perl -e 'print(("A" x 100 . chr(0)) x 50)' | sudo -S -k id
Password: Segmentation fault (core dumped)
造成此漏洞的原因有两个:
如果用户在尝试擦除星号行时导致sudo收到写错误,则可以触发该错误.由于在擦除该行时剩余的缓冲区长度未在写入错误时正确重置,因此堆栈上的缓冲区可能会溢出。
0x05:影响
除非在sudoers文件中启用了pwfeedback,否则不会有任何影响。
如果在sudoers中启用了pwfeedback,则堆栈溢出可能使无特权的用户升级到root帐户。由于攻击者完全控制了用于溢出缓冲区的数据,因此极有可能利用漏洞。
0x06:解决方案
如果sudoers文件启用了pwfeedback,那么通过预先挂起一个感叹号来禁用它就足以防止利用这个bug。例如:
Defaults pwfeedback
更改为
Defaults !pwfeedback
在使用vi 在sudo命令在sudoers中禁用pwfeedback之后,示例sudo -l输出变成:
该错误已在sudo 1.8.31中修复。