我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ThinkPHP5漏洞分析之SQL注入(七)

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ThinkPHP5漏洞分析之SQL注入(七)

说明

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

文章目录

参考链接:Mochazz/ThinkPHP-Vuln/

影响版本:5.0.7<=ThinkPHP5<=5.0.22 、5.1.0<=ThinkPHP<=5.1.30

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

5.1.x

?s=index/\think\Request/input&filter[]=system&data=pwd?s=index/\think\view\driver\Php/display&content=?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

5.0.x

?s=index/think\config/get&name=database.username # 获取配置信息?s=index/\think\Lang/load&file=../../test.jpg    # 包含任意文件?s=index/\think\Config/load&file=../../t.php     # 包含任意.php文件?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

本文以?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

为例。

相信很多人在不懂原理的情况下,看这一串payload是感觉很nb的一个paylaod(因为它长,需要的参数多),像我本人之前就纳闷这payload中为啥还会有反斜杠,s参数名是啥?invokefunction是啥?这个think\app是个啥东西呀为啥为啥。可是当时只看得懂system(whoami)😂。接下来就从代码中找到这些答案。

只想看结果请直接跳到:

0x00 从?s=是个啥开始

在application\config.php#78行,有一个var_pathinfo键的值默认就是s,而该项的注释是PATHINFO变量名 用于兼容模式。那么什么是PATHINFO?什么是兼容模式?

在源码中遇到不知道的定义,大可以全局搜索它在哪里定义,哪里用到了它:

在这里插入图片描述

来到thinkphp\library\think\Request.php#pathinfo()来阅读var_pathinfo的使用。
在这里插入图片描述

可以看到在390行用Config::get获取了var_pathinfo的值,也就是s,然后就变成了`` G E T [ s ] ‘ ,获取到值赋值给 ‘ _GET[s]`,获取到值赋值给` GET[s],获取到值赋值给_SERVER[‘PATH_INFO’],然后下面407行去除了最左边的正斜杠。那么现在就明白了。s就是用来获取payload中的index/\think\app/invokefunction`这部分的,它也叫做兼容模式参数,而它的值在tp里面就作为pathinfo。pathinfo后来又会怎么处理呢?继续跟着程序执行流程

在thinkphp\library\think\Route.php#check()

在这里插入图片描述

其中,$url实际上传入的就是刚才的pathinfo的值。注意到839行把所有的/都替换为了|。那么现在就是

index|\think\app|invokefunction这个样子。但是因为没有定义好的路由规则,最后还是return了false。在thinkphp\library\think\App.php#642:

在这里插入图片描述

可以看到,如果没有定义好路由规则,也就是刚才的return了false,并且还有强制路由的话就会抛出错误。但是这个漏洞利用条件之一就是不开启强制路由~。

那么再往下走,就会到thinkphp\library\think\Route.php#parseUrl来解析那个pathinfo。我想这应该就是所谓的兼容模式了。

0x01 模型/控制器/方法的处理

在parseUrl方法中也会把正斜杠替换为|来处理index/\think\app/invokefunction(为了方便下面以url替换这串)

但是与之前的check方法不同的是,它紧接着调用了parseUrlPath()方法。

在这里插入图片描述

在parseUrlPath()方法中,用$path = explode('/', $url);来把这个url给处理为了一个数组。:

在这里插入图片描述

这样实际上就是分成了模型、控制器、方法了。最终逐个获取的位置是parseUrl方法的:

在这里插入图片描述

0x02 漏洞原因

当程序执行到thinkphp\library\think\App.php#exec(),会进入到module分支,来到module方法,在:

在这里插入图片描述

这里的 r e s u l t 数组实际上就是刚才 p a r s e U r l 返回的那个“ result数组实际上就是刚才parseUrl返回的那个“ result数组实际上就是刚才parseUrl返回的那个path数组”,

在这里插入图片描述

1=>控制器,2=>操作名(也叫做方法名)。在这里获取了之后,程序没有再对控制器、方法名过滤导致了任意控制器下任意方法的调用。(但实际上并不是很任意。。)

紧接着就会使用加载器

$instance = Loader::controller(                $controller,                $config['url_controller_layer'],                $config['controller_suffix'],                $config['empty_controller']            );

加载\think\app了,在thinkphp\library\think\Loader.php#controller

在这里插入图片描述

然后在invokeClass方法中:

在这里插入图片描述

使用反射来获取了think\App的一个指针?句柄?反正$reflect现在已经代表这个类了。 。。然后用:

在这里插入图片描述

来实例化。,返回到了$instance变量中,这时控制器这块已经基本上处理完了,think\App实际上就是thinkphp\library\think\App.php这个php文件里的App类(在MVC架构中,某些类也是可以叫做控制器),think是一个命名空间。意思就是think命名空间下的都是thinkphp的核心代码。命名空间的概念百度一下就知道了。

接下来就是获取方法,调用反射执行类的方法。App类里的invokefunction方法如下:

        public static function invokeFunction($function, $vars = [])    {        $reflect = new \ReflectionFunction($function);        $args    = self::bindParams($reflect, $vars);        // 记录执行信息        self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');        return $reflect->invokeArgs($args);    }

最后return的时候调用了invokeArgs,在手册中解释如下:

在这里插入图片描述

很明确它是能调用带参函数的。

总体流程如下:使用反射执行了App里的invokeFunction,并给其传入了参数1:function=call_user_func_array,参数2:vars[]=system&vars[1][]=whoami

它会执行call_user_func_array('system', ['whoami']),也就是system(‘whoami’)。执行了命令。

0x03 参数的获取?

使用的是bindParams方法获取的参数,参数名必须还得是这特定值,为啥呢?

因为bindParams方法中会用getParameters(ReflectionFunctionAbstract::getParameters)获取反射对象的每一个参数,返回参数列表。

来源地址:https://blog.csdn.net/Jack0610/article/details/128583647

免责声明:

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

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

ThinkPHP5漏洞分析之SQL注入(七)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

phpcms v9.6 注入漏洞详细分析

PHPCMS V9.6是一个非常受欢迎的开源内容管理系统。然而,它也存在一些安全漏洞,其中之一是注入漏洞。注入漏洞允许攻击者向数据库中插入恶意代码,从而执行未经授权的操作。该漏洞的具体细节如下:1. 注入点:注入漏洞通常出现在用户输入的地方
2023-09-15

PHPCMS V9专题模块注入漏洞的分析与修复方法

分类ID没有进行有效过滤,导致注入发生。详细说明:受影响版本:phpcms V9 - GBK 漏洞文件:/phpcms/modules/sphttp://www.cppcns.comecial/index.php 漏IBVxhgeQXq洞函
2022-06-12

数据库之SQL注入的示例分析

小编给大家分享一下数据库之SQL注入的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、产生SQL注入原因开发代码的时候没有全面考虑到网络安全性,特别是在
2023-06-20

sql注入之类型以及提交注入的示例分析

这篇文章主要介绍sql注入之类型以及提交注入的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!参数类型这里说的参数是源码中存在注入的地方。其中参数类型有:数字、字符、搜索、json等。其中sql语句干扰符号有:
2023-06-20

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录