1. 简介


如 今,互联网的使用急剧上升,但绝大多数互联网用户没有安全知识背景。大多数的人都会使用互联网通过邮件Email的方式和他人进行通信。出于这个原因,大 多数网站允许他们的用户联系他们,向网站提供建议,报告一个问题,或者要求反馈,用户将会发送反馈给网站管理员的电子邮件。
    不
幸的是,大多数web开发人员对安全编码Code-Security没有足够的认识,其中的一些程序猿使用现成的库或框架,这些库受到许多已知的漏洞。这
些漏洞是已经公布,厂商并已经对其进行了修补,并且相应的攻击源代码poc都在互联网上可下载的,但大多数开发人员都懒得升级到最新版本。

今天我们要谈论电子邮件注射,攻击者可以使用你的邮件服务器来发送垃圾邮件。

2. 邮件注入


From Wikipedia:

电子邮件注入是一个安全漏洞,这种漏洞广泛存在于在互联网电子邮件收发应用中。这是电子邮件注射和HTTP头注射类似。和SQL注入攻击类似,这种漏洞是一类常见的的漏洞,发生在当一个编程语言是嵌入到另一个,例如MYSQL嵌入到PHP中。

当一个可以提交数据到一个Web应用程序表单被添加到一个Web页面,恶意用户可能会利用MIME格式添加额外的信息到要发送的消息中
(POST/GET),比如一个新的收件人列表或一个完全不同的消息体。因为MIME格式使用回车分隔在数据包中信息(HTTP数据包中的每一行之间都有
一个换行符,在POST和HTTP
HEADER之间有两个换行符),通过添加回车提交表单数据(使用FB的一些插件可以很容易的做到),可以允许一个简单的留言板是用来发送成千上万的消
息。同样,一个垃圾邮件发送者可以使用这种战术的恶意发送大量的匿名消息。

电子邮件注入是针对PHP内置邮件功能的一种攻击类型。它允许恶意攻击者注入任何邮件头字段,BCC、CC、主题等,它允许黑客通过注入手段从受害者的邮
件服务器发送垃圾邮件。由于这个原因,这种攻击称为电子邮件注入,或者邮件形式滥发。这个漏洞是不限于PHP。它可能会影响任何从用户UI接收消息并发送
电子邮件消息的应用程序。这种攻击的主要原因是不适当的用户输入验证或应用程序根本没有验证和过滤机制。

3. 邮件注入的攻击原理


中国古话说得好: 知其然才能知其所以然。
为了解释邮件注入的工作原理,我们必须先了解PHP Email函数的工作原理。下面是从PHP Manual中找到API解释

mail():

http://www.php.net/manual/en/function.mail.php

bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )

你可以注意到,这需要三个必填参数(”目的地、主题和消息”)和其他一些可选参数和函数返回一个布尔值。

那么让我们来看看一个带漏洞的代码来演示这个漏洞:

<?php
$to="littlehann@foxmail.com";
if (!isset($_POST["send"]))
{?>
<form method="POST" action="<?php echo $_SERVER['PHP_SELF'];?>">
From: <input type="text" name="sender">
Subject : <input type="text" name="subject">
Message :
<textarea name="message" rows="" cols="" lines=""></textarea>
<input type="submit" name="send" value="Send">
</form><?php
}
else
{
// the form has been submitted
$from=$_POST['sender'];
// send mail :
if (mail($to,$_POST['subject'],$_POST['message'],"From: $fromn"))
{
echo "Your mail has been sent successfully";
}
else
{
echo "An error has been occured !";
}
}
?>

前面的代码将用于演示目的和解释我们的攻击原理。我们将前面的代码分成三个部分:

第一部分

<?php
$to="littlehann@foxmail.com";
if (!isset($_POST["send"])){
?>

这段代码将检查表单提交或不是。用户点击提交按钮和普通访问这个页面脚本的响应将是不同的, 如果这段代码返回True(if语句中的判断最终结果为true)这意味着表单没有提交。表单将出现,等待用户输入。另一方面,如果它返 回"False",这意味着表单已经提交,所以电子邮件将被发送。

第二部分

  
<form method="POST" action="<?echo $_SERVER['PHP_SELF'];?>">
From: <input type="text" name="sender">
Subject : <input type="text" name="subject">
Message :
<textarea name="message" rows="" cols="" lines=""></textarea>
<input type="submit" name="send" value="Send">
</form>

第二部分是一个HTML表单标记,这要求用户输入。

第三部分

<?php
}else{
// the form has been submitted
$from=$_POST['sender'];
// send mail :
if (mail($to,$_POST['subject'],$_POST['message'],"From: $fromn"))
{
echo "Your mail has been sent successfully";
}
else
{
echo "An error has been occured !";
}}?>

在前面的代码中我们可以特别注意这一行 mail($to,$_POST['subject'],$_POST['message'],”From: $fromn”), PHP的mail()函数需要subject, message, from 这些参数。如果函数执行成功,由PHP引擎发送邮件后,将打印出成功提示 "Your mail has been sent successfully"。如果出现错误,将提示相应信息 "An error has been occurred"

