注入电子邮件
许多应用程序拥有一项允许用户通过应用程序提交消息的功能。例如,向支持人员报告问题或提供关于Web点反馈。这项功能一般通过邮件(或SMTP)服务器执行。通常,用户提交的输入被插入到邮件服务器处理的SMTP会话中。如果攻击者能够提交未被过滤或净化的专门设计的输入,就可以在这个会话中注入任意SMTP命令。
多数时候,应用程序允许用户指定消息的内容和自己的电子邮件地址(插入到生成电子邮件的From字段),还可以指定消息的主题和其他细节。能够控制的任何字段都易于受到SMTP注入。
SMTP注入漏洞经常被垃圾邮件发送者利用,他们扫描因特网查找易受攻击的邮件表单,并使用它们生成大量垃圾邮件。
操纵电子邮件标头
假设有下面的邮件:
1 | To: admin@wahh-app.com |
PHP **mail()**命令使用additional_headers参数为消息设定发件人地址。这个参数还可用于指定其他标头,包括Cc和Bcc,并用换行符分割每个被请求的标头。因此攻击者可以通过在From字段中注入这其中的某个标头,将邮件发送给任意收件人。
1 | To: admin@wahh-app.com%0ABC从:all@wahh-othercompany.com |
这会导致**mail()**命令生成以下邮件:
1 | To: admin@wahh-app.com |
SMTP命令注入
在其他情况下,应用程序可能会执行SMTP会话,或将用户提交的输入传送一个以不同的组件以完成这一任务。这时,我们就可以直接在这个会话中注入任意SMTP命令,完全控制由应用程序生成的消息。
例如,以一个使用以下请求提交站点反馈的应用程序为例:
1 | POST feedback.php HTTP/1.1 |
应用程序会使用以下命令开始一个SMTP会话:
1 | MAIL FROM: daf@wahh-mail.com |
SMTP 客户端发出DATA命令后,应用程序送出电子邮件消息的内容,包括消息头和主体,然后发送一个点字符(.)。这告诉服务器消息已发送完毕,客户端可以发出其他SMTP命令,发送其他消息。
这时,攻击者可以在任何受控的电子邮件字段中注入任意SMTP命令。例如,他可以尝试注入Subject字段,如下所示:
1 | POST feedback.php HTTP/1.1 |
如果应用程序易受攻击,那么建立以下SMTP会话,它生成两个的电子邮件消息,其中第二个完全由攻击者控制:
1 | MAIL FROM: daf@wahh-mail.com |
查找SMTP注入漏洞
为了有效探查应用程序的邮件功能,需要测试每一个提交给电子邮件有关的功能的参数,甚至哪些最初可能与生成的消息无关的参数。
应当测试每一种攻击,并在每个测试中使用Windows和UNIX形式的换行符。
- 应当发轮流提交西面的每个测试字符串作为每一个参数,在相关位置插入电子邮件地址。
- 留意应用程序返回的任何错误消息。如果这些错误与电子邮件功能中的任何问题有关,确定是否需要对输入进行调整,以利用漏洞。
- 应用程序的响应可能并不会以任何形式表示一个漏洞存在或被成功利用。应该监控指定的电子邮件地址,看是否收到任何电子邮件。
- 仔细检查生成相关请求的HTML表单。它们可能提供与服务器端使用的软件有关的线索。其中可能包含一个用于指定电子邮件收件人地址的隐藏或禁用字段,可以直接对其进行修改。
防止SMTP注入
如果对提交电子邮件功能或SMTP会话使用的任何用户提交的数据进行严格的确认检查,就可以防止SMTP注入漏洞。因此,应根据其用途对每项数据进行尽可能严格的确认。
- 应根据一个适当的正则表达式检查电子邮件地址(当然应拒绝所有换行符)
- 消息主体不得包含任何换行符,并应实施适当的长度限制
- 如果消息内容被一个SMTP会话直接使用,那么应禁止使用仅包含一个.字符的消息行。