前言
作者:Ho1aAs
博客:https://blog.csdn.net/xxy605
一、漏洞演示
进入PHPOK的后台,右上角先切换到开发模式
进入左侧的应用管理界面
点击安装应用——导入应用,上传一个zip压缩的php文件
# 1.php
<?php phpinfo();?>
轻易完成了上传,访问_app/1.php就能发现文件已经被解压了,而且没有改名
二、漏洞分析
导入应用并上传的功能首先调用了zip函数接收压缩包
这一步只限定了上传文件类型是zip,而不限制其内容,没有对内容进行过滤和判断,对任何zip都保存
/**
* 制作压缩包
* @参数 $dir,支持单个文件,目录及数组
* @参数 $saveName,保存的ZIP文件名
**/
public function zip($dir, $saveName)
{
if(@!function_exists('gzcompress')){
return false;
}
ob_end_clean();
$filelist = array();
if(is_array($dir)){
$filelist = $dir;
}else{
if(!file_exists($dir)){
return false;
}
if(is_file($dir)){
$filelist = array($dir);
}else{
$this->filelist($filelist,$dir);
}
}
if(count($filelist) < 1){
return false;
}
if(class_exists('ZipArchive')){
$obj = new ZipArchive();
$obj->open($saveName,ZipArchive::OVERWRITE|ZipArchive::CREATE);//创建一个空的zip文件
foreach($filelist as $file){
if(!file_exists($file) || !is_file($file)){
continue;
}
$name = substr($file,strlen($this->dir_root));
$obj->addFile($file,$name);
}
$obj->close();
return true;
}
foreach($filelist as $file){
if(!file_exists($file) || !is_file($file)){
continue;
}
$fd = fopen($file, "rb");
$content = @fread($fd, filesize($file));
fclose($fd);
$file = substr($file, strlen($this->dir_root));
if(substr($file, 0, 1) == "\\" || substr($file, 0, 1) == "/"){
$file = substr($file, 1);
}
$this->addFile($content, $file);
}
$out = $this->file();
$fp = fopen($saveName, "wb");
fwrite($fp, $out, strlen($out));
fclose($fp);
}
zip压缩包上传成功后,调用unzip函数对其解压
这一步也是单纯的解压,并没有对压缩包内容进行过滤就解压到了根目录
public function unzip($file,$to='')
{
if(class_exists('ZipArchive')){
$zip = new ZipArchive;
$zip->open($file);
$zip->extractTo($to);
$zip->close();
return true;
}
# ...(略)
三、利用
将任意文件添加到zip压缩文件,通过该功能上传zip、解压到根目录
四、修复
建议对上传的非应用安装包进行检查,解压时过滤危险文件类型、内容等
五、总结
由于以下问题导致该漏洞的产生:
- 对安装应用功能的非法利用
- 上传、解压zip文件无过滤
完
转载:https://blog.csdn.net/Xxy605/article/details/117512930
查看评论