但是有朋友要问了,问题在哪里?主要的问题对用户的输入没有做必要的验证和过滤,正如《白帽子讲web安全》里说到的,任何的安全问题可以归结为信任的问
题,这里存在的问题就是程序代码对用户的输入无限制的信任。正如你所看到的在第三部分代码,发送邮件功能代码从用户接收输入(包括邮件主题、消息和来源
等),参数没有过滤和验证。因此,恶意攻击者可以任意控制这些参数的值,用户发送inject攻击。

4. 邮件注入示范


notice:
为了使用PHP作为邮件发送代理,我们需要对PHP.INI进行简单的配置:

[mail function]
; For Win32 only.
; http://php.net/smtp
SMTP = smtp.qq.com
; http://php.net/smtp-port
smtp_port =

出于演示目的,我们将使用前面的带漏洞的代码。此外,我们将提交下列值作为发送邮件的参数:

mail("littlehann@foxmail.com", "Call me urgent", "Hi,nPlease call me ASAP.nBye", "From: littlehann@foxmail.comn")

表单发送的HTTP数据包:

从攻击者的角度来看,有许多额外的字段,可以被注入在邮件标题。更多信息见RFC 822。例如,CC(抄送)或者BCC(密送)允许攻击者插入更多的消息。
    但要注意的是,我们在添加一个新的参数之前,我们必须增加一个换行符分隔每个字段。换行符的16进制值为"0x0A"。下面是一个demo code。

1) Cc/Bcc注入
在发送者字段(sender)后注入Cc和Bcc参数

From:sender@domain.com%0ACc:recipient@domain.com%0ABcc:recipient1@domain.com

所以现在,消息将被发送到recipient和recipient1账户。

2) 参数注射

From:sender@domain.com%0ATo:attacker@domain.com

现在消息将被发送到原来的收件人和攻击者帐户。注意,这里的攻击者的账户是我们通过注入额外传入的。

3) 邮件主题注入

From:sender@domain.com%0ASubject:This’s%20Fake%20Subject

攻击者注入的假的主题subject将被添加到原来的主题中并且在某些情况下将取代原本的主题subject。这取决于邮件服务行为。即代码编写的容错性,当参数中出现两个subject的时候代码是选择丢弃还是后者覆盖。

4) 改变消息的主体body
要注意SMTP的Mail格式,消息主题和头部Header之间有两个换行符(和HTTP是一样的)。

From:sender@domain.com%0A%0AMy%20New%%0Fake%20Message.

假消息将被添加到原始消息中。

5. 实战演示


这里提示一下,直接配置php.ini原生的email功能可能不太好用,配置起来也麻烦,建议采用一些第三方的Email系统(WP就挺不错的)进行发送,这个模块已经把相关的交互和HTTP数据包的构造封装好了。

附带上一些实验截图:

1) 正常发送

2) Cc/Bcc注入

在From字段添加Inject Payload

发送邮件后,增加了抄送的功能:

3) 邮件主题注入

我们在from的参数加添加subject字段:

接收邮件后:

可以看到,原本的subject被注入语句覆盖了一部分内容,但是具体是覆盖还是附加和具体的PHP代码编写逻辑有关,因为现在CMS对Email发送的普通做法就是利用PHP进行HTTP/HTTPS数据包的构造,先在本地构造好数据包后,再想服务器发送。

所以不同的系统对email注入的效果会有所不同。

4) 改变消息的主体body

这里要注意的的,SMTP区分消息头部和消息主题是依据%0A%0A双换行符决定的。

发送邮件后,我们发现消息的消息体已经被修改了。

以上就是我在本地的PHP环境中模拟实验的结果,因为环境和程序代码处理逻辑的差异,可能在不同的环境下实验会有差异,我的经验是根据不同的PHP CMS系统的Email源代码进行分析,理清发送Email数据包的代码逻辑,有针对性的进行email 注入。

6. 解决方案


1. 永远不要信任用户的输入字段。所有用户输入应该被认为是不可信的和潜在的恶意。应用程序不受信任的输入过程可能会变得容易受到诸如缓冲区溢出攻击、SQL注入,OS指令注入、拒绝服务和电子邮件注入。
2. 使用正则表达式来过滤用用户提交的数据。例如,我们可以在输入字符串中搜索(r 或 n)。
3. 使用外部组件和库,提供防范这个问题像 ZEND mail、PEAR mail和swift mailer。
4. ModSecurity可以阻止服务器级别的电子邮件注入。利用ModSecurity,我们可以检测通过POST或GET提交的CC, BCC或目的地址,并且拒绝任何包含这些字母请求。

7. 引用


1- http://www.securephpwiki.com/
2- http://projects.webappsec.org/
3- http://en.wikipedia.org/
4-http://www.damonkohler.com

PHP Email Injection
Reference From: http://resources.infosecinstitute.com/email-injection/
Translated By: LittleHann

