ThinkPHP5远程命令执行漏洞

0x01 ThinkPHP简介

ThinkPHP是一个基于MVC和面向对象的轻量级PHP开发框架,遵循Apache2开源协议发布。从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,注重开发体验和易用性,为web应用开发提供了强有力的支持。

0x02 漏洞简介

(1)漏洞名称

ThinkPHP5远程命令执行

(2)漏洞描述

由于ThinkPHP5框架对控制器名没有进行足够的安全检测,导致在没有开启强制路由的情况下,攻击者构造指定的请求,可以直接getshell。

(3)影响范围

  • ThinkPHP 5.0系列 <5.0.23
  • ThinkPHP 5.1系列< 5.1.31
  • 基于ThinkPHP5二次开发的CMS:如AdminLTE后台管理系统、Thinkcmf、ThinkSNS等。

0x03 测试环境

  • centos 7.5
  • nginx 1.14.0
  • php 7.2.10
  • thinkphp5.1beta

0x04 环境部署

查看服务开启状态
ThinkPHP5远程命令执行漏洞_第1张图片
将thinkPHP5.1源码K拷贝到nginx目录/usr/local/nginx/html
在这里插入图片描述
赋予权限chmod -R 777 thinkphp5.1/
在这里插入图片描述
检测是否部署成功
url:http://192.168.162.128/thinkphp5.1/public/index.php
ThinkPHP5远程命令执行漏洞_第2张图片

0x05 漏洞验证

payload:http://192.168.162.128/thinkphp5.1/public/index.php?s=index/\think\Request/input&filter=phpinfo&data=1
ThinkPHP5远程命令执行漏洞_第3张图片

0x06 漏洞产生原因

1. 概述

该漏洞出现的原因在于ThinkPHP5框架底层对控制器名过滤不严,从而让攻击者可以通过url调用到ThinkPHP框架内部的敏感函数,进而导致getshell漏洞。

2. 代码审计

由结果推原因
thinkphp5.1\public\index.php,17行,请求start.php
ThinkPHP5远程命令执行漏洞_第4张图片
‪thinkphp5.1\thinkphp\start.php,21行,run()函数
ThinkPHP5远程命令执行漏洞_第5张图片
thinkphp5.1\thinkphp\library\think\App.php,280行,run()函数,进行URL路由检测
在这里插入图片描述
thinkphp5.1\thinkphp\library\think\App.php,371行,path()函数
ThinkPHP5远程命令执行漏洞_第6张图片
thinkphp5.1\thinkphp\library\think\Request.php
path()函数:获取当前请求URL的pathinfo信息(不含URL后缀)并返回
ThinkPHP5远程命令执行漏洞_第7张图片
pathinfo()函数:获取当前请求URL的pathinfo信息(含URL后缀)并返回
从配置文件中获取var_pathinfo的值
ThinkPHP5远程命令执行漏洞_第8张图片
配置文件thinkphp5.1\config\app.phpvar_pathinfo的值为s
在这里插入图片描述

注意这里的$_GET[$this->config->get('var_pathinfo')],当请求报文包含 $_GET['s'],就取其值作为pathinfo,并返回pathinfo给调用函数,来传递路由信息。而$_GET['s']用户可控的
ThinkPHP5远程命令执行漏洞_第9张图片
上面将用户可控的pathinfo返回给调用函数path(),再跟进函数path()
pathinfo传递给$this->path之后返回给调用函数routeCheck()
ThinkPHP5远程命令执行漏洞_第10张图片

再跟进routeCheck()函数,得到返回值并赋值给$path,再调用check($path, $depr, $must)函数,
ThinkPHP5远程命令执行漏洞_第11张图片
跟进check($path, $depr, $must)函数,$path作为参数之一
thinkphp5.1\thinkphp\library\think\Route.php,744行,
check($path, $depr, $must)函数:检测URL路由,传递进来的参数$url是可控的
ThinkPHP5远程命令执行漏洞_第12张图片
跟踪可控变量$url
首先经过str_replace函数:将url中的/替换为|
调用check函数,url作为参数之一
ThinkPHP5远程命令执行漏洞_第13张图片
又调用check函数,检查路由;
之后创建UrlDispatch实例,$url作为参数之一传递给UrlDispatch的构造函数
在这里插入图片描述
跟进UrlDispatch的构造函数,thinkphp5.1\thinkphp\library\think\route\Dispatch.php,29行,将值传递给this->action,之后调用抽象run()函数
ThinkPHP5远程命令执行漏洞_第14张图片
\thinkphp5.1beta\thinkphp\library\think\route\dispatch\Module.php,19行,类Module继承了抽象类Dispatch,实现了函数run()
ThinkPHP5远程命令执行漏洞_第15张图片

$this->action的值传递给$result
获取控制器名
在这里插入图片描述
获取操作名
在这里插入图片描述
实例化控制器
ThinkPHP5远程命令执行漏洞_第16张图片
跟进实例化函数,‪thinkphp5.1beta\thinkphp\library\think\App.php,461行,查看实例化过程
可以看到,如果name中包含\,就将name的值赋值给class,之后返回,以此这里控制器的实例化是用户可控的,
ThinkPHP5远程命令执行漏洞_第17张图片
之后便是执行实例化后的函数,然后返回给浏览器。

0x07 参考文章

  1. https://bbs.ichunqiu.com/thread-48967-1-1.html
  2. https://paper.seebug.org/770/

你可能感兴趣的:(PHP代码审计,漏洞复现)