当前位置: 首页 > news >正文

网络安全基础之php开发文件上传的实现

前言

php是网络安全学习里必不可少的一环,简单理解php的开发环节能更好的帮助我们去学习php以及其他语言的web漏洞原理

正文

在正常的开发中,文件的功能是必不可少,比如我们在论坛的头像想更改时就涉及到文件的上传等等文件功能。但也会出现漏洞,或者一些bug。这部分是php开发部分的文件上传、删除部分,为啥不写完?感觉有点多。

文件上传代码

在开发中,对于这种功能型的代码一般有两种办法来开发。一种比较复杂,另外一种比较简单。

自己写代码

这种办法是比较复杂、比较费时费力的。甚至在某些情况下是单纯的吃力不讨好。比如你花几个星期开发一个文本编辑器,最后开发出的文本编辑器性能还不怎么样,但是开源社区或者其他地方有符合你最终需求的文本编辑器代码,性能还优秀,这种情况下就真的吃力不讨好了。

PS:在开发时一点要做好技术选型这些,尽量避免重复造轮子
创建一个file_upload.php文件来实现一个简单文件上传功能,先编写一个html页面来方便查看结果,在file_index.php中写入下面的html代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Head</title><link rel="stylesheet" href="index.css">
</head>
<body>
<div class="header"><a href="index.html" class="logo"><h1>wushiyiwuzhong</h1></a><nav class="navbar"><ul><li><a href="#">文件功能导航</a></li><li><a href="#">文件上传</a></li><li><a href="#">文件下载</a></li><li><a href="#">文件删除</a></li><li><a href="#">文件读取</a></li><li><a href="#">文件写入</a></li></ul></nav>
</div>
<div class="content"></div>
</body>
</html>

页面展示效果如下:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接下来我们开始实现简单的文件上传功能,在file_upload.php中编写代码,同样,我们先设计前端代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Head</title><link rel="stylesheet" href="index.css">
</head>
<body>
<div class="header"><a href="index.html" class="logo"><h1>wushiyiwuzhong</h1></a><nav class="navbar"><ul><li><a href="file_index.php">文件功能导航</a></li><li><a href="file_upload.php">文件上传</a></li><li><a href="#">文件下载</a></li><li><a href="#">文件删除</a></li><li><a href="#">文件读取</a></li><li><a href="#">文件写入</a></li></ul></nav>
</div>
<div class="content">
<h1>文件上传 功能页面</h1>
<!--  编写form表单上传文件  --><form action="" method="post"><!-- action留空,由当前页面处理  --><input type="file" name="file"><!--  文件上传框  --><input type="submit" name="上传"><!--  提交按钮 --></form>
</div>
</body>
</html>

页面效果如下:

开始php后端部分的编写,现在前端这些代码只负责让用户上传文件,并不负责验证这个是不是病毒等等有害文件、能不能上传、上传后放在那里。像后面这些功能都是有后端决定的。

前置知识

在PHP中,文件上传功能的实现步骤:
(1)在网页中上传表单,单击“上传”按钮后,选择的文件数据将发送到服务器。
(2)用$_FILES获取上传文件有关的各种信息。
(3)用文件上传处理函数对上传文件进行后续处理。

说明:
(1)如果表单中有文件上传域,则定义表单时必须设置enctype=“multipart/form-data”,且必须为POST方式发送。
(2)限制文件大小可在表单中添加一个隐藏域,该隐藏域必须放在文件上传域之前,否则会设置失效。

若文件上传域的name属性值为upfile,则可以使用$_FILES[‘upfile’]访问文件的有关信息。
相关信息:
$_FILES[‘upfile’][‘name’]; //客户端上传文件的原名称,不包含路径
$_FILES[‘upfile’][‘type’]; //上传文件的MIME类型
$_FILES[‘upfile’][‘tmp_name’]; //已上传文件在服务器端保存的临时文件名,包含路径
$_FILES[‘upfile’][‘error’]; //上传文件出现的错误号,为一个整数
F I L E S [ ′ u p f i l e ′ ] [ ′ s i z e ′ ] ; / / 已上传文件的大小,单位为字节说明:若同时上传多个文件,则上传域的 n a m e 属性值应为 u p f i l e [ ] , 此时 _FILES['upfile']['size']; //已上传文件的大小,单位为字节 说明:若同时上传多个文件,则上传域的name属性值应为upfile[],此时 FILES[upfile][size];//已上传文件的大小,单位为字节说明:若同时上传多个文件,则上传域的name属性值应为upfile[],此时_FILES变成三维数组,保存第一个文件名的数组元素是$_FILES[‘upfile’][‘name’][0]。

