当前位置:   article > 正文

Thinkphp5.0.x 文件包含漏洞_thinkphp5.0漏洞

thinkphp5.0漏洞

前言:这个漏洞我复现的不是很完善,按网上的教程,传入图片码是可以被解析为php文件,从而实现攻击,但是我尝试了几次都不成功,目前还不知道是为什么。

影响版本

5.0.0 <= Thinkphp <= 5.0.18

5.1.0 <= ThinkPHP <= 5.1.10

环境搭建

这里我是在网上直接找的thinkphp5.0.18源码,然后用phpstudy进行搭建的。

源码地址:https://www.codejie.net/5913.html

漏洞复现

首先是进入 application\index\controller\index.php 文件中, 将代码修改为以下内容

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

之后在创建 application\index\view\index\index.html 其中index.html的内容可以随意写,只要你能认得出来是这个文件就行。如果没有这个模板文件的话会报错。它的作用其实就是起一个被替换的作用,之后会讲解。

之后就是把图片码放入 public 目录下,以此模拟文件上传,不过我的图片码可能生成或别的原因,无法起作用,这里就放入一个一句话木马文件,仅做演示。

 之后访问 http://localhost/public/?cacheFile=1.php

 代码审计

接下来就是一步一步理解其代码是如何执行的。

application\index\controller\index.php

 1. 我们先跟进 assign() 函数

Controller.php

 可以看到它又指向了其他文件中的 assign() 函数,那 view 的赋值是什么呢。

这里我们可以看到 view 有 View 和 Config两种,这里可以通过后面的方法名意思来判断,或者全局搜索

就这四个文件中有 assign() 方法,但 View.php 有两个,至于选哪个,如果你做过thinkphp的饭序列化,可以明白文件之间要靠 namespaceuse 来联系,这里就不讲了,你们可以看看 Controller.php 和 这两个 View.php 前面的 namespace 和 use 差异来判断。这里选择的就是第一个View.php。

View.php

 这里就可以知道他把我们输入的参数转为了array型。

如:我们传入 ?file=1.jpg

       它会将其转为   array("file" => "1.jpg")

这里assign()方法就审完了。

2. get()方法就没必要跟进了,它其实就是get传参,而request()函数是一个全局函数,它的作用就是获取HTTP的请求数据的。

这里可以知道的就是跟进get()函数, 会在后面进入 filerEXP() 函数中进行数据过滤,不过不会影响到我们。

 3. fetch()函数

Controller.php

 这里又是进行一次跳转。

View.php

第一段意思就是把我们 get传参的参数存入$data中

第二段意思就是又进行一次跳转

 这里可以判断出跳转到了 Think.php文件中

Think.php

 又进行了跳转

 Template.php

 查找storage

 File.php

很明显发现在这里可能会产生文件包含漏洞。但问题也来了,$cacheFile 这个变量的值要怎么赋值呢。这里就利用extract()这个函数的特性。它的作用就是可以把一个数组类型,其键值取出单独作为一个变量,之后对应的值就作为这个变量的值。

例:

  1. <?php
  2. $a = "Original";
  3. $my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
  4. extract($my_array);
  5. echo "\$a = $a; \$b = $b; \$c = $c";
  6. ?>
  7. //运行结果: $a = Cat; $b = Dog; $c = Horse

 所以这也就是为什么我们要传 ?cacheFile=1.php 因为它们先会被转为数组类型 array("cacheFile" => "1.php"), 然后利用 extract 函数就成功控制 $cacheFile 变量,给其赋值。

漏洞修复

File.php文件的read方法中修改为以下内容

 加上这两行。其作用就是在还没进行extract函数之前,先把$cacheFile的值赋给$this->cacheFile,之后再对$this->cacheFile进行包含,这样即使$cacheFile的值发生改变了,也没有什么影响。

补充:

 这里我们可以单独打印以下$this->cacheFile和$cacheFile的值

可以看到其实第二个才是进入read方法时$cacheFile的值,其赋值过程在 Template.php,fetch方法中

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/1011052
推荐阅读
相关标签
  

闽ICP备14008679号