ThinkPHP5之文件包含审计分析(五)

news2024/11/23 15:19:24

说明

该文章来源于同事lu2ker转载至此处,更多文章可参考:https://github.com/lu2ker/

文章目录

    • 说明
    • 0x00 环境准备
    • 0x01 测试代码
    • 0x02 代码分析
    • 0x03 总结

参考链接:Mochazz/ThinkPHP-Vuln/

影响版本:5.0.0<=ThinkPHP5<=5.0.18 、5.1.0<=ThinkPHP<=5.1.10

测试环境:PHP7.3.4、Mysql5.7.26、TP5.0.18

0x00 环境准备

关于tp默认的模板调用路径,全局搜了一下后发现应该是在这里:
thinkphp\library\think\view\driver\Think.php#41

public function __construct($config = [])
{
	$this->config = array_merge($this->config, $config);
	if (empty($this->config['view_path'])) {
	$this->config['view_path'] = App::$modulePath . 'view' . DS;
}
	$this->template = new Template($this->config);
}

这里的构造函数生成的,默认位置就在application\index\view\。实际上按照习惯也应该是和模型(M),控制器(C)同级的。

之后呢,又在同类下的parseTemplate方法中132行,根据控制器名称使用默认规则(即同名)给$template赋值,然后又拼接上默认的模板文件后缀.html就好了。:

$template = str_replace('.', DS, $controller) . $depr . (1 == $this->config['auto_rule'] ? Loader::parseName($request->action(true)) : $request->action());
........
return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');

这就是为什么要创建创建 application/index/view/index/index.html文件

0x01 测试代码

<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
    public function index()
    {
        $this->assign(request()->get());
        return $this->fetch(); // 当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html
    }
}

开始需要assign方法进行模板变量赋值,然后fetch方法渲染。应该是比较常见的写法。

正式开始之前,还要再public下放一张图片马,模拟已经上传好了。

访问:http://www.tp5018.qwe/index.php/index/index?cacheFile=1.jpg 即可

0x02 代码分析

request的get方法不是这次的重点,只是获取get传入的参数。所以直接忽略。首先会来到

thinkphp\library\think\Controller.php#144也就是Controller类的assign方法,

并直接调用thinkphp\library\think\View.php#92View类的的assign方法

public function assign($name, $value = '')
    {
        if (is_array($name)) {
            $this->data = array_merge($this->data, $name);
        } else {
            $this->data[$name] = $value;
        }
        return $this;
    }

首先判断是不是数组,因为tp的request->get()返回的就是一个数组($data变量),数组内每一个元素存放一个参数的键值对。所以会执行array_merge()方法,array_merge在手册中的解释是将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。

这些还只是正常的数据传递过程,和文件包含还没有什么关系,接着往下看fetch方法的渲染。

  • 在thinkphp\library\think\View.php#148

进入了View类的fetch方法:其中,我们从158行开始:

try {
            $method = $renderContent ? 'display' : 'fetch';
            // 允许用户自定义模板的字符串替换
            $replace = array_merge($this->replace, $replace, (array) $this->engine->config('tpl_replace_string'));
            $this->engine->config('tpl_replace_string', $replace);
            $this->engine->$method($template, $vars, $config);
        } catch (\Exception $e) {
            ob_end_clean();
            throw $e;
        }

