文章首发于先知社区https://xz.aliyun.com/t/4623
简介
PHP 的 disabled_functions主要是用于禁用一些危险的函数防止被一些攻击者利用
Bypass思路
利用LD_PRELOAD
什么是LD_PRELOAD
1 | LD_PRELOAD是Linux系统的一个环境变量,用于动态库的加载,动态库加载的优先级最高,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。 |
简单来说就是LD_PRELOAD
指定的动态链接库文件,会在其它文件调用之前先被调用
demo
光看概念估计你可能会很懵,我们来写一个简单的demo来了解一下啥是LD_PRELOAD
首先我们先写一个id.c,内容如下:
1 |
|
执行一波
1 | qiyou@ubuntu:~/Desktop$ id |
可以看到uid和gid都变为了0,权限也变为了root
我们可以用ldd查询一下依赖关系,可以发现id.so(我们编译的动态链接库)在其它动态链接库之前提前被加载了,也就是说我们的恶意代码中的函数覆盖了原本的动态链接库的函数

配合putenv+mail
putenv官方手册是这么解释的:
1 | putenv ( string $setting ) : bool |
如果该函数未被ban掉的话,即使是禁用了其它常见的函数,也可能会导致rce
我们可以按照如下步骤:
- 生成一个我们的恶意动态链接库文件
- 利用putenv设置LD_PRELOAD为我们的恶意动态链接库文件的路径
- 配合php的某个函数去触发我们的恶意动态链接库文件
- Getshell
那么php中的某个函数怎么去找呢,参考了该文章,发现mail()函数可以使用,而mail()函数执行默认是会调用外部程序sendmail的,看一下php.ini就会发现默认调用sendmail -t -i

PS:如果没有安装sendmail的话可以用
apt-get install sendmail
安装sendmail
我们可以用strace查看一下mail函数调用的过程,可以很明显看出来执行了sendmail -t -i

然后我们可以使用 readelf -Ws /usr/sbin/sendmail
可以查看senmail都调用了哪一些函数,然后从中选几个即可,这里我们选择getuid

然后就可以编写我们的动态连接程序
test.c
1 |
|
然后生成我们的动态链接程序
1 | gcc -c -fPIC test.c -o test |
然后编写php脚本mail.php
1 |
|
执行一波,然后用strace查看调用过程是否执行了我们的ls > test
,可以发现成执行了我们的命令


配合putenv+error_log
0ctf2019的Wallbreaker Easy
中ban了mail函数,但是error_log
没有ban掉,故我们可以用error_log
来bypass disabled_functions
error_log的一些参数
1 | error_log(error,type,destination,headers) |
编写php脚本,动态链接文件同上,error_log调用的过程中(当type为1时)和mail函数一样,也会调用sendmail,
1 |
|



利用ImageMagick
环境搭建
这个搭建环境有一丝丝繁琐,不过没关系,按照我以下步骤来应该问题不大QAQ
1 | 1:apt-get update&&apt-get install imagemagick |

安装几个依赖
1 | apt-get install php-pear php-dev |
下载以及安装imagick
1 | 1.wget http://pecl.php.net/get/imagick-3.4.3.tgz |
成功安装

然后安装ffmpeg
1 | apt-get install ffmpeg |
成功安装

如何利用
那么我们应该如何利用呢,参考了飘零师傅的分析,可以知道当Imagick处理的文件是如下后缀的时候,就会调用外部程序ffmpeg去处理该文件
1 | wmv,mov,m4v,m2v,mp4,mpg,mpeg,mkv,avi,3g2,3gp |
我们来写一个小demo来验证一下是否正确
img.php
1 |
|
我们strace一下看看执行的过程,可以发现在执行的过程中调用了ffmpeg

配合__attribute__
函数
PS: __attribute__
的介绍
1 | __attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。__attribute__前后都有两个下划线,并且后面会紧跟一对原括弧,括弧里面是相应的__attribute__参数 |
我们可以知道当该函数为__attribute__((__constructor__))
的时候,会在main()函数执行之前被自动的执行
所以我们尝试构造poc.c
1 |
|
然后生成我们的动态链接程序
1 | gcc -c -fPIC poc.c -o poc |
img.php
1 |
|
运行一波,发现我们的命令执行成功了

利用imap_open (CVE-2018-19518)
php imap扩展用于在PHP中执行邮件收发操作。其imap_open函数会调用rsh来连接远程shell,而debian/ubuntu中默认使用ssh来代替rsh的功能(也就是说,在debian系列系统中,执行rsh命令实际执行的是ssh命令)。
因为ssh命令中可以通过设置-oProxyCommand=
来调用第三方命令,攻击者通过注入注入这个参数,最终将导致命令执行漏洞。
ssh的-oProxyCommand 参数
SSH 命令中用到了许多命令,其中我们可以使用 -o 参数来设置连接期间可用的各种选项。在建立SSH连接之前,我们可以设置 ProxyCommand
参数,如下所示:
1 | qiyou@ubuntu:~/test$ ls |
可以发现即使是ssh连接失败了,但是命令还是执行了。
CVE-2018-19518
的环境可以直接使用vulhub上的环境:链接
直接上poc
1 |
|
执行一波,可以发现执行成功了,要想写webshell的话直接把我们的exp改一下就ok了,这里就不多赘述了

后记
被0ctf锤哭了,膜RR师傅Orz,比赛的时候没有做出来,赛后没有时间复现,等到想要复现的时候环境已经关了,只能是本地复现了,顺便总结了一下。

Reference
https://www.tr0y.wang/2018/04/18/PHPDisalbedfunc/index.html
https://www.jianshu.com/p/137ae1400337
https://blog.csdn.net/haoel/article/details/1602108
https://github.com/Bo0oM/PHP_imap_open_exploit/blob/master/exploit.php