ThinkPHP3.2.X RCE漏洞 分析,复现
漏洞利用条件:
assign方法变量可控 如:
漏洞分析
tp3基础
assign两种调用方法:
- 传入一个数组如assign(array(‘a’=>‘haha’));
- 传入两个变量assign(‘a’,‘haha’);
暂且将a和haha称为键值对, assign方法传入的键值对可以在模板中通过{$变量名}调用 如在模板中使用{$a}即可取到haha
display方法,显示模板内容,参数是模板位置,如果参数为空调用默认模板
分析
tp3在解析模板时,会生成一个php缓存文件$_filename ,将解析后的模板写入这里,然后再include $_filename 解析过程中将 {$a} 变成 :<?php echo ($a); ?> ,在这之前使用extract,生成变量$a=haha , 这样就达到了模板可以直接调用键值对的效果
缓存变量名是$_filename 所以,如果我在assign传入(’_filename’,‘日志’),那extract就会导致变量覆盖,然后include日志文件 http://xxx.com?s=<?php phpinfo();?> ,就会触发报错,将url写入日志,然后include日志,getshell
复现的时候发现个问题,写入日志时,直接访问http://xxx.com?s=<?php phpinfo();?> 尖括号会被浏览器编码 burp抓包改下就好了
代码调试
如图,获取一个test参数,assign,然后display 访问:http://tp3.cc/?test[_filename]=./Application/Runtime/Logs/Common/21_08_03.log
assign
- Controller的assign调用view的assign
- assgin将键值对存到tVar里
display
- Controller的display调用view的display
- 调用fetch方法
- tVar值传给了params[‘var’],然后传给了listen
- 跟踪params,调用了exec
- 继续跟踪发现调用了Behavior\ParseTemplateBehavior->run
- 变量传给了
$data ,又将$_data['var'] 传给了fetch - 又load
- 终于
extract变量覆盖,,这里include的就是日志文件
2. assgin将键值对存到tVar里
display
- Controller的display调用view的display
- 调用fetch方法
- tVar值传给了params[‘var’],然后传给了listen
- 跟踪params,调用了exec
- 继续跟踪发现调用了Behavior\ParseTemplateBehavior->run
- 变量传给了$data,又将$_data[‘var’]传给了fetch
- 又load
- 终于
extract变量覆盖,,这里include的就是日志文件
|