保存上传文件到指定目录
move_uploaded_file(文件原来的路径和文件名,文件的目的路径和文件名);
功能说明:
(1)将上传的文件移动到网站指定目录内,并为它重命名。
(2)检查并确保由第一个参数指定的文件是合法的上传文件(即通过HTTP POST上传机制所上传),这对于网站安全是至关重要的。

下面是具体的代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Head</title><link rel="stylesheet" href="index.css">
</head>
<body>
<div class="header"><a href="index.html" class="logo"><h1>wushiyiwuzhong</h1></a><nav class="navbar"><ul><li><a href="#">文件功能导航</a></li><li><a href="#">文件上传</a></li><li><a href="#">文件下载</a></li><li><a href="#">文件删除</a></li><li><a href="#">文件读取</a></li><li><a href="#">文件写入</a></li></ul></nav>
</div>
<div class="content">
<h1>文件上传 功能页面</h1>
<!--  编写form表单上传文件  --><form action="" method="post" enctype="multipart/form-data"><!--enctype进行编码传输--><input type="file" name="file"><!--name参数--><input type="submit" name="submit" value="提交"></form>
</div>
</body>
</html><?php//获取上传文件名
@$file_name=$_FILES['file']['name'];
//获取上传文件类型
@$file_type=$_FILES['file']['type'];
//获取上传文件大小
@$file_size=$_FILES['file']['size'];
//获取上传文件临时文件名
@$file_tmpname=$_FILES['file']['tmp_name'];
//获取上传文件是否错误
@$file_error=$_FILES['file']['error'];echo $file_name."<hr>";
echo $file_type."<hr>";
echo $file_size."<hr>";
echo $file_tmpname."<hr>";
echo $file_error."<hr>";

运行查看效果,如果代码正确的话上传一个文件会打印这个被上传的文件的相关信息

我这里上传一张图片做为测试

点击提交上传之后会打印这种图片相关信息

保存用户上传的文件

现在我们实现当用户上传文件后,比如用户上传了自己的头像后我们的服务器要保存用户的数据。这里我们设置当用户上传文件后将文件保存在当前目录下的upload目录里

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Head</title><link rel="stylesheet" href="index.css">
</head>
<body>
<div class="header"><a href="index.html" class="logo"><h1>wushiyiwuzhong</h1></a><nav class="navbar"><ul><li><a href="file_index.php">文件功能导航</a></li><li><a href="file_upload.php">文件上传</a></li><li><a href="#">文件下载</a></li><li><a href="#">文件删除</a></li><li><a href="#">文件读取</a></li><li><a href="#">文件写入</a></li></ul></nav>
</div>
<div class="content">
<h1>文件上传 功能页面</h1>
<!--  编写form表单上传文件  --><form action="upload.php" method="post" enctype="multipart/form-data"><input type="file" name="file"><!-- name是什么,那么后端接受的参数就是什么--><input type="submit" name="submit" value="提交"></form>
</div>
</body>
</html><?php
// 检查是否有文件被上传
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file'])) {// 指定存放上传文件的目录$uploadDirectory = "upload/";// 获取文件相关信息$fileName = $_FILES['file']['name']; // 文件原名$fileTmpName = $_FILES['file']['tmp_name']; // 文件临时存放的位置$fileError = $_FILES['file']['error']; // 错误码$fileSize = $_FILES['file']['size']; // 文件大小// 检查目录是否存在if (!file_exists($uploadDirectory)) {// 如果不存在则创建目录mkdir($uploadDirectory, 0755, true);}// 检查文件上传过程中是否出错if ($fileError === 0) {// 检查文件是否已经存在if (!file_exists($uploadDirectory . $fileName)) {// 尝试移动文件到指定目录if (move_uploaded_file($fileTmpName, $uploadDirectory . $fileName)) {echo "文件上传成功!";} else {echo "文件上传失败,请检查目录权限。";}} else {echo "文件已存在于目标目录中。";}} else {// 错误处理echo "上传过程中出错,错误码:" . $fileError;}
} else {echo "请通过有效表单提交文件。";
}

代码运行效果如下:

上传文件进行测试,看是不是保存在upload目录下


打开文件夹,确认是不是真的成功了

到这里成功实现了文件上传功能

PS:此时我们就完成了简单的文件上传功能的实现,但是现在的代码是没有任何过滤的,攻击者可以通过上传木马、webshell等等恶意文件来控制我们的服务器。

情景假设:

我是一名黑客,我在目标网站找到了上传漏洞。我现在先上传一个php的webshell到网站上去


现在我们使用蚁剑去连,连接编码为base64,密码为123

PS:当时写代码的时候忘记写回显了。。。。。。不过实战中还是有很多方法可以知道上传路径的

通过第三方组件进行文件上传

