前言

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']; //上传文件出现的错误号,为一个整数
\)_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">
// 实例化 UEditor
var ue = UE.getEditor('editor');
</script>
</body>
</html>

运行效果:



进行文件上传的测试





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

总结

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

php开发之文件上传的实现的更多相关文章

  1. Java开发系列-文件上传

    概述 Java开发中文件上传的方式有很多,常见的有servlet3.0.common-fileUpload.框架.不管哪种方式,对于文件上传的本质是不变的. 文件上传的准备 文件上传需要客户端跟服务都 ...

  2. 04springMVC结构,mvc模式,spring-mvc流程,spring-mvc的第一个例子,三种handlerMapping,几种控制器,springmvc基于注解的开发,文件上传,拦截器,s

     1. Spring-mvc介绍 1.1市面上流行的框架 Struts2(比较多) Springmvc(比较多而且属于上升的趋势) Struts1(即将被淘汰) 其他 1.2  spring-mv ...

  3. SpringBoot | 第十七章:web应用开发之文件上传

    前言 上一章节,我们讲解了利用模版引擎实现前端页面渲染,从而实现动态网页的功能,同时也提出了兼容jsp项目的解决方案.既然开始讲解web开发了,我们就接着继续往web这个方向继续吧.通常,我们在做we ...

  4. SpringBoot --web 应用开发之文件上传

    原文出处: oKong 前言 上一章节,我们讲解了利用模版引擎实现前端页面渲染,从而实现动态网页的功能,同时也提出了兼容jsp项目的解决方案.既然开始讲解web开发了,我们就接着继续往web这个方向继 ...

  5. Java开发之文件上传

    文件上传有SmartUpload.Apache的Commons fileupload.我们今天介绍Commons fileupload的用法. 1.commons-fileupload-1.3.1.j ...

  6. Web 开发中 文件上传 是出现的:java.io.FileNotFoundException: (文件名、目录名或卷标语法不正确。)

    <span style="font-family: Arial, Helvetica, sans-serif; "> </span> <span st ...

  7. iOS开发系列-文件上传

    概述 Http协议对文件上传协议要求的 1. 必须设置请求头Content-Type为multipart/form-data.在iOS中后面需要跟上分隔符比如:boundary=----WebKitF ...

  8. Baidu WebFE(FEX)团队开发 的 文件上传插件 WebUploader

    1.webUploader官网下载地址:http://fex.baidu.com/webuploader/ 直接下载代码,运行examples目录文件即可 2.webUploader上传demo:ht ...

  9. 互联网开发-web文件上传性能问题

    1. 问题描述 文件大小 部署环境 平均上传速度 5M 外网 28s-36s 5M 公司局域内网 秒传,很快 2. 问题分析 在网上搜索“测速网”测试了一下公司外网的带宽情况: 上传带宽 = 1.04 ...

  10. 6.MVC框架开发(文件上传)

    1.需要设置表单的enctype="multipart/form-data"属性 2.在控制器中获取表单文件中数据 [HttpPost] public ActionResult A ...

随机推荐

  1. Mybatis(配置解析解读(核心))

    核心配置文件 mybaits-confing.xml *properties(属性) *settring(设置) *typeAliases(类型别名) *typeHandlers(类型处理器) *ob ...

  2. wireshark 怎么过滤字符串 和 复制data中的可读文本

    设置 首先点击,[捕获]下面的小放大镜 选择 分组字节流 - 窄(UTF-8/ASCII)- 字符串 (注意,要向选择字符串) 效果 复制报文中的可读数据 右键报文,复制,...as Printabl ...

  3. 2021-11-17 WPF初识

    StackPanel容器:默认竖直排列,Orientation="Horizontal"横向排列,超过就不会显示 wrapPanel:超过会自动换行 设置样式: <Windo ...

  4. 「Python实用秘技16」快速提取字体子集

    本文完整示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/PythonPracticalSkills 这是我的系列文章「Python实用秘技」的第16 ...

  5. nuitka 将程序编译为单个exe

    原文链接:https://github.com/Nuitka/Nuitka 在Windows上,有两种模式,一种是将其复制到您公司指定的AppData,也将其用作缓存,另一种是在临时目录中进行.您需要 ...

  6. python教程 入门学习笔记 第1天 初识python python语言环境安装 python编写器

    初识python 一.python语言简介: 1.起源:1989年由荷兰的前谷歌程序员吉多.范罗苏姆(龟叔)创造,python的命名来源于英国电视喜剧Monty Python's Flying Cir ...

  7. 何时使用Elasticsearch而不是MySql

    MySQL 和 Elasticsearch 是两种不同的数据管理系统,它们各有优劣,适用于不同的场景.本文将从以下几个方面对它们进行比较和分析: 数据模型 查询语言 索引和搜索 分布式和高可用 性能和 ...

  8. Linux第四章(80X86保护模式及其编程)

    80X86保护模式及其编程 80X86基础知识 保护模式内存管理 各种保护措施 中断和异常处理 任务管理 保护模式编程的初始化 一个简单的多任务内核 4.1 80X86系统寄存器和系统指令 为了协助处 ...

  9. 《SQL与数据库基础》19. 日志

    目录 日志 错误日志 二进制日志 日志格式 日志查看 日志删除 查询日志 慢查询日志 本文以 MySQL 为例 日志 错误日志 错误日志是 MySQL 中最重要的日志之一,它记录了当 mysql 启动 ...

  10. [译]这几个CSS小技巧,你知道吗?

    前言 在网页设计和前端开发中,CSS属性是非常重要的一部分.掌握常用的CSS属性不仅可以使你的网页看起来更美观,还能提升用户体验,今天小编为大家介绍8个常见的CSS小技巧: 1.修改滚动条样式 下图是 ...