加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP通过bypass disable functions执行系统命令的方法汇总

发布时间:2021-05-20 12:03:50 所属栏目:PHP教程 来源:网络整理
导读:一、为什么要bypass disable functions 为了安全起见,很多运维人员会禁用PHP的一些“危险”函数,例如eval、exec、system等,将其写在php.ini配置文件中,就是我们所说的disable functions了,特别是虚拟主机运营商,为了彻底隔离同服务器的客户,以及避免
副标题[/!--empirenews.page--]

一、为什么要bypass disable functions

为了安全起见,很多运维人员会禁用PHP的一些“危险”函数,例如eval、exec、system等,将其写在php.ini配置文件中,就是我们所说的disable functions了,特别是虚拟主机运营商,为了彻底隔离同服务器的客户,以及避免出现大面积的安全问题,在disable functions的设置中也通常较为严格。

攻与防是对立的,也是互相补充的,既然有对函数的禁用措施,就会有人想方设法的去突破这层限制,我们只有在掌握突破方式以及原理的基础之上,才能更好的去防范这类攻击。

执行系统命令通常是攻击者拿到网站webshell之后想要进一步动作的必然操作,如若不能执行系统命令,接下来的更深入的攻击将很难继续,所以就有了网站管理者禁用类似exec、system之类函数的现象。然而随着技术的不断进步,不断有新的思路出现,单纯的禁用这些函数,某些情况下已经不能阻止攻击者达到执行系统命令的目的了,那么攻击者用什么样的方式突破了disable functions呢?我们又怎样防范这样的攻击呢?

二、 Bash漏洞导致的任意命令执行

GNU Bash 环境变量远程命令执行漏洞(CVE-2014-6271)是GNU Bash 的一个远程代码执行漏洞,在这个CVE的介绍中,可以看到这样的描述:“GNU Bash 4.3及之前版本中存在安全漏洞,该漏洞源于程序没有正确处理环境变量值内的函数定义。远程攻击者可借助特制的环境变量利用该漏洞执行任意代码。以下产品和模块可能会被利用:OpenSSH sshd中的ForceCommand功能,Apache HTTP Server中的mod_cgi和mod_cgid模块,DHCP客户端等”。实际上,PHP也可以利用这个漏洞做很多事情,甚至有可能直接在80导致远程命令执行。关于这个漏洞的详细情况可以查阅CVE-2014-6271的相关资料,此处不再赘述。

下面我们来看一下PHP到底什么地方能用到bash的这个漏洞呢?其实可以用的地方不止一处,这里我们以mail函数作为例子,其他地方同理,可以自行分析。

PHP的mail函数提供了3个必选参数和2个可选参数,这里我们主要看最后一个参数,PHP官方手册上对最后一个参数的说明:

“Theadditional_parameters parameter can be used to pass an additional parameter tothe program configured to use when sending mail using the sendmail_pathconfiguration setting. For example,this can be used to set the envelope senderaddress when using sendmail with the -f sendmail option. Theuser that the webserver runs as should be added as a trusted user to thesendmail configuration to prevent a ‘X-Warning' header from being added to themessage when the envelope sender (-f) is set using this method. For sendmailusers,this file is /etc/mail/trusted-users. “

简单的说就是这个参数可以通过添加附加的命令作为发送邮件时候的配置,比如使用-f参数可以设置邮件发件人等,官方文档在范例Example #3也有所演示,具体可以参考官方文档: http://php.net/manual/zh/function.mail.php 。

在mail函数的源代码mail.c中,我们可以找到如下代码片段:

如果传递了第五个参数(extra_cmd),则用spprintf将sendmail_path和extra_cmd拼接到sendmail_cmd中(其中sendmail_path就是php.ini中的sendmail_path配置项),随后将sendmail_cmd丢给popen执行:

如果系统默认sh是bash,popen会派生bash进程,而我们刚才提到的CVE-2014-6271漏洞,直接就导致我们可以利用mail()函数执行任意命令,绕过disable_functions的限制。但是这里其实有一个问题,就是extra_cmd在spprintf之前做了安全检查,我当前的PHP版本是最新的7.2.4,代码位置在mail.c的第371-375行:

php_escape_shell_cmd函数会对特殊字符(包括&#;`|*?~<>^()[]{}$,x0A and xFF. ‘ 等)进行转义,那这样是不是就没办法了呢?不是的,我们可以通过putenv函数来设置一个包含自定义函数的环境变量,然后通过mail函数来触发,网上早已有POC。

同样调用popen派生进程的php函数还有imap_mail,或者还可能有其他的我们没有发现的函数,所以如果要防范这类攻击,最好的办法就是从根源上入手,修复CVE-2014-6271这个bash漏洞。

三、LD_PRELOAD:无需bash漏洞

上文说到mail函数利用bash破壳漏洞可以实现突破disable functions的限制执行系统命令,但是像这样的漏洞,一般安全意识稍好一点的运维人员,都会打上补丁了,那么是不是打上补丁之后就一定安全了呢?显然答案是否定的,LD_PRELOAD是Linux系统的下一个有趣的环境变量:

它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。

它允许你定义在程序运行前优先加载的动态链接库,我们只要知道这一件事就足够了,这说明什么?这说明我们几乎可以劫持PHP的大部分函数,还拿上文的mail函数作为例子,上文说过,php的mail函数实际上是调用了系统的sendmail命令,那么我们来看一下sendmail都调用了哪些库函数:

使用readelf -Ws /usr/sbin/sendmail命令来查看,我们发现sendmail函数在运行过程动态调用了很多标准库函数,我们从中随便选取一个库函数geteuid进行测试。

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!