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 ✅ 存在漏洞
前置条件
- 从源代码构建curl
- 下载附带的验证脚本:poc_smtp_crlf_injection.sh
操作步骤
- 使脚本可执行:
|
|
- 运行验证脚本:
|
|
脚本将:
- 启动记录所有接收命令的SMTP服务器
- 使用CRLF注入的邮箱地址执行curl
- 显示清晰的对比结果
- 高亮显示注入的命令
预期与实际行为
预期行为: curl应拒绝包含控制字符的邮箱地址,并返回类似"邮箱地址中包含无效字符"或"不允许控制字符"的错误。
实际行为: curl接受CRLF字符并将其作为SMTP命令的一部分发送,导致协议级命令注入:
|
|
MAIL FROM命令被分成两个独立行,其中"RCPT TO:attacker@evil.com"作为单独的SMTP命令被注入。邮件现在同时发送给合法收件人和攻击者地址。
漏洞证据
代码分析
文件:lib/smtp.c,第838-846行
|
|
文件:lib/smtp.c,第1875-1921行(smtp_parse_address函数)
- 函数执行基本解析(去除<>,查找@)
- 没有对控制字符(CR、LF、NUL)进行验证
- 字符串直接传递给命令构造
对比验证
curl已经在类似上下文中拒绝控制字符。从lib/cookie.c,第436-446行:
|
|
此函数明确拒绝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开发团队认为这是重复报告,并引用了之前的三个相关报告。根据项目透明度政策,所有报告都被公开披露。