在实际的开发中我们可能会节省重复造轮子的时间而去使用其他第三方开发的第三方组件来快速实现我们需要的功能。下面的就是一个第三方组件的例子
(演示使用的第三方组件下载地址)[https://github.com/fex-team/ueditor/releases/tag/v1.4.3.3]

下载后解压到对应的网站目录
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
然后在代码里引入该第三方组件,在html代码里直接加入

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>第三方组件的文件上传</title><link rel="stylesheet" href="index.css"><!-- 集成 UEditor 的 CSS 文件 --><link href="ueditor/themes/default/css/ueditor.min.css" type="text/css" rel="stylesheet"><!-- UEditor 配置文件 --><script type="text/javascript" charset="utf-8" src="ueditor/ueditor.config.js"></script><!-- UEditor 编辑器源码文件 --><script type="text/javascript" charset="utf-8" src="ueditor/ueditor.all.min.js"></script>
</head>
<body>
<a href="index.html" class="logo"><h1>wushiyiwuzhong</h1>
</a>
<nav class="navbar"><ul><li><a href="file_index.php">文件功能导航</a></li><li><a href="file_upload.php">文件上传</a></li><li><a href="#">文件下载</a></li><li><a href="#">文件删除</a></li><li><a href="#">文件读取</a></li><li><a href="#">文件写入</a></li></ul>
</nav>
</div>
<div class="content"><h1>文件上传 功能页面</h1><!-- 编写form表单上传文件 --><form action="upload.php" method="post" enctype="multipart/form-data"><!-- 初始化 UEditor 编辑器的容器 --><script id="editor" name="editor" type="text/plain" style="width:1024px;height:500px;"></script><input type="file" name="file"><!-- 文件上传的input --><input type="submit" name="submit" value="提交"></form>
</div>
<script type="text/javascript">// 实例化 UEditorvar ue = UE.getEditor('editor');
</script>
</body>
</html>

运行效果:

进行文件上传的测试


可以看到第三方组件过滤了简单的恶意文件

总结

到此文件上传漏洞的大致原理和简单利用就结束了,自己开发的代码漏洞出在自己开发的部分,而如果引用第三方组件,那么漏洞点在第三方组件。至于过滤、绕过这些都是后面的事情

相关文章:

网络安全基础之php开发文件上传的实现

前言 php是网络安全学习里必不可少的一环&#xff0c;简单理解php的开发环节能更好的帮助我们去学习php以及其他语言的web漏洞原理 正文 在正常的开发中&#xff0c;文件的功能是必不可少&#xff0c;比如我们在论坛的头像想更改时就涉及到文件的上传等等文件功能。但也会出…...

[文件读取]cuberite 文件读取 (CVE-2019-15516)

1.1漏洞描述 漏洞编号CVE-2019-15516漏洞类型文件上传漏洞等级⭐⭐⭐漏洞环境VULFOCUS攻击方式 描述: Cuberite是一款使用C语言编写的、轻量级、可扩展的多人游戏服务器。 Cuberite 2019-06-11之前版本中存在路径遍历漏洞。该漏洞源于网络系统或产品未能正确地过滤资源或文件路…...

SpringBoot 自定义参数校验(5)

文章目录 前言方式一 @Pattern方式二 自定义参数校验Controller层请求示例前言 本文基于SpringBoot 3.1.2,使用自定义参数规则来处理参数校验。 方式一 @Pattern 使用@Pattern,自定义正则表达式,以下是一个校验IP地址的示例: import jakarta.validation.constraints.Not…...

Win Docker Desktop + WSL2 部署PyTorch-CUDA服务至k8s算力集群

Win Docker Desktop WSL2 部署PyTorch-CUDA服务至k8s算力集群 Win Docker Desktop WSL2 安装安装WSL-Ubuntu拉取镜像并测试挂载数据并开放端口导出镜像或导入镜像在k8s集群部署 Win Docker Desktop WSL2 安装 首先根据你的操作系统版本 安装WSL &#xff0c;记得切换WSL2&a…...

JLMR Micro Super Resolution Algorithm国产微超分算法DEMO

一、简介 目前&#xff0c;做超分算法基本还是以AI训练为主&#xff0c;但是AI基本上都是基于既定场景的训练。而传统的算法基本上都是利用上下文的纹理预测、插值等方案&#xff0c;在图像放大过程中会出现模糊&#xff0c;或马赛克等现象。 我们基于加权概率模型&#xff0c…...

Docker的安装配置与使用

1、docker安装与启动 首先你要保证虚拟机所在的盘要有至少20G的空间&#xff0c;因为docker开容器很吃空间的&#xff0c;其次是已经安装了yum依赖 yum install -y epel-release yum install docker-io # 安装docker配置文件 /etc/sysconfig/docker chkconfig docker on # 加…...

macOS文本编辑器 BBEdit 最新 for mac

BBEdit是一款功能强大的文本编辑器&#xff0c;适用于Mac操作系统。它由Bare Bones Software开发&#xff0c;旨在为开发者和写作人员提供专业级的文本编辑工具。 以下是BBEdit的一些主要特点和功能&#xff1a; 多语言支持&#xff1a;BBEdit支持多种编程语言和标记语言&…...

Android Audio实战——音量设置Hal(二十)

本来上一篇分析音量设置中对于 setCurrentGainIndex 方法我们分析到了 native 层就没有往下分析,但这这里还有准备再看看下面的流程。 一、源码分析 1、android_media_AudioSystem.cpp 源码位置:frameworks/base/core/jni/android_media_AudioSystem.cpp static jint and…...

jetson配置笔记

typora-root-url: /home/msj/ubuntu笔记本台式机环境配置说明/images Ubuntu18.04 配置 说明&#xff1a;我们所有文档配置都是按照ubuntu18.04&#xff0c;保证x86架构(笔记本台式机)和 ARM架构(jetson Nano只能安装18.04)的一致性 1. 更换各类源 我们所有源都更换清华源&a…...

使用select实现定时任务

selectOutOfTime.c里边的代码如下&#xff1a; #include<stdio.h> #include<sys/time.h> #include<sys/types.h> #include<unistd.h> #include <string.h>#define BUF_SIZE 100int main(void){fd_set reads;struct timeval tv;int errorNum;cha…...

uniapp的实战总结大全

&#x1f642;博主&#xff1a;冰海恋雨 &#x1f642;文章核心&#xff1a;uniapp部分总结 目录 ​编辑 目录 前言&#xff1a; 解决方案 1. 跨平台开发 2. Vue.js生态 3. 组件库 4. 自定义组件 5. Native能力 6. 插件生态 7. 性能优化 写法 1. 模板&#xf…...

No205.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…...

保序回归:拯救你的校准曲线(APP)

保序回归&#xff1a;拯救你的校准曲线&#xff08;APP&#xff09; 校准曲线之所以是评价模型效能的重要指标是因为&#xff0c;校准曲线衡量模型预测概率与实际发生概率之间的一致性&#xff0c;它可以帮助我们了解模型的预测结果是否可信。一个理想的模型应该能够准确地预测…...

清华镜像源地址,适用于pip下载速度过慢从而导致下载失败的问题

清华地址 https://pypi.tuna.tsinghua.edu.cn/simple下载各种各样的包的指令模板 pip install XXX -i https://pypi.tuna.tsinghua.edu.cn/simple这样就行了&#xff0c;XXX代表的是你将要下载的包名称。 比如&#xff1a; pip install opencv-python -i https://pypi.tuna.…...

arcgis--NoData数据处理

方法一&#xff1a;利用【栅格计算器】可以对NoData的值进行修改。【Spatial Analyst工具】-【地图代数】-【栅格计算器】&#xff0c;将NoData修改为某一个值。 方法二&#xff1a;先对原始数据进行重分类&#xff0c;分成1类&#xff0c;将NoData赋值为2,。然后&#xff0c;将…...

基于单片机教室人数实时检测系统仿真及源程序

一、系统方案 1、本设计采用51单片机作为主控器。 2、红外传感器检测进出人数&#xff0c;液晶1602显示。 3、按键最多容纳人数&#xff0c;烟雾报警。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 void lcd_init() { lcd_write_com(0x38…...

【Linux笔记】Linux环境变量与地址空间

【Linux笔记】Linux环境变量与地址空间 一、命令行参数1.1、main函数的参数1.2、main函数的第三个参数 二、环境变量的概念与内容2.1、环境变量的概念2.2、环境变量的分类2.3、环境变量的组织形式2.4、常见的环境变量 三、设置环境变量3.1、通过命令获取或设置环境变量3.2、通过…...

【springboot】@restcontroller和@controller的区别

返回值不同&#xff1a;RestController注解的类中的所有方法都会返回JSON或XML等数据格式&#xff0c;而Controller注解的类中的方法可以返回JSP或HTML等视图页面。 默认注解不同&#xff1a;RestController注解中包含了ResponseBody注解&#xff0c;表示返回的数据会直接作为…...

oracle 不支持的字符集 orai18n.jar ZHS16GBK 异常问题解决

项目场景&#xff1a; 项目中有使用到oracle数据库来存在数据。 问题描述 在使用查询语句是&#xff0c;oracle会报错。 java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK 原因分析&#xff1a; 经排查发现缺少oracle字符集的依赖包导致的。…...

设计模式-04-原型模式

经典的设计模式有23种&#xff0c;但是常用的设计模式一般情况下不会到一半&#xff0c;我们就针对一些常用的设计模式进行一些详细的讲解和分析&#xff0c;方便大家更加容易理解和使用设计模式。 1-什么是原型模式 如果对象的创建成本比较大&#xff0c;而同一个类的不同对象…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...