继续进行代码审计,本次选择的是XiaoCMS
0x01 简单分析
这个CMS采用的MVC模式,先看下入口文件
index.php
1 2 3 4 5 6 7 8
| <?php
define('XIAOCMS_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR); include XIAOCMS_PATH . 'core/xiaocms.php'; xiaocms::run();
|
包含了xiaocms.php
有一个安全处理函数,将’/‘和’.’替换为’’
1 2 3
| private static function _safe($str) { return str_replace(array('/', '.'), '', $str); }
|
还有一个读取文件的函数,不过用在了加载控制器中了,也没什么用
进入Base.class.php
重新定义了GET和POST方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static function get($string) { if (!isset($_GET[$string])) return null; if (!is_array($_GET[$string])) return htmlspecialchars(trim($_GET[$string])); return null; }
public static function post($string) { if (!isset($_POST[$string])) return null; if (!is_array($_POST[$string])) return htmlspecialchars(trim($_POST[$string])); $postArray = self::array_map_htmlspecialchars($_POST[$string]); return $postArray; }
|
htmlspecialchars会将<>和双引号过滤
0x02 后台任意文件上传
看到有upload.class.php,进去看下,有个upload函数
1 2 3 4 5 6 7 8
| public function upload($file_upload, $file_name) { if (!is_array($file_upload) || empty($file_name)) return false; $this->parse_init($file_upload); if (!@move_uploaded_file($this->file_name['tmp_name'], $file_name)) return '文件上传失败,请检查服务器目录权限'; return true; }
|
跟进parse_init函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| protected function parse_init($file) { $this->file_name = $file; if ($this->file_name['size'] > $this->limit_size) { echo '您上传的文件:' . $this->file_name['name'] . ' 大小超出上传限制!'; exit(); } if ($this->limit_type) { if (!in_array($this->get_file_ext(), $this->limit_type)) { echo '您上传的:' . $this->file_name['name'] . ' 文件格式不正确!'; exit(); } } return true; }
|
$this->limit_type通过set_limit_type函数获取,搜索set_limit_type
在admin/controller/uploadfile.php中发现upload函数
1 2 3 4 5 6 7
| private function upload($fields, $type, $size) { $upload = xiaocms::load_class('upload'); $ext = strtolower(substr(strrchr($_FILES[$fields]['name'], '.'), 1)); …… …… $result = $upload->set_limit_size(1024*1024*$size)->set_limit_type($type)->upload($_FILES[$fields],XIAOCMS_PATH.$filenpath); ……
|
同样在admin/controller/uploadfile.php中发现uploadify_uploadAction函数
1 2 3 4 5 6 7 8 9 10 11
| /![10](D:\hexo\source\_posts\XiaoCMS漏洞分析\10.png)** * uploadify_upload */ public function uploadify_uploadAction() { $type = $this->get('type'); $size = (int)$this->get('size'); if ($this->post('submit')) { $data = $this->upload('file', explode(',', $type), $size); if ($data['result']) echo $data['path']; } }
|
$this->limit_type与$this->limit_size都可以控制了,接下来构造upload.html
上传shell
0x03 后台模板写shell
漏洞位于admin/controller/template.php
editAction函数
1 2 3 4 5 6 7 8 9
| public function editAction() { …… if ($this->post('submit')) { file_put_contents($filepath, htmlspecialchars_decode($this->post('file_content')), LOCK_EX); $this->show_message('提交成功',1); } $filecontent = htmlspecialchars(file_get_contents($filepath)); include $this->admin_tpl('template_add'); }
|
前面提到过get post到的内容都被htmlspecialchars转义了,而这里又用htmlspecialchars_decode反转义了
0x04 总结
htmlspecialchars和MySQL PDO是真的难受……