我的编程空间,编程开发者的网络收藏夹
学习永远不晚

FineCMS任意头像上传漏洞复现:文件的四次上传

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

FineCMS任意头像上传漏洞复现:文件的四次上传

目录

文件上传

1、文件上传完整代码

PHP代码

<?phpheader("Content-Type:text/html; charset=utf-8");require_once('pclzip.lib.php');// echo "
";// var_dump($_POST['username']);exit;// // var_dump(file_get_contents("php://input"));exit;// // var_dump($GLOBALS['HTTP_RAW_POST_DATA']);exit;// if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) {//     exit('环境不支持');// }// // 创建图片存储文件夹// $dir = 'upload/';// if (!file_exists($dir)) {//     mkdir($dir);// }function check_dir($dir){    $handle = opendir($dir);    while(($f = readdir($handle)) !== false){        if(!in_array($f, array('.', '..'))){            if(is_dir($dir.$f)){                check_dir($dir.$f.'/');             }else{                $ext = strtolower(substr(strrchr($f, '.'), 1));                if(!in_array($ext, array('jpg', 'gif', 'png'))){                    unlink($dir.$f);                }            }        }    }}// // 创建图片存储的临时文件夹// $temp = $dir.'member/1/';// if (!file_exists($temp)) {//     mkdir($temp);// }// $filename = $temp.'avatar.zip'; // 存储flashpost图片// file_put_contents($filename, $GLOBALS['HTTP_RAW_POST_DATA']);// //第三次绕过// // $zip=new ZipArchive;//新建一个ZipArchive的对象 // // if(!$zip->open($filename)){// //     //check_dir($dir);// //     exit("fail to open zip file");// // }// // if(!$zip->extractTo($temp)) {// //     exit("fail to extract zip file");// // }// $archive = new PclZip($filename);// if ($archive->extract(PCLZIP_OPT_PATH, $temp, PCLZIP_OPT_REPLACE_NEWER) == 0) {//        check_dir($dir);//        exit("解压失败");// }// check_dir($dir);// exit('success');$file = $_FILES['file'];if (!$file) {    exit("请勿上传空文件");}$name = $file['name'];$dir = 'upload/';$ext = strtolower(substr(strrchr($name, '.'), 1));//递归删除  zip  1   web.php// function check_dir($dir)// {//     $handle = opendir($dir);//     while (($f = readdir($handle)) !== false) {//         if (!in_array($f, array('.', '..'))) {//             $ext = strtolower(substr(strrchr($f, '.'), 1));//             if (!in_array($ext, array('jpg', 'gif', 'png'))) {//                 unlink($dir . $f);//             }//         }//     }// }// mkdir($dir);if (!is_dir($dir)) {    mkdir($dir);}$temp_dir = $dir.md5(time(). rand(1000,9999)).'/';// $temp_dir = $dir . 'member/1/';if (!is_dir($temp_dir)) {    mkdir($temp_dir);}if (in_array($ext, array('zip', 'jpg', 'gif', 'png'))) {    if ($ext == 'zip') {        // $zip = new ZipArchive;        // if(!$zip->open($file['tmp_name'])) {        //     echo "fail";        //     return false;        // }        // if(!$zip->extractTo($temp_dir)) {        //     check_dir($temp_dir);        //     exit("fail to extract");        // }        $archive = new PclZip($file['tmp_name']);        // foreach($archive->listContent() as $value){        //     $filename = $value["filename"];        //     if(preg_match('/\.php$/', $filename)){        //          exit("压缩包内不允许含有php文件!");        //      }        // }                if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {            check_dir($dir);            exit("解压失败");        }        check_dir($temp_dir);        exit('上传成功!');    } else {        move_uploaded_file($file['tmp_name'], $temp_dir . '/' . $file['name']);        check_dir($temp_dir);        exit('上传成功!');    }} else {    exit('仅允许上传zip、jpg、gif、png文件!');}

HTML代码

