Headline
CVE-2021-3267: File upload vulnerability leads to getshell · Issue #6 · Kitesky/KiteCMS
File Upload vulnerability found in KiteCMS v.1.1 allows a remote attacker to execute arbitrary code via the uploadFile function.
Log in to the website backend
url:/index.php/admin/passport/login.html
Add php file extension
System -> site config -> upload ->image extension
Upload malicious scripts through the upload interface
Use burp to bypass js detection
Get the path of the uploaded file
Get shell
Code audit
/application/admin/controller/Upload.php uploadFile()
public function uploadFile() { // 获取表单上传文件 $file = Request::file(‘file’);
$uploadObj = new UploadFile($this->site_id); $ret = $uploadObj->upload($file, ‘image’);
if ($ret) { return $this->response(200, '上传成功’, $ret); } else { return $this->response(201, $uploadObj->getError()); } }
follow up function :upload()
/application/common/model/UploadFile.php
According to the 16th line of Upload.php, the second parameter of the upload function is image
public function upload($file, $fileType = ‘image’) { // 验证文件类型及大小 switch ($fileType) { case 'image’: $result = $file->check([‘ext’ => $this->config[‘upload_image_ext’], ‘size’ => $this->config[‘upload_image_size’]*1024]); if(empty($result)){ // 上传失败获取错误信息 $this->error = $file->getError(); return false; } break; …
follow up function: check()
thinkphp/library/think/File.php
$rule has been modified to: {ext=> "jpg,png,gif,php", size=>2097152}
public function check($rule = []) { $rule = $rule ?: $this->validate;
if ((isset($rule[‘size’]) && !$this->checkSize($rule[‘size’])) || (isset($rule[‘type’]) && !$this->checkMime($rule[‘type’])) || (isset($rule[‘ext’]) && !$this->checkExt($rule[‘ext’])) || !$this->checkImg()) { return false; }
return true; }
File size will not exceed the maximum,php in the whitelist of file extensions,$rule[‘type’] is not set,then follow the function:checkImg()
public function checkImg() { $extension = strtolower(pathinfo($this->getInfo(‘name’), PATHINFO_EXTENSION));
/\* 对图像文件进行严格检测 \*/
if (in\_array($extension, \['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'\]) && !in\_array($this\->getImageType($this\->filename), \[1, 2, 3, 4, 6, 13\])) {
$this\->error = 'illegal image files';
return false;
}
return true;
}
The value of variable $extension is php,so the first half of the conditional statement is false.
The function named checkImg returns true,and function check() return true.