PHP邮件注入攻击技术的更多相关文章

  1. PHP的SQL注入攻击的技术实现以及预防措施

    最近在折腾 PHP + MYSQL 的编程.了解了一些 PHP SQL 注入攻击的知识,总结一下经验.在我看来,引发 SQL 注入攻击的主要原因,是因为以下两点原因: 1. php 配置文件 php. ...

  2. 【web渗透技术】渗透攻防Web篇-SQL注入攻击初级

    [web渗透技术]渗透攻防Web篇-SQL注入攻击初级 前言不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动.在网络中,数据库驱动的Web应用随处可见,由此而存在的S ...

  3. 2017-2018-2 20179205《网络攻防技术与实践》第十一周作业 SQL注入攻击与实践

    <网络攻防技术与实践>第十一周作业 SQL注入攻击与实践 1.研究缓冲区溢出的原理,至少针对两种数据库进行差异化研究 缓冲区溢出原理   在计算机内部,输入数据通常被存放在一个临时空间内, ...

  4. 实例讲解 SQL 注入攻击

    这是一篇讲解SQL注入的实例文章,一步一步跟着作者脚步探索如何注入成功,展现了一次完整的渗透流程,值得一读.翻译水平有限,见谅! 一位客户让我们针对只有他们企业员工和顾客能使用的企业内网进行渗透测试. ...

  5. SQL注入攻击的种类和防范手段

    观察近来的一些安全事件及其后果,安全专家们已经得到一个结论,这些威胁主要是通过SQL注入造成的.虽然前面有许多文章讨论了SQL注入,但今天所讨论的内容也许可帮助你检查自己的服务器,并采取相应防范措施. ...

  6. 《图解HTTP》 第11章 web的攻击技术

    11.1 针对Web的攻击技术 简单的HTTP协议本身并不存在安全性问题,所以协议本身几乎不会成为攻击的对象. 11.1.1 HTTP不具备必要的安全功能 11.1.2 在客户端即可篡改请求 在HTT ...

  7. Web攻击技术

    Web攻击技术 1.针对Web的攻击技术 1.1.在客户端即可篡改请求 在Web应用中,从浏览器那接收到的Http的全部内容,都可以在客户端自由地变更.篡改,所以Web应用可能会接收到与预期数据不相同 ...

  8. 《图解Http》 10,11章:构建Web的技术, Web的攻击技术

    10.2动态HTML 通过调用客户端脚本语言js,实现对web页面的动态改造.利用DOM文档对象模型,指定想发生变化的元素. 10.22 更容易控制的DOM 使用DOM可以将HTML内的元素当作对象操 ...

  9. 《图解HTTP》阅读笔记--第十一章针对web的攻击技术

    第十一章.针对WEB的攻击技术 ----<图解HTTP>阅读笔记攻击目标---Web简单的HTTP协议本身并不存在安全性 问题,协议本身并不会成为被攻击的对象,应用HTTP的服务器和客户端 ...

随机推荐

  1. Java基础详解 (一)Java的类成员访问权限修饰词(以及类访问权限)

    在一个类的内部,其成员(包括成员变量和成员函数)能否被其他类所访问,取决于该成员的修饰词.Java的类成员访问权限修饰词有四类:private,无(默认情况下),protected和public.其权 ...

  2. js的nextSibling,属性兼容IE和FF等浏览器

    Firefox中 空白字符,比如回车,空格等也算作一个Node 就是firstChild,nextsbiling这两个.下面给出函数吧.还是代码比较说明问题代码都是网上来的.不过要注意的是,getNe ...

  3. poj1012

    Joseph Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 52097   Accepted: 19838 Descript ...

  4. 点击劫持(CLICKJACKING)与X-FRAME-OPTIONS HEADER

    转载: http://www.tuicool.com/articles/mqUBfa 目录 前言 1.1 点击劫持(clickjacking attacks) 1.2  Frame Bursters. ...

  5. Java compiler level does not match the version of the installed Java project facet.(转)

    Java compiler level does not match解决方法 从别的地方导入一个项目的时候,经常会遇到eclipse/Myeclipse报Description  Resource P ...

  6. use AP_VENDOR_PUB_PKG.Update_Vendor_Site_Public to u ORA-01722: invalid number in Package AP_VENDOR_PUB_PKG Procedure Update_Vendor_Site_Public

    ORA-01722: invalid number in Package AP_VENDOR_PUB_PKG Procedure Update_Vendor_Site_Public 发现此问题的经过: ...

  7. 泛型委托 Predicate/Func/Action

    Predicate 泛型委托  表示定义一组条件并确定指定对象是否符合这些条件的方法.此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素.看看下面它的定义: // Summar ...

  8. JS 之DOM对象(1)

    介绍DOM1中底层的一些属性和方法. 节点操作 appendChild() parentNode.appendChild(newNode)  在parentNode节点的最后插入newNode ins ...

  9. 学习Shell脚本编程(目录)

    所涉及的内容如下: Shell命令行的运行 编写.修改权限和执行Shell程序的步骤 在Shell程序中使用参数和变量 表达式比较.循环结构语句和条件结构语句 在Shell程序中使用函数和调用其他Sh ...

  10. abstract virtaul override new 及多态

    abstract abstract 修饰符可以和类.方法.属性.索引器及事件一起使用.在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类.标记为抽象或包含在抽象类中的成员必须通过从 ...