许多应用程序拥有一项允许用户通过应用程序提交消息的功能。例如,向支持人员报告问题或提供关于Web站点的反馈。这项功能一般通过邮件(或SMTP)服务器执行。通常,用户提交的输入被插入到邮件服务器处理的SMTP会话中。如果攻击者能够提交未被过滤或净化的专门设计的输入,就可以在这个会话中注入任意SMTP命令。
多数时候,应用程序允许用户指定消息的内容和自己的电子邮件地址(插入到生成电子邮件的From字段中),还可以指定消息的主题和其他细节。能够控制的任何字段都易于受到SMTP注入。
SMTP注入漏洞经常被垃圾邮件发送者利用,他们扫描因特网查找易受攻击的邮件表单,并使用它们生成大量垃圾电子邮件。
以图10-6所示的表单为例,它允许用户发送关于应用程序的反馈。
图10-6 一个典型的站点反馈表单
在该表单中,用户可指定发件人(From)地址和邮件的内容。应用程序将这个输入传送给 PHP mail()命令,由它建立邮件并与它配置的邮件服务器进行必要的SMTP会话。生成的邮件如下:
PHP mail()命令使用additional_headers参数为消息设定发件人地址。这个参数还可用于指定其他标头,包括Cc和Bcc,并用换行符分隔每个被请求的标头。因此,攻击者可以通过在From字段中注入这其中某个标头,将邮件发送给任意收件人,如图10-7所示。
图10-7 电子邮件标头注入攻击
这会导致mail()命令生成以下邮件:
在其他情况下,应用程序可能会执行SMTP会话,或者将用户提交的输入传送给一个不同的组件以完成这一任务。这时,我们就可以直接在这个会话中注入任意SMTP命令,完全控制由应用程序生成的消息。
例如,以一个使用以下请求提交站点反馈的应用程序为例:
应用程序会使用以下命令开始一个SMTP会话:
注解
SMTP客户端发出DATA命令后,应用程序送出电子邮件消息的内容,包括消息头和主体,然后发送一个点字符(.)。这告诉服务器消息已发送完毕,客户端可以发出其他SMTP命令,发送其他消息。
这时,攻击者可以在任何受控的电子邮件字段中注入任意SMTP命令。例如,他可以尝试注入Subject字段,如下所示:
如果应用程序易受攻击,那么会建立以下SMTP会话,它生成两个不同的电子邮件消息,其中第二个完全由攻击者控制:
为了有效探查应用程序的邮件功能,需要测试每一个提交给与电子邮件有关的功能的参数,甚至那些最初可能与生成的消息无关的参数。