这个try,首先给 m e t h o d 设置成了 f e t c h (因为 V i e w 类的 f e t c h 方法默认 method设置成了fetch(因为View类的fetch方法默认 method设置成了fetch(因为View类的fetch方法默认renderContent是个false),然后执行的代码的作用就是取来一些渲染视图需要的文件位置,比如:

在这里插入图片描述

重要的是,注意到$this->engine->$method($template, $vars, $config);这条语句,因为$method已经被赋值过了,所以它是会去调用tp模板引擎的fetch方法(在Think类),而Think类下的fetch在最后又调用了template的fetch方法。也就是最后会走到这里:

  • thinkphp\library\think\Template.php#160

到这里先停一下,回想一下传入的cacheFile=1.jpg现在是个什么状态,在哪个变量里

  1. 刚开始通过requets->get()获取,作为$name传入assign方法
  2. 两层assign处理后,由Controller下的assign返回了 t h i s ,参数在 this,参数在 this,参数在this->view->data数组里
  3. 然后在View类中的fetch中赋值给了$vars(这里的fetch是第二层,层层深入)
  4. v a r s 做为 T h i n k 类下 f e t c h 方法的 vars 做为 Think类下fetch方法的 vars做为Think类下fetch方法的data[]参数传入(这里的fetch是第三层)
  5. d a t a 做为 T e m p l a t e 类下 f e t c h 方法的 data 做为Template类下fetch方法的 data做为Template类下fetch方法的vars[]传入(这里是最后一层fetch,模板引擎的核心)

变量的传递过程理清后来看最重要的代码:

在这里插入图片描述

首先关注参数, t e m p l a t e 在最开始我们就知道它存放的是模板文件的位置, template在最开始我们就知道它存放的是模板文件的位置, template在最开始我们就知道它存放的是模板文件的位置,vars是我们的图片马文件参数,$config在调用过程中,一直是默认空的。

再经过了176行的模板文件解析之后进入了if代码块,首先把自动生存的缓存php文件路径给了 c a c h e F i l e 变量,接着就调用了 s t o r a g e − > r e a d ( ) ,并将 cacheFile变量,接着就调用了storage->read(),并将 cacheFile变量,接着就调用了storage>read(),并将data和$cacheFile一起传入了,跟入:

  • 来到thinkphp\library\think\template\driver\File.php#45
public function read($cacheFile, $vars = [])
    {
        if (!empty($vars) && is_array($vars)) {
            // 模板阵列变量分解成为独立变量
            extract($vars, EXTR_OVERWRITE);
        }
        //载入模版缓存文件
        include $cacheFile;
    }

注意到其中调用了extract函数来处理$vars,在官方手册中extract解释如下:

本函数用来将变量从数组中导入到当前的符号表中。

检查每个键名看是否可以作为一个合法的变量名,同时也检查和符号表中已有的变量名的冲突。

意思就相当于全局是变量注册,可以看我这里的记录指出了对用户可控的输入使用该函数可能会造成风险。尤其是第二个参数:默认EXTR_OVERWRITE,如果有冲突,覆盖已有的变量。

了解了这个函数,就明白了在URL栏传入的?cacheFile=1.jpg实际上就是为了这里的变量覆盖!在变量覆盖之后,程序立马就include了$cacheFile,也就是1.jpg图片马。

至此完成文件包含。

0x03 总结

这个漏洞个人认为文件包含是小事,因为重点是在最后的变量覆盖。而且那条代码还是一个经典的变量覆盖漏洞案例。如果是从审计来看,定位到extract函数,注意到这里设置了EXTR_OVERWRITE,那么只要第一个参数可控就可以完成变量覆盖了,include只是完美利用了变量覆盖这个功能。全局搜索也是很容易搜到调用位置的,这里有两处,另外一处是display方法,试了下也是可以完美利用的,它在调用View类下的fetch方法的时候会传入$renderContent=true用来区分fetch方法:

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/144547.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java - JIT即时编译

java前端编译器和后端编译器的作用Java前端编译器&#xff1a;javac 编译&#xff0c;在程序运行前&#xff0c;将 源文件 转化为 字节码 即 .class 文件Java 程序最初只能通过解释器解释执行&#xff0c;即 JVM 对字节码逐条解释执行&#xff0c;因此执行速度比较慢。字节码与…

【SAP Abap】SAP Flight 航班系统数据模型简介(SCARR、SPFLI、SFLIGHT、SBOOK等)

SAP Flight 航班系统数据模型简介&#xff08;SCARR、SPFLI、SFLIGHT、SBOOK等&#xff09;1、本文目的2、数据模型3、查看模型数据4、生成演示数据5、模型应用1、本文目的 SAP ABAP 系统都会自带 Flight 航班系统数据模型&#xff0c;其大量应用于 SAP ABAP 帮助文档、系统 D…

移动安全总结 2019

声明 本文是学习移动安全总结 2019. 下载地址 http://github5.com/view/1223而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 序言 随着2019年的逝去&#xff0c;二十一世纪第二个十年也已随之结束。回顾过去的十年&#xff0c;我们的生活随着科技的进…

养老院人员定位方案125K芯片AS3933/SI3933/GC3933/PAN3501

随着社会老龄化&#xff0c;高龄化&#xff0c;空巢化和病残化的迅速发展&#xff0c;将使得越来越多的老人住进养老院。虽养老院数量越来越多&#xff0c;但养老院人也越来越多&#xff0c;给现有的养老管理上带来压力&#xff0c;由于服务人员有限&#xff0c;无法及时顾及到…

【LeetCode每日一题】——89.格雷编码

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 数学 二【题目难度】 中等 三【题目编号】 89.格雷编码 四【题目描述】 n 位格雷码序列 是一…

举个栗子!Tableau 技巧(249):为文本表中的不同度量设置不同颜色

使用文本表呈现数据时&#xff0c;通常会用颜色的深浅来代表度量的数值大小。单一度量很容易实现&#xff0c;但多个度量的情况&#xff0c;很多数据粉反馈不知道如何实现。 如下示例&#xff0c;在为不同度量设置了不同颜色后&#xff0c;的确既美观又直观。 具体该如何实现呢…

进制转换 2进制转10进制 10进制转2进制

觉得有用的&#xff0c;HXD们请点个赞●▽● 10进制转2进制&#xff08;以十进制100转换为二进制为例子&#xff1a;&#xff09; 方法一&#xff08;除2取余数&#xff0c;倒叙摆列&#xff0c;高位补零 &#xff09; 100/250余0&#xff1b; 50/225余0&#xff1b; 25/21…

Allegro174版本新功能介绍之改变菜单字体大小

Allegro174版本新功能介绍之改变菜单字体大小 Allegro在升级到174的时候,默认的字体是非常小的,如下图 看起来十分费劲 启动界面 菜单界面 但是174是支持把把这些字体调大的,具体操作如下 选择Setup

git远程仓库使用流程

git远程仓库使用流程远程仓库使用流程远程仓库介绍远程仓库使用流程如何将本地文件夹关联远程仓库多人开发配置流程远程仓库SSH配置远程仓库使用流程总结git分支使用流程分支介绍1.2-分支使用流程远程仓库使用流程 Git命名作用详细描述git clone克隆远程仓库代码把服务器的项目…

Laravel 开发 API 时的前置准备

前言 使用 Laravel 有一段时间了&#xff0c;今天来总结我平时进行开发前的一些准备工作&#xff0c;如果有不合理的地方或者有更好的建议欢迎各位大佬指出纠正&#xff01; 环境 PHP8 MySQL5.7 Nginx1.20 IDE&#xff1a;PhpStorm搭建 安装 推荐使用 composer 安装 或者…

舆情监测技术方案,网络舆情分析技术手段有哪些?

网络舆情分析技术手段着力于利用技术实现对海量的网络舆情信息进行深度挖掘与分析&#xff0c;以快速汇总成舆情信息&#xff0c;从而代替人工阅读和分析网络舆情信息的繁复工作&#xff0c;接下来TOOM舆情监测小编带您简单了解舆情监测技术方案&#xff0c;网络舆情分析技术手…

网站服务器运行过程中有哪些常见问题?

网站服务器运行过程中有哪些常见问题?在线业务运转过程中&#xff0c;网站服务器的宕机或无法访问往往会给访客带来极差的用户体验&#xff0c;继而影响到在线业务的品牌声誉及长远发展。下面聊聊关于网站服务器的常见问题&#xff0c;需多加留意。 1.页面加载速度变慢 这是用…

Leetcode:222. 完全二叉树的节点个数(C++)

目录 问题描述&#xff1a; 实现代码与解析&#xff1a; 直接当普通二叉树遍历&#xff1a; 利用完全二叉树和满二叉树的特性&#xff1a; 原理思路&#xff1a; 问题描述&#xff1a; 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的…

js实现纯前端压缩图片

演示 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>压缩图片</title> </head> <bo…

php学习笔记-phpday1

php代码基本语法 PHP&#xff08;PHP: Hypertext Preprocessor&#xff09;即“超文本预处理器”&#xff0c;是在服务器端执行的脚本语言&#xff0c;尤其适用于Web开发并可嵌入HTML中。PHP语法学习了C语言&#xff0c;吸纳Java和Perl多个语言的特色发展出自己的特色语法&…

【自学C++】C++ HelloWorld

C HelloWorld C HelloWorld教程 我们打开 Dev-C 软件&#xff0c;界面如下&#xff1a; 我们选择文件 -> 新建 -> 源代码&#xff0c;如下图所示&#xff1a; 点击源代码之后&#xff0c;此时界面如下图所示&#xff1a; 我们在新建的文件中&#xff0c;输入以下内容&a…

用远见超越未见 | 立足2022,洞见未来之2023十大安全技术趋势

2022年是极不平凡的一年&#xff0c;外部的世界局势逐步恶化&#xff0c;内部的新冠疫情转段迈向新阶段。2022年也是伟大的一年&#xff0c;党的二十大胜利召开。党的二十大报告就“推进国家安全体系和能力现代化&#xff0c;坚决维护国家安全和社会稳定”作出专章部署&#xf…

三万字机器学习项目整理(基础到进阶)

如果你是学生、计算机领域的工作者&#xff0c;我强烈建议你学习、掌握机器学习&#xff0c;我不敢说它是最简单的&#xff08;机器学习的确很简单&#xff09;&#xff0c;但是掌握机器学习一定是性价比最高的。 本文用浅显易懂的语言精准概括了机器学习的相关知识&#xff0…

jQuery(JS库) | 一文带你掌握jQuery的使用

目录 一&#xff1a;开篇基础 1. 为什么使用 jQuery 2. DOM 对象 3. JS对象和 jQuery 对象 4. 获取 jQuery 5. 牛刀小试 6. DOM 对象和 jQuery 对象 二&#xff1a;选择器 1. 基本选择器 2. 表单选择器 三&#xff1a;过滤器 1. 基本过滤器 2. 表单对象属性过滤器…

天津人才引进迁出迁入延期经验分享

由于2022年疫情&#xff0c;集体户口折腾了5个月终于告与段落了&#xff0c;只能说2022年点真得太背了。。。把自己的痛苦经验分享给大家乐乐。。。 迁出找人代办&#xff0c;获得准迁证后&#xff0c;个人证件比准迁证提前将近2天开始邮寄&#xff0c;但最后还比准迁证晚到了1…