0x00 环境准备
XYHCMS官网:http://www.xyhcms.com/
网站源码版本:XYHCMS V3.5(2017-12-04 更新)
程序源码下载:http://www.xyhcms.com/Show/download/id/2/at/0.html
测试网站首页:
0x01 代码分析
1、文件位置: /App/Manage/Controller/SystemController.class.php 第194行开始:
1. public function site() {
2. if (IS_POST) {
3. $data = I('config', array(), 'trim');
4. foreach ($data as $key => $val) {
5. if (stripos($val, '<?php') !== false) {
6. $data[$key] = preg_replace('/<\?php(.+?)\?>/i', '', $val);
7. }
8. }
9. $data['CFG_IMGTHUMB_SIZE'] = strtoupper($data['CFG_IMGTHUMB_SIZE']);
10. 10. $data['CFG_IMGTHUMB_SIZE'] = str_replace(array(',', 'X'), array(',', 'X'), $data['CFG_IMGTHUMB_SIZE']);
11. 11. if (empty($data['CFG_IMGTHUMB_SIZE'])) {
12. 12. $this->error('缩略图组尺寸不能为空');
13. 13. }
14. 14. if (!empty($data['CFG_IMAGE_WATER_FILE'])) {
15. 15. $img_ext = pathinfo($data['CFG_IMAGE_WATER_FILE'], PATHINFO_EXTENSION);
16. 16. $img_ext = strtolower($img_ext);
17. 17. if (!in_array($img_ext, array('jpg', 'gif', 'png', 'jpeg'))) {
18. 18. $this->error('水印图片文件不是图片格式!请重新上传!');
19. 19. return;
20. 20. }
21. 21. }
22. 22. foreach ($data as $k => $v) {
23. 23. $ret = M('config')->where(array('name' => $k))->save(array('s_value' => $v));
24. 24. }
25. 25. if ($ret !== false) {
26. 26. F('config/site', null);
27. 27. $this->success('修改成功', U('System/site'));
28. 28. } else {
29. 29. $this->error('修改失败!');
30. 30. }
31. 31. exit();
32. 32. }
这段函数中对提交的参数进行处理,然后写入配置文件。注意看红色部分代码,接收到的参数进行正则匹配,如果检测’<?php’,就通过正则将这部分脚本代码替换为空,但显然这样过滤是不严谨的,存在被绕过的情况。PHP有多个代码风格,标准的”<?php ?>”被过滤,那么我们可以通过变换代码风格,达到绕过代码过滤,写入配置文件,导致任意代码执行,最后控制网站服务器权限。
1. PHP代码风格:
2. 标准风格:<?php ?>
3. ASP风格 :<% %>
4. 长风格:<script language='php'></script>
0x02 漏洞利用
1、 登录网站后台,在系统设置—网站设置—会员配置:
提交构造的PHP长风格的一句话木马,绕过代码过滤,写入配置文件,达到任意代码执行的目的。
2、 通过访问http://127.0.0.1/App/Runtime/Data/config/site.php,成功触发代码执行漏洞。
3、 利用菜刀连接,控制网站服务器权限:
0x03 修复建议
1、写入配置文件前,对特殊字符(如<、>等)进行htmlencode处理;
2、全局配置可考虑写入数据库进行调用。
最后
欢迎关注个人微信公众号:Bypass--,每周原创一篇技术干货。