DOCTYPE html><html lang="zh"><head>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <meta http-equiv="X-UA-Compatible" content="ie=edge" />    <title>文件上传章节练习题title>    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">    <style type="text/css">        .login-box{            margin-top: 100px;            height: 500px;            border: 1px solid #000;        }        body{            background: white;        }        .btn1{            width: 200px;        }        .d1{            display: block;            height: 400px;        }    style>head><body>    <form method="post" action="upload.php" enctype="multipart/form-data">        <input type="file" name="file" value=""/>        <input type="submit" name="submit" value="upload"/>    form>body>html>

2、第一次上传 【无递归删除】

1、PHP代码【含代码解析】

header("Content-Type:text/html; charset=utf-8");require_once('pclzip.lib.php');$file = $_FILES['file'];if (!$file) {    exit("请勿上传空文件");}$name = $file['name'];$dir = 'upload/';$ext = strtolower(substr(strrchr($name, '.'), 1)); //拿出最后的后缀为.的后面内容function check_dir($dir){    $handle = opendir($dir);    while (($f = readdir($handle)) !== false) {        if (!in_array($f, array('.', '..'))) {            $ext = strtolower(substr(strrchr($f, '.'), 1));            if (!in_array($ext, array('jpg', 'gif', 'png'))) {                   unlink($dir . $f);  //直接删除            }        }    }}$temp_dir = $dir . 'member/1/';   //临时文件,这里1其实应该代表有用户IDif (!is_dir($dir)) {       //判断文件有无文件    mkdir($dir);}if (in_array($ext, array('zip', 'jpg', 'gif', 'png'))) { //判断文件后缀    if ($ext == 'zip') {     $archive = new PclZip($file['tmp_name']);//打开压缩包,后面进行解压    if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {            check_dir($dir);            exit("解压失败");        }        check_dir($temp_dir);  //运用check_dir函数,判断文件把不符合规则的文件类型删除        exit('上传成功!');    } else {        move_uploaded_file($file['tmp_name'], $temp_dir . '/' . $file['name']);       // check_dir($temp_dir);        exit('上传成功!');    }} else {    exit('仅允许上传zip、jpg、gif、png文件!');}

2、简述代码整体运行过程与破解

上述过程就是上传压缩包,然后打开压缩包看里面文件类型进行删除与保留。

此过程想要上传恶意代码很简单,因为它打开压缩包打开的内容包括各种文件。但是它只扫描它打开的这层文件中的内容。即不会扫描文件夹里的内容。

3、测试代码

1、压缩包包含php与图片文件上传 【被删除PHP文件】

在这里插入图片描述

上传压缩包,并且尝试在内容里面加入PHP文件

在这里插入图片描述

上传文件结果

在这里插入图片描述

查看结果:创建了upload文件,并且发现在文件夹1中只有图片,成功过滤了PHP文件

在这里插入图片描述
在这里插入图片描述

2、压缩包包含文件夹与图片文件上传 【没有删除PHP文件】

由代码查看发现他编码进行递归查询,如此就不会第二次打开文件夹的。为此我们才有包含文件夹进行绕过删除文件。

创建文件夹web1
在这里插入图片描述

将web1文件压缩同图片文件一起压缩
在这里插入图片描述
上传压缩包
在这里插入图片描述

弹出的第二行错显示了 Permission denied,表示它没有权限删除我们创建的文件夹web1。

查看上传内容:文件夹没有被删除,但是php文件被删除了。
在这里插入图片描述

继续查看web1文件夹的内容

在这里插入图片描述
我们发现web1文件没有删除为此就绕过删除了。

这不用时间竞争型漏洞,因为要试很多次。【也可以用,只是麻烦了】
有更好的把上传的压缩包包含文件夹
unlink:直接删除 【只能删除文件不能删除文件夹,因为没有递归删除】

4、防御第一次绕过

既然我们知道了它没有进行递归查询,没有检测文件夹内容。我们就修改函数使用递归

