文件上传基础

一、文件上传

1. 什么是文件上传?

文件上传就是:

用户把自己电脑上的文件发送给服务器,服务器接收这个文件。

例如网站有:选择文件 → 上传

整个过程:本地文件 →浏览器 →HTTP请求 →服务器 →PHP处理 →保存文件


2. PHP 如何接收上传文件?

PHP 使用预定义变量:$_FILES

例如前端:

复制代码
<input type="file" name="file">

PHP:

复制代码
$_FILES['file']

3. $_FILES 中有什么?

例如:$_FILES'file'里面常见的数据:

复制代码
$_FILES['file']['name']
$_FILES['file']['type']
$_FILES['file']['tmp_name']
$_FILES['file']['error']
$_FILES['file']['size']

分别表示:

name:用户上传时的文件名

type:文件的MIME类型信息

tmp_name:PHP暂时保存上传文件的位置

error:上传过程中产生的错误代码

size:文件大小

其中最重要的是:$_FILES'file''tmp_name'。它表示:服务器暂时保存这个上传文件的位置。


二、文件上传是怎么保存的?

PHP 常使用:move_uploaded_file()函数将上传的临时文件移动到指定的目录中,从而将上传的文件保存下来。

例如:

复制代码
move_uploaded_file(
    $_FILES['file']['tmp_name'],
    'uploads/test.jpg'
);

这个函数有两个参数:

第一个参数:上传文件当前的临时位置

第二个参数:文件最终保存的位置

执行过程:

复制代码
用户上传 test.jpg
       ↓
PHP接收
       ↓
临时保存
       ↓
$_FILES['file']['tmp_name']
       ↓
move_uploaded_file()
       ↓
uploads/test.jpg

三、什么是文件上传漏洞?

正常的网站不会什么文件都接受。

例如只允许:.jpg .png .gif

并且还应该检查:文件大小,文件类型、文件内容、文件扩展名、保存位置、文件名

如果程序对这些检查存在问题,就可能产生文件上传漏洞。

所以文件上传漏洞的核心不是:网站有上传功能。

而是:用户能够上传服务器本来不应该接受或处理的文件。

也就是说:如果服务器端代码未对客户端上传的文件进行严格的验证和过滤,就容易造成可以上传任意文件的情况,包括上传脚本 文件

产生的危害

恶意用户可以利用上传的恶意脚本文件控制整个文件,甚至控制整服务器,这个恶意脚本文件又被称为webshell

可将webshell称为一直网页的后门 ,webshell脚本具有非常强大的功能,如查看服务器中的目录,文件,执行系统命令等。

JavaScript检测绕过

常用于用户选择文件上传的场景,如果上传的文件的后缀不被允许,则会弹窗告知。此时上传文件的数据包并没有发送到服务器端,只是在客户端浏览器中使用JavaScript对数据包进行检测。

上传了非jpg的格式

绕过客户端JavaScript检测的方式:

1)使用浏览器插件,删除检测文件后缀的JavaScript代码,然后上传文件即可绕过。

2)先把需要上传的文件的后缀改成允许上传的格式,即可绕过JavaScript的检测,然后抓包,再把后缀名改成可执行文件的后缀即刻上传成功。

客户端上传文件的HTML部分代码:函数作用:先将文件名转换为小写,再通过substr函数获取文件名的最后一个点号后面的后缀。如果不是.jpg则弹框提示。

服务端处理上传文件的代码:

如果上传文件没错,在通过file_exists函数判断在upload目录下文件是否存在,不存在就通过move_uploaded_file函数将文件保存到upload。此代码并没有对文件后缀做任何判断,所以只需绕过前端JavaScript的校验就可以上传webshell。

文件后缀/黑名单绕过

原理:虽然服务器代码中限制了某些后缀的文件上传,但是有些版本的apache允许解析其他文件的后缀。

例如:在httpd.conf中,如果配置了 Addtype application/x-httpd-php .php .phtml,则能解析php和.phtml文件。

网站管理员可以在配置文件中添加任意扩展名,从而让网站去解析,配置这些扩展名是因为,这些扩展名曾经使用过,在某些情况下需要对这些文件进行解析,因此可以这样绕过。

通常有phtml、phps、php3、php5、pht等

apache是从右向左解析文件后缀的,如果最右侧的扩展 名不可识别,就继续往左解析,直到遇到可以接卸的文件后缀为止。因此,如果上传的文件名类似1.php.xxxxx,由于xxxxx后缀不能被解析,所以继续向左解析,从而触发后门。

第五行:定义一个数组,数组中的元素就是被列入黑名单的扩展名

第八行:截取扩展名

第13行:检测后缀名是否在黑名单中。

在这里上传文件后,对文件重命名了

文件Content-Type绕过

如果服务器端的代码时通过Content-Type的值来判断文件的类型,就存在被绕过的可能,因为Content-Type的值时通过客户端传递的,可以修改,当上传一个php文件时,在Burp中将Content-Type修改为image/jpeg,就可以绕过。

竞争条件攻击

由于网站上传文件的逻辑是先允许上传任意文件,然后检查上传文件中是否包含webshell脚本,如果包含则删除该文件。但是,文件上传成功和删除文件这两个操作之间会存在一个时间差。攻击者可以利用这个时间差来完成竞争条件的上传漏洞攻击。

思路:先上传一个webshell脚本,这个脚本的内容是生成一个新的webshell脚本。然后客户端立即访问上传的脚本,就会在服务端自动生成webshell。

复制代码
<?php
fputs(fopen('../shell.php','w'),'<?php @eval($_POST[a]) ?>');
?>
  • fopen('../shell.php','w'):打开(创建)上层目录下shell.php,w代表写入模式;如果文件不存在就新建,存在就覆盖。
  • fputs(文件句柄,内容):把一句话木马代码写入shell.php文件。
  • 写入的木马:<?php @eval($_POST[a]) ?>

eval()执行 POST 参数a传过来的 PHP 代码;@用来屏蔽报错。

攻击者使用蚁剑 / 菜刀连接shell.php,参数密码为a,获取网站权限。

黑名单绕过

文件上传漏洞修复建议

通过白名单的方式判断文件后缀名是否合法

对上传的文件进行重命名。

相关推荐
恋猫de小郭33 分钟前
Kotlin 2.5 的 Companion 改造,对 KMP 的重要升级
android·前端·flutter
Kapaseker2 小时前
写了这么久 Kotlin,你真的理解 in、out 和 * 吗?
android·kotlin
小七在进步2 小时前
C++内存管理:new/delete vs malloc/free深度解析
android·java·c++
geovindu15 小时前
sql:Search-Optimized SQL Queries using mysql 9.0
android·数据库·sql·mysql·数据库开发·数据库架构
知之则吱吱17 小时前
Android 开发者验证机制迎来新变化:核心要求、实施时间与开发者应对指南
android·google
墨天梦18 小时前
D09_Retrofit接口与数据转换
android·kotlin·retrofit
电商API_1800790524719 小时前
闲鱼商品列表API接口商品详情API接口请求示例(含一份真实响应数据示例)
android·数据挖掘·网络爬虫·跨境电商·反向海淘
我命由我1234519 小时前
Android 广播 - 组件通信
android·java·开发语言·android studio·android jetpack·android-studio·android runtime
阿俊-全栈开发19 小时前
LikeShop 单商户标准版商品管理二开:分类、SKU 规格与库存联动实现
android·likeshop·likeshop开源商城