原blog细节分析
Wediscovered a vulnerability (a signal handler race condition) inOpenSSH'sserver (sshd): if a client does not authenticate withinLoginGraceTimeseconds (120 by default, 600 in old OpenSSH versions),thensshd's SIGALRM handler is called asynchronously, but this signalhandlercalls various functions that are not async-signal-safe (forexample,syslog()). This race condition affects sshd in its defaultconfiguration.
我们发现了一个漏洞(信号处理程序竞争条件)OpenSSH的服务器 (sshd):如果客户端未在LoginGraceTime秒(默认为 120 秒,旧版 OpenSSH 为600 秒)进行身份验证,那么 sshd 的 SIGALRM 处理程序被异步调用,但是这个信号处理程序调用各种非异步信号安全的函数(例如例如,syslog())。此竞争条件会影响 sshd 的默认配置。
Oninvestigation, we realized that this vulnerability is in fact aregressionof CVE-2006-5051 ("Signal handler race condition in OpenSSHbefore4.4 allows remote attackers to cause a denial of service (crash),andpossibly execute arbitrary code"), which was reported in 2006 byMarkDowd.
经过调查,我们发现该漏洞实际上是 CVE-2006-5051(“OpenSSH 4.4 之前的版本中的信号处理程序竞争条件允许远程攻击者造成拒绝服务(崩溃))的回归,该漏洞于 2006 年被报告
Thisregression was introduced in October 2020 (OpenSSH 8.5p1) by commit752250c("revised log infrastructure for OpenSSH"), which accidentallyremovedan "#ifdef DO_LOG_SAFE_IN_SIGHAND" from sigdie(), a functionthatis directly called by sshd's SIGALRM handler.
此回归是在 2020 年 10 月(OpenSSH8.5p1)通过提交 752250c(“修订的 OpenSSH 日志基础结构”)引入的,它意外地从 sigdie() 中删除了“#ifdefDO_LOG_SAFE_IN_SIGHAND”,该函数由 sshd 的 SIGALRM 处理程序直接调用。
Inother words: -OpenSSH < 4.4p1 is vulnerable to this signal handler race condition, if not backport-patched againstCVE-2006-5051, or not patched against CVE-2008-4109, which was an incorrect fix forCVE-2006-5051;
换句话说:- 如果没有针对 CVE-2006-5051 进行反向移植修补,或者没有针对CVE-2008-4109进行修补(这是对 CVE-2006-5051 的错误修复),OpenSSH < 4.4p1 容易受到此信号处理程序竞争条件的影响;
-4.4p1 <= OpenSSH < 8.5p1 is not vulnerable to this signal handler race condition (because the "#ifdefDO_LOG_SAFE_IN_SIGHAND" that was added to sigdie() by the patch for CVE-2006-5051transformed this unsafe function into a safe _exit(1) call);
-4.4p1 <= OpenSSH < 8.5p1 不易受此信号处理程序竞争条件的影响(因为 CVE-2006-5051补丁 “#ifdef DO_LOG_SAFE_IN_SIGHAND”添加到 sigdie() 将此不安全的函数转换为安全的_exit(1) 调用);
-8.5p1 <= OpenSSH < 9.8p1 is vulnerable again to this signal handler race condition (because the "#ifdefDO_LOG_SAFE_IN_SIGHAND" was accidentally removed from sigdie()).
- 8.5p1 <= OpenSSH < 9.8p1 再次易受此信号处理程序竞争条件的影响(因为“#ifdef DO_LOG_SAFE_IN_SIGHAND”被意外从 sigdie()中删除)。
/*
* Try to kill any processes that we have spawned, E.g. authorized
* keys command helpers.
*/
=>终止所有的生成的进程,例如,已授权的关键字命令助手
/*XXX pre-format ipaddr/port so we don't need to access active_state */
/*Log error and exit. */
=>XXX 预格式化ipaddr/port,这样我们就不需要访问 active_state
记录错误并退出
继续向上看调用关系
在文件sshd.c
在 main 中,SIGALRM信号触发 了上一张图的 prace_alarm_handler
该信号处理的描述:
[C] 纯文本查看复制代码
/*
* We don't want to listen forever unless the other side
* successfully authenticates itself. So we set up an alarm which is
* cleared after successful authentication. A limit of zero
* indicates no limit. Note that we don't set the alarm in debugging
* mode; it is just annoying to have the server exit just when you
* are about to discover the bug.
*/
max_startups_rate 最大启动速率
max_startups_begin 最大启动初始值
max_startups 最大启动次数
* returns1 if connection should be dropped, 0 otherwise.
* droppingstarts at connection #max_startups_begin with a probability
* of(max_startups_rate/100). the probability increases linearly until
* allconnections are dropped for startups > max_startups返回值1:连接应断开,0连接不断开