function check_dir($dir){    $handle = opendir($dir);    while(($f = readdir($handle)) !== false){        if(!in_array($f, array('.', '..'))){            if(is_dir($dir.$f)){//判断是否还有文件夹                check_dir($dir.$f.'/');   //再次调用函数             }else{                $ext = strtolower(substr(strrchr($f, '.'), 1));                if(!in_array($ext, array('jpg', 'gif', 'png'))){                    unlink($dir.$f);                }            }        }    }}

函数内再次检测了文件,对文件夹进行检测。

3、第二次上传 【有递归查询】

1、PHP 代码 【修改第一次上传的函数内容】

function check_dir($dir){    $handle = opendir($dir);    while(($f = readdir($handle)) !== false){        if(!in_array($f, array('.', '..'))){            if(is_dir($dir.$f)){//判断是否还有文件夹                check_dir($dir.$f.'/');   //再次调用函数             }else{                $ext = strtolower(substr(strrchr($f, '.'), 1));                if(!in_array($ext, array('jpg', 'gif', 'png'))){                    unlink($dir.$f);                }            }        }    }}

2、简述代码整体运行过程与破解

上述代码进行解压压缩包,对文件再次检索查看是否有文件夹。当有文件夹再次运行函数打开文件夹,再在文件夹中再次检索。直到没有文件夹检索为至。

这个方法虽然解决了第一次上传文件夹不背扫描问题,但是并没有解决第一个上传仍然存在的时间竞争漏洞。为此我们可以采用时间竞争漏洞绕过

3、测试代码

1、压缩包包含文件夹与图片文件上传 【PHP文件被删除】

选择新建文件夹.zip
在这里插入图片描述
成功上传我们查看文件夹web1 是否内部php被过滤
在这里插入图片描述
我们发现它成功过滤了文件夹内的PHP文件
在这里插入图片描述

2、时间竞争型漏洞绕过
1、编写竞争代码

在删除之前访问上传的php文件,从而执行上传文件中的php代码。

竞争型文件上传过程介绍
文件上传过程:
服务器获取文件>>>保存上传临时文件>>>重命名移动临时文件

编写PHP代码,将要删除前重命名实现移动文件【跳三层到xss_location目录】

fputs(fopen('../../../payload.php','w'),'');?>

上传web1.zip 【其中1.php代码修改为了上述代码】
在这里插入图片描述

2、Burp Suite抓取上传包
1、准备工作

开启抓包
在这里插入图片描述
将手工代理开启【代理端口与Burp Suite设置的一样】
在这里插入图片描述

在这里插入图片描述

将本地地址改为本机IP一致
在这里插入图片描述

2、开始抓包

上传文件抓包
在这里插入图片描述
上图成功被拦截,并且拦截的是压缩包 【拦截中的PK代表压缩包】
在这里插入图片描述
将其抓取内容放到爆破中
在这里插入图片描述
先clear掉符号
在这里插入图片描述
随后找个数字进行添加字符
在这里插入图片描述
让其运行2000次
在这里插入图片描述

如果想手动访问也可以就要访问169.254.2.70/xss_location/mermber/1/1/web1.php,手动刷新页面。【要关拦截】

开始访问
在这里插入图片描述

结果查看
在这里插入图片描述

4、防御第二次上传

因为时间竞争型漏洞是猜到了存储文件的,为此我们将其创建文件名方式进行修改。使用对文件随机数进行命名。

$temp_dir = $dir.md5(time(). rand(1000,9999)).'/';// $temp_dir = $dir . 'member/1/';

3、第三次上传 【随机命名防止时间竞争漏洞】

1、PHP代码改进 【文件随机命名】

$temp_dir = $dir.md5(time(). rand(1000,9999)).'/';// $temp_dir = $dir . 'member/1/';

2、简述代码整体运行过程与破解

不同之前是将上传文件创建的 文件夹随机命令。导致无法猜测到文件名进行恶意代码上传。
在这里插入图片描述

从结果上来看我们确实是无法在解压后运用条件绕过了删除,那我们就可以考虑在解压过程中下手。即实现当解压一半出错,它直接跳转解压失败不进行条件判断删除PHP文件了。

3、解压一个出错的zip【知识点补充】

这个问题其实需要看具体情况,看解压的那个程序的容忍程度,我这里就以两个解压的程序作为例子:

  1. Windows下的7zip
  2. PHP自带的ZipArchive库
  3. 先说7zip。7zip的容忍度很低,只要压缩包中某一个文件的CRC校验码出错,就会报错退出。 如何修改压缩包里文件的CRC校验码呢?可以使用010editor。
    在这里插入图片描述
    4.我们先准备两个文件。【简单点我就用现在的文件夹】我们用010editor打开zip,可以看到右下角有这个文件的格式信息,它被分成几部分,我们打开第6部分【png那个】,其中有个deCrc,我们随便把值改成其他的值,然后保存.
    在这里插入图片描述

修改内容并且保存
在这里插入图片描述

进行解压
在这里插入图片描述

如此我们发现出错了。但是PHP依旧解压了
此时用7zip解压就会出错,解压出的PHP是完好的,另一个文件是图片出现错所以无法显示了,【如果是txt,会显示文件但是因为报错内容无法显示就只有txt文件】
在这里插入图片描述

接下来我们说一下PHP的解压。
采用一个PHP的解压代码测试【为了方便我把压缩包移动到同级目录下】
在这里插入图片描述

    function unzip($zipname, $path) {        $zip = new ZipArchive;        if(!$zip->open($zipname)) {            echo "fail";            return false;        }        if(!$zip->extractTo($path)) {            echo "fail to extract";            return false;        }        $zip->close();        return true;    }    if(unzip('./web1.zip', './')) {        echo "success zip";    }else {        echo "failt to unzip";    }

采用在Windows中使用PHP来解压
在这里插入图片描述
他成功解压了并且中目录里
在这里插入图片描述

如果压缩入txt文件【文件内容为zzzzzz,压缩包为hhhh.zip,修改php内容文件为hhhh.zip】 同样先修改deCrc
在这里插入图片描述
依旧成功
在这里插入图片描述
并且不同Windows会是txt文件没有内容
在这里插入图片描述

综上我们发现在PHP中是好像无采用压缩包报错绕过,但是如果文件内容无法修改就文件

这也说明ZipArchive的容忍度比较高。 那么我们又如何让ZipArchive出错呢?最简单的方法,我们可以在文件名上下功夫。
比如,Windows下不允许文件名中包含冒号(:),我们就可以在010editor中将2.txt的deFileName属性的值改成“2.tx:”,

在这里插入图片描述
再次解压
在这里插入图片描述
发现对文件解压时出错了。【目录下也解压出来php,没有txt】
Linux下也有类似的方法,我们可以将文件名改成5个斜杠(/)

总结;
1.Windows系统下7zip的容忍度很低,只要压缩包中某一个文件的CRC校验码出错,就会报错退出
2.PHP代码中 .。
使用zip解压时deCrc,我们随便把值改成其他的值,然后保存就可以出错。
使用7z情况下修改文件名Windows下不允许文件名中包含冒号(:),我们就可以在010editor中将2.txt的deFileName属性的值改成“2.tx:”
3.linux系统将文件名改成5个斜杠(/)【前提这个压缩至少有五个字符可以修改】

4、测试代码

1、上传错误压缩包绕过删除

采用上述的压缩包上传。
因为使用PHP类要修改一下

// //第三次绕过$zip=new ZipArchive;//新建一个ZipArchive的对象 if(!$zip->open($filename)){    //check_dir($dir);    exit("fail to open zip file");}if(!$zip->extractTo($temp)) {    exit("fail to extract zip file");}// $archive = new PclZip($filename);// if ($archive->extract(PCLZIP_OPT_PATH, $temp, PCLZIP_OPT_REPLACE_NEWER) == 0) {//        check_dir($dir);//        exit("解压失败");// }

结果表示未能提取【上传了hhhh.zip,包含php文件,与txt文件】
查看上传文件是否成功有php
在这里插入图片描述

发现成功上传php,但是因为txt出错没有被上传。并且因为出错绕过了判断而没有删除

5、防御第三次绕过

既然我们知道他是在是解压过程在避开递归删除
如此对应防御:如果在解压到php后就先递归删除再解压下一个文件,就算退出但是第一个已经递归删除过了就解决问题了

  if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {            check_dir($dir); //解压成功一个后进行递归删除            exit("解压失败");        }

4、第四次绕过 【在之前基础上对解码后的文件进行递归删除】

1、PHP代码 【在解码后进行递归删除】

  if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {            check_dir($dir); //解压成功一个后进行递归删除            exit("解压失败");        }

2、简述代码整体运行过程与破解

代码的之前代码基础上当解码失败后,不会直接保存而是再进行删除递归后才真正的结束、

相较于第三次的防御解决方法 可以尝试命名php为的value为…/…/aaa.php
即解压完后修改名称,如此是解压到上级目录 使用工具修改aaaaaaaaa.php改为…/…/aaa.php

3、测试代码

1、上传修改了value的php文件

同之前一样修改【改为txt:,与…/…/aaa.php】

在这里插入图片描述
php的修改只要是有aaaaaaaaaaaaaa.php原来名字的文件都修改

在这里插入图片描述
查看上上级目录是否有对应php文件
在这里插入图片描述

总结

第一次绕过代码没有文件再次检测,采用传包含文件夹的压缩包绕过或使用时间竞争漏洞绕过
2、第二个绕过代码添加了递归对文件夹再次检测,但由于没有间竞争漏洞绕过问题。使用间竞争漏洞绕过
3、第三次绕过代码进行随机命名文件无法猜文件名间竞争漏洞绕过失效,但是可以采用解压一半报错保存php文件
4、第四次绕过代码对报错保留的文件进行了递归删除,但是我们可以欺骗系统将解码的文件判定为上级目录文件规避了递归在当前目录下是所有检测。

其实这种漏洞补一处出现处,要从根本解决。
根本原因:它是在网站的根目录下解压文件,用户可以访问。
解决:为此在临时文件夹中解压,再把需要的文件提取到网站目录下。

来源地址:https://blog.csdn.net/Miracle_ze/article/details/126347577

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

FineCMS任意头像上传漏洞复现:文件的四次上传

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Ueditor编辑器任意文件上传漏洞

一、漏洞描述 UEditor是一款所见即所得的开源富文本编辑器,具有轻量、可定制、用户体验优秀等特点,被广大WEB应用程序所使用。本次爆出的高危漏洞属于.NET版本,其它的版本暂时不受影响。漏洞成因是在抓取远程数据源的时候未对文件后缀名做验
2023-08-18

漏洞挖掘 | 某OA系统任意文件上传

写代码写到心烦,抽空来审审某.net开发的oa源码吧,从完整利用链分析到利用getshell
漏洞挖掘 | 某OA系统任意文件上传
2024-05-11

「漏洞预警」Apache Flink 任意 Jar 包上传导致远程代码执行漏洞复现

漏洞描述Apache Flink是一个用于分布式流和批处理数据的开放源码平台。Flink的核心是一个流数据流引擎,它为数据流上的分布式计算提供数据分发、通信和容错功能。Flink在流引擎之上构建批处理,覆盖本地迭代支持、托管内存和程序优化。近日有安全研究人员发
「漏洞预警」Apache Flink 任意 Jar 包上传导致远程代码执行漏洞复现
2017-10-17

网站漏洞测试 文件上传漏洞的安全渗透与修复

很多客户网站以及APP在上线运营之前都会对网站进行渗透测试,提前检测网站是否存在漏洞,以及安全隐患,避免因为网站出现漏洞而导致重大的经济损失,客户找到我们SINE安全做渗透测试服务的时候,我们都会对文件上传功能进行全面的安全测试,包括文件上
2023-06-03

Apache Flink 任意 Jar 包上传导致远程代码执行漏洞复现问题(漏洞预警)

漏洞描述 Apache Flink是一个用于分布式流和批处理数据的开放源码平台。Flink的核心是一个流数据流引擎,它为数据流上的分布式计算提供数据分发、通信和容错功能。Flink在流引擎之上构建批处理,覆盖本h
2022-06-04

基于SpringBoot上传任意文件功能的实现

一、pom文件依赖的添加 org.springframework.boot spring-boot
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录