CVE-2020-7247: OpenSMTPD 远程命令执行漏洞通告

 

0x00 漏洞背景

2020年01月29日, OpenSMTPD 官方在 github 代码仓库提交了针对 CVE-2020-7247 漏洞的修复。

CVE-2020-7247 是 OpenSMTPD 在实现 RFC 5321 的过程中对 发件人/收件人 校验不严而导致的。

OpenSMTPD 是面向 unix操作系统(BSD, MacOS, GNU/Linux) 的一个 smtp 服务程序,遵循 RFC 5321 SMTP 协议。

OpenSMTPD 最初是为OpenBSD操作系统开发的,由于其开源的特性,进而分发到了其他 unix 平台。

OpenSMTPD 是OpenBSD项目的一部分。根据ISC许可,该软件可免费供所有人使用和重用。

360CERT判断漏洞等级为中危,影响面有限。

但由于默认配置配置下就会遭到攻击。还请服务管理/运维人员及时做好自查自检工作。

 

0x01 漏洞详情

Qualys 是提交该漏洞的团队。其分析问题出现在 smtp_mailaddr函数

smtp_mailaddr 函数负责校验发件人(MAIL FROM)和收件人(RCPT TO)邮件地址

usr.sbin/smtpd/smtp_session.c

static int
smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args,
    const char *domain)
{
    ...
 if (!valid_localpart(maddr->user) ||
     !valid_domainpart(maddr->domain)) {
  /* accept empty return-path in MAIL FROM, required for bounces */
  if (mailfrom && maddr->user[0] == '\0' && maddr->domain[0] == '\0')
return (1);

  /* no user-part, reject */
  if (maddr->user[0] == '\0')
return (0);

  /* no domain, local user */
  if (maddr->domain[0] == '\0') {
   (void)strlcpy(maddr->domain, domain,
       sizeof(maddr->domain));
   return (1);
  }
  return (0);
}

 return (1);
}

可以看到 valid_localpart 这一校验。用于验证是否进行本地分发(例如: 发送给本地用户 guest)。

如果maddr->user无效(!valid_localpart为true),且maddr->domain[0] 为空。smtp_mailaddr会添加默认域 并返回1

这就导致程序会错误的进行下去,并且开始本地投递流程。

而本地投递流程中,依靠mda_unpriv函数进行本地命令拼接并执行。

// command 组成
asprintf(&dispatcher->u.local.command,
"/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}");

// command 执行
execle("/bin/sh", "/bin/sh", "-c", mda_command, (char *)NULL, mda_environ);

因为使用 sh 进行命令执行,则如果引入了 ; 这一特殊符号的话就能额外执行命令。

上述存在问题的代码在2018年5月提交的代码中引入。许多发行版可能仍在使用旧版本的库,故不受此问题的影响。

例如,只有Debian的develop分支受此问题影响,而Debian稳定分支不受此影响。因为其使用了更为陈旧的版本。

 

0x02 修复建议

及时升级到 OpenSMTPD 6.6.2p1 版本。

下载地址如下

OpenSMTPD 6.6.2p1 portable release

 

0x03 时间线

2020-01-29 OpenSMTPD 发布安全更新

2020-01-30 360CERT发布预警

 

0x04 参考链接

  1. OpenSMTPD 6.6.2p1 released: addresses CRITICAL vulnerability
  2. qualys 分析报告
(完)