博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP mail()可能导致的问题
阅读量:6438 次
发布时间:2019-06-23

本文共 2504 字,大约阅读时间需要 8 分钟。

参考文献:

题目网址:

环境:

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)函数通过指定的过滤器过滤变量。如果成功,则返回已过滤的数据,如果失败,则返回 falsevariable    必需。规定要过滤的变量。filter  可选。规定要使用的过滤器的 ID。options     规定包含标志/选项的数组。检查每个过滤器可能的标志和选项。

此函数在双引号中嵌套转义空格仍然能够通过检测。同时由于底层正则表达式的原因,通过重叠单引号和双引号,欺骗 filter_var(),这样就可以绕过检测。

一个简单的例子:

img_ee1879a78a9b30560a139e477072daa6.png
1.png

③escapeshellcmd()函数

引入的特殊符号,虽然绕过了filter_var()的检测,但PHP的mail()在底层调用了 escapeshellcmd() ,对用户输入的邮箱地址进行检测,即使存在特殊符号,也会被 escapeshellcmd()处理转义,这样就没办法达到命令执行的目的了。

但还调用了escapeshellarg()//把字符串转码为可以在 shell 命令里使用的参数,此函数将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,确保能够直接将一个字符串传入 shell 函数(含 exec(),system(),反引号)

一个例子

  • 传入的参数是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

转载地址:http://flkwo.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
linux为启动菜单加密码
查看>>
MySQL5.5编译方式安装实战
查看>>
细谈Ehcache页面缓存的使用
查看>>
GridView如何设置View的初始样式
查看>>
Placeholder in IE8 and older
查看>>
SQL语句字符串处理大全
查看>>
环境变量的作用,为什么要设置环境变量?
查看>>
从尾到头打印单链表
查看>>
getopt
查看>>
我的第一个IT产品:PublicLecture@HK【My First IT Product】
查看>>
优秀员工与普通员工
查看>>
CCNP学习笔记15-RSTP
查看>>
DELL服务器iDRAC相关设置
查看>>
JVM学习笔记(一)------基本结构
查看>>
$@等特定shell变量的含义
查看>>
我的友情链接
查看>>
(超详细版)Linux下Hadoop2.7.1集群环境的搭建(3台为例)
查看>>
策略模式、上下文与内部类的思考
查看>>
关于getCurrentUrl的获取问题
查看>>