文件上传漏洞-upload靶场1-2关 通过笔记(如何区分前段验证和后端验证)

文件上传漏洞-upload靶场1-2关 通过笔记(区分前段验证和后端验证)

前言

upload是一个文件上传的专用靶场,搭设也非常简单,只需要把相关源码文件放到apache的网站目录下即可使用,或者去github下载一键绿化包进行安装链接如下:

[Releases · c0ny1/upload-labs (github.com)]

image-20230822214734727

下载后按照使用说明安装即可,在安装该靶场时最好安装在虚拟机中,在此也不做过多的解析了,如有不明白可以私聊我。

image-20230822214826621

upload靶场能帮助我们,实践复现文件上传漏洞,帮助我们更好的学习该漏洞形成的原因,该工具一共20关,除了第一关是前段验证,其他19关都是关于后端验证。

image-20230823002849979

upload的难度也是逐步上升,第十关是一个分水岭,后面的内容也是非常硬核

在开始挑战关卡前,我们先了解下什么才是一次成功的攻击:

  1. webshell要成功的上传到服务器中
  2. 要知道webshell在服务器中的路径
  3. 上传的webshell能被正常解析

只有满足这三条条件,才能算一次成功的攻击。

upload第一关(JS验证)

image-20230822222434463

javascript是一个前端常用的语言,用它写的代码在一般情况都是属于前端,不过当你使用node.js为服务器环境时候,javascript也可以作为后端语言来使用。

判断思路

在上传webshell时,我们并不知道该网站使用了那些方法来验证上传的文件,所以我们要从分析源码、抓取流量、随意上传一个文件等方法去分析它的验证方式,以便找到适合的方法去进行攻击。

第一种方法:分析源码
            <h3>任务</h3>
            <p>上传一个<code>webshell</code>到服务器。</p>
        </li>
        <li>
            <h3>上传区</h3>
            <form enctype="multipart/form-data" method="post" onsubmit="return checkFile()">
                <p>请选择要上传的图片:<p>
                <input class="input_file" type="file" name="upload_file"/>
                <input class="button" type="submit" name="submit" value="上传"/>
            </form>


<script type="text/javascript">
    function checkFile() {
        var file = document.getElementsByName('upload_file')[0].value;
        if (file == null || file == "") {
            alert("请选择要上传的文件!");
            return false;
        }
        //定义允许上传的文件类型
        var allow_ext = ".jpg|.png|.gif";
        //提取上传文件的类型
        var ext_name = file.substring(file.lastIndexOf("."));
        //判断上传文件类型是否允许上传
        if (allow_ext.indexOf(ext_name) == -1) {
            var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
            alert(errMsg);
            return false;
        }
    }
</script>

以上源码是从该网站中找到的,其中有一个form表单和一个js脚本较为关键,在form表单中又有两个input标签

form表单有三个属性分别是:

  • enctype属性:表单中用于指定在提交表单数据时使用的编码类型
    • 它的值为multipart/form-data:
      • 表单数据会被分割为多个部分(multipart),每个部分都包含一个表单字段的数据。这种编码类型可以同时传输文本数据和二进制数据,比如上传的文件
  • mothod属性:表示这个表单接收数据的方法
    • 它的值为post:
      • 使用post方法来接收数据
  • onsubmit属性:用于指定在提交表单时执行的 JavaScript 代码
    • 它的值为return checkFile():
      • 用来指定在表单提交之前执行的 JavaScript 函数 checkFile()

input标签解析:

  • - 该代码可以用于创建一个文件上传的输入字段,允许用户选择本地计算机上的文件并上传到服务器。它的表示name值为upload_file
  • - 创建一个提交按钮,并在用户界面中显示 "上传" 文本。当用户点击此按钮时,表单的提交动作将被触发,将表单数据发送到服务器。

从下面的js代码中我们发现了 checkFile()的函数,它的第一句,就是使用 document.getElementsByName() 方法来获取带有 name="upload_file" 属性的元素,并通过索引 [0] 来获取第一个匹配的元素,然后使用 .value 属性获取其值,如果没有上传文件,或上传空文件则提示请选择要上传的文件。

在下半段js代码中,首先限定了上传文件后缀,只能上传这三种后缀的文件,又通过调用 file.lastIndexOf(".") 方法,可以获取文件名中最后一个点(.)的索引。然后,通过调用 file.substring() 方法,可以从该索引位置开始截取字符串,得到文件名中的扩展名进行判断,如果上传的文件不符合要求,则提示用户上传正确的格式的文件

通过这一段代码的分析,我们就可以判断它是一个前端验证的文件上传,确定了是前段验证,那么问题就简单了,所谓前端验证都是纸老虎可不是开玩笑的哈哈。

js代码函数分析

document.getElementsByName()

  • 它是JavaScript 中的一个 DOM 方法,用于根据元素的 name 属性获取文档中所有匹配的元素集合。

  • 该方法接收一个字符串参数,表示要获取的元素的 name 属性的值,返回一个类数组对象,包含所有与指定 name 属性匹配的元素。

对象.lastIndexOf()

  • 它是 JavaScript 字符串的方法,用于获取字符串中最后一个出现的指定字符或子字符串的索引位置。

对象.substring()

  • 它是 JavaScript 字符串的方法,用于获取字符串中指定索引位置之间的子字符串。
第二种方法抓包

首先我们打开Burp抓取一个upload上传的包

image-20230822233118103

把这个包放到repeater(重放器)中进行分析

image-20230822233247084

在此处我们发现,我们上传了一个名为123.jpg的文件,

Content-Type: image/jpeg 表示我们发送的是一个图片文件

在此我们对我们上传的文件后缀名进行更改

  • 如果是前端验证,更改文件后缀名后依旧能正常发送,因为它已经经过了验证。

image-20230822234556009

在修改文件后缀为asp后,也是成功发送给后端服务器,这也能证明它只使用前端验证

第三种方法:随意上传文件分析

这种方法是最为快捷的,但是判断是否是前段验证或后端验证,这种方法就非常考验我们的经验。

如果是前端验证,它的报错响应速度会非常快,因为它一直在你本地的前端,如果是后端服务器验证,相反它的响应速度就会有一定的延迟,具体还得看网络情况,为什么会有延迟呢,我统计了一下情况供大家参考:

  1. 网络延迟:前端验证是在客户端执行的,而后端验证涉及将数据发送到服务器并等待服务器响应。这意味着在进行后端验证时,会出现网络延迟的情况,这可能会导致更长的验证时间。

  2. 请求处理时间:后端验证涉及将数据发送到服务器上的处理程序,然后由服务器上的应用程序进行验证并返回响应。与前端验证相比,服务器的请求处理时间会更长,因为服务器可能涉及其他任务、处理其他请求或执行其他复杂的验证逻辑。

  3. 数据传输量:后端验证涉及将数据上传到服务器进行处理,这需要将数据通过网络传输到服务器,这可能会涉及较大的数据量,因此相对于前端验证来说可能更慢。

攻击思路

前端验证最大的缺点,就是它可以被客户端篡改,这文件就在我本地计算机中,我想咋改就咋改,而后端服务器就比较麻烦了,在后面也会详细的去介绍如何成功上传。

前段验证的攻击方法:

1、直接修改源码:

image-20230822235836598

使用浏览器自带的检查工具,找到前端验证的代码,直接删除。

2、使用bp抓包工具:

image-20230823000308923

直接在抓包工具中修改文件后缀名,因为它已经通过了前段的验证,这时候修改对上传的文件毫无影响。

3、使用br禁用网页的js功能

image-20230823000846522

image-20230823001103937

4、使用浏览器自带的禁用js功能(火狐浏览器)

1.在火狐浏览器的url界面中输入 about:config 进入高级设置界面

image-20230823001327765

找到javascript.enabled

image-20230823001430901

将javascript.enabled的true改为false

image-20230823001503534

同样也能达到br抓包禁用的效果,不过在这里不建议使用浏览器的禁用方法,它会把所有的js全部都禁用掉,一些正常的js也会变层无法使用。

最后上传一个简单的webshell脚本,来测试是否成功。

image-20230823001929745

已经成功获取的网站权限!


upload第二关(MIME验证)

什么是MIME?

MIME(Multipurpose Internet Mail Extensions)是一种用于标识文件类型的标准。它是在互联网上发送邮件和其他数据的一种常用方式。

MIME 类型由两部分组成:主类型和子类型,之间用斜杠(/)分隔。主类型表示文件的大类别,而子类型表示具体的文件类型。例子如下:

  • 文本文件:text/plain
  • HTML 文件:text/html
  • JPEG 图像文件:image/jpeg
  • PNG 图像文件:image/png
  • JSON 数据文件:application/json
  • PDF 文档:application/pdf

MIME 类型主要用于在 HTTP 协议中指定传输的数据类型,并且还在其他应用程序中进行使用,例如电子邮件、文件上传等。通过使用正确的 MIME 类型,服务器和客户端能够理解传输的数据类型,并进行相应的解析和处理。

MIME 类型还可用于指定数据的字符编码、语言和其他相关信息,这些信息用于确保数据的正确显示和处理。

在 HTTP 协议中,MIME 类型常用于请求报文和响应报文的 Content-Type 头字段中,用于指定将要发送或接收的数据的类型。

判断思路

首先还是随意上传一个文件,来判断一下它究竟是前段验证,还是后端服务器验证。

image-20230823234326872

查看源码发现,from表单也有一个onsubmit属性和第一关的一模一样,难道它也是前段验证?抱着怀疑的我们按第一关的操作,把这个属性删除在尝试上传,看看是否能成功。

image-20230823235053202

删除该属性后,尝试上传文件,任然提示文件类型不正确,此时我们就拿出最终绝招,用bp抓个数据包,也按照第一关的方法,去尝试是否能成功上传。

image-20230823235639207

我们上传一个jpeg的图片文件,经过bp后把后缀名改为php,然后放行,看看是否能够成功上传。

image-20230823235952163

居然成功上传了,难道它也是前段验证?那为什么我们删除验证的js脚本函数后,又不能成功上传呢?带着这些疑问,我又开始抓包研究。

image-20230824001327255

在此我有了发现,在第一关我开启Bp抓包的时候,上传一个任意文件,如果上传的文件类型错误,bp就抓不到数据包,而是在网页中直接弹出一个警告框

image-20230824001522759

而到了第二关,我上传一个随意文件时,Bp能抓到一个请求包,并在Content-Type中显示了当前上传文件的类型,text/plain,在此我就可以判断第二关的验证是后端服务器,下面是我画的一张前端验证、后端验证的流程图。

image-20230824004345678

总结一下思路,

  • 如果是前段验证,当bp开启抓包的时候,文件类型错误,将抓不到任何请求包。
  • 如果是服务器后端验证,无论是否成功,Bp都能抓到对应的响应包。
  • 这也就是前段验证和后端验证的最大区别。

攻击思路:

当我们分清楚前端验证和后端验证的区别后,就可以开始分析如何在后端验证的情况,上传一个webshell。

在判断思路中,我们使用第一关的攻击思路,上传一个图片格式的文件,用bp抓包并修改文件后缀,能够成功将webshell上传到站点,但是使用其他格式缺总是失败,而且我们还发现上传不同类型的文件,content-Type的值也是不一样的,这一点证明的后端服务器,可能是开启了一个白名单模式,只有指定的文件类型才能成功上传,那么我们是否可以用bp抓包,对content_type的值进行篡改,来实现攻破后端服务器验证的关卡呢?心动不如行动,我们一起来实践一下。

image-20230824005546942

首先我们先上传一个webshell,后缀为php,在用bp抓住这个包,使用repeter进行验证我们的想法。

image-20230824005726006

我们只修改Content-type的值尝试,能不能正常上传。

image-20230824005801650

果然和我想的一样,只要我们修改了Content-type的值为图片类型,我们就可以上传任意文件,包括webshell。再来尝试上传的webshell是否能正常解析。

image-20230824010024661

使用post方法进行传参,能够成功执行phpinfo();函数,这叫代表我们已经成功闯过了第二关,也就初步了掌握了文件上传的基础技巧,后面还有18个关卡,我们还要继续努力。

后端源码分析
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}


在解析源码前,我们先看看这串源码中,使用了哪些函数
  1. isset():用于检查变量或表单字段是否已设置和存在。
  2. file_exists():用于检查指定文件或目录是否存在。
  3. $_POST:是一个包含通过 POST 方法提交的表单字段和值的关联数组。在这里,$_POST['submit'] 用于检查表单是否通过提交按钮进行了提交。
  4. $_FILES:是一个包含通过文件上传的文件信息的关联数组。在这里,$_FILES['upload_file'] 包含了关于上传文件的信息,如文件名、临时路径、文件大小、文件类型等。
  5. move_uploaded_file():用于将上传的文件移动到目标位置。

以下是对代码的解释和说明:

在这段代码中,首先定义了一个布尔变量 $is_upload 并初始化为 false,用于表示文件是否成功上传。还定义了一个变量 $msg ,用于存储上传过程中的提示信息。

通过使用 isset($_POST['submit']) 检查表单是否通过提交按钮进行了提交。

使用 file_exists(UPLOAD_PATH) 来检查指定的上传目录是否存在。UPLOAD_PATH 是一个用于存储上传文件的目录路径。

使用 $_FILES['upload_file']['type'] 来获取上传文件的 MIME 类型(例如:image/jpegimage/pngimage/gif)。

通过使用 $_FILES['upload_file']['tmp_name'] 获取上传文件的临时路径。

通过使用 $_FILES['upload_file']['name']UPLOAD_PATH 来创建存储上传文件的目标路径。

使用 move_uploaded_file($temp_file, $img_path) 将上传的临时文件移动到目标路径。

当移动文件成功时,将 $is_upload 设置为 true,如果移动文件失败,则将 $msg 设置为 ‘上传出错!’。

如果上传文件的类型不是 ‘image/jpeg’、‘image/png’ 或 ‘image/gif’,将 $msg 设置为 ‘文件类型不正确,请重新上传!’。

如果上传目录不存在,将 $msg 设置为 UPLOAD_PATH 所指定的目录路径后面跟上 ‘文件夹不存在,请手工创建!’。

这个代码片段主要用于处理文件上传过程,并设置content-type的值为image/jpeg、png、gif,也就是说只要请求头中的content-type字段的值是上诉的文件类型,都可以成功上传。
文件移动到目标路径。

当移动文件成功时,将 $is_upload 设置为 true,如果移动文件失败,则将 $msg 设置为 ‘上传出错!’。

如果上传文件的类型不是 ‘image/jpeg’、‘image/png’ 或 ‘image/gif’,将 $msg 设置为 ‘文件类型不正确,请重新上传!’。

如果上传目录不存在,将 $msg 设置为 UPLOAD_PATH 所指定的目录路径后面跟上 ‘文件夹不存在,请手工创建!’。

这个代码片段主要用于处理文件上传过程,并设置content-type的值为image/jpeg、png、gif,也就是说只要请求头中的content-type字段的值是上诉的文件类型,都可以成功上传。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

路由转发(详细理解+实例精讲)

系列文章目录 华为数通学习&#xff08;5&#xff09; 目录 华为数通学习&#xff08;5&#xff09; 前言 一&#xff0c;最长匹配原则 实例1&#xff1a; 实例2&#xff1a; 二&#xff0c;路由转发流程&#xff1a; 三&#xff0c;IP路由表小结&#xff1a; 总结 前…

【同步异步可并发日志系统】设计及实现

1. 项⽬介绍2. 开发环境3. 项目核⼼技术4. 环境搭建5. ⽇志系统介绍5.1 为什么需要⽇志系统5.2⽇志系统技术实现5.2.1 同步写⽇志5.2.2 异步写⽇志 6. ⽇志系统框架设计6.1 各模块测试代码 7. 代码设计7.1 实⽤类设计7.2 ⽇志等级类设计7.3 ⽇志消息类设计7.4 ⽇志格式化输出设…

Easy Rules规则引擎(2-细节篇)

目录 一、序言二、规则引擎参数配置实例1、skipOnFirstAppliedRules示例(1) FizzRule(2) BuzzRule(3) FizzBuzzRule(4) NonFizzBuzzRule(5) FizzBuzzRulesLauncher 2、skipOnFirstNonTriggeredRule示例3、skipOnFirstFailedRule示例 三、组合规则1、UnitRuleGroup组合规则2、Ac…

java八股文面试[多线程]——synchronized 和lock的区别

其他差别&#xff1a; synchronized是隐式的加锁,lock是显式的加锁; synchronized底层采用的是objectMonitor,lock采用的AQS; synchronized在进行加锁解锁时,只有一个同步队列和一个等待队列, lock有一个同步队列,可以有多个等待队列; synchronized使用了object类的wait和noti…

经典问题解析四

关于动态内存分配 new 和 malloc 的区别是什么&#xff1f; delete 和 free 的区别是什么&#xff1f; new 关键字与 malloc 函数的区别 new 关键字是 C 的一部分 malloc 是由 C 库函数提供的函数 new 是以具体类型为单位进行内存分配 malloc 以字节为单位进行内存分配 …

利用R作圆环条形图

从理念上看&#xff0c;本质就是增加了圆环弧度的条形图。如上图2。 需要以下步骤&#xff1a; 数据处理&#xff0c;将EXCEL中的数据做成3*N的表格导入系统&#xff0c;代码如下&#xff1a;library(tidyverse) library(stringr)library(ggplot2)library(viridis) stuper &…

【前车之鉴】: 2023最新教程-将java程序打包到maven私服的正确打开方式,详细流程介绍不怕你掌握不了

文章目录 为什么看这篇整体流程1. 注册账号【首次需要】2. 工单申请【新项目必须】3. 项目配置【新项目必须】4. 授权认证【新项目必须】5. 一键发布 最后也很重要 为什么看这篇 一是当前网络上一些博客有遗漏部分&#xff0c;这里做补充&#xff0c;二是网上思路没错&#xff…

DC/DC开关电源学习笔记(一)开关电源技术概述

&#xff08;一&#xff09;开关电源技术概述 1.什么是开关电源&#xff1f;2.开关电源技术概述2.1 小型化、薄型化、轻量化、高频化2.2 高可靠性2.3 低噪声2.4 采用计算机辅助设计和控制 1.什么是开关电源&#xff1f; 开关模式电源&#xff08;Switch Mode Power Supply&…

JVM解密: 解构类加载与GC垃圾回收机制

文章目录 一. JVM内存划分二. 类加载机制1. 类加载过程2. 双亲委派模型 三. GC垃圾回收机制1. 找到需要回收的内存1.1 哪些内存需要回收&#xff1f;1.2 基于引用计数找垃圾(Java不采取该方案)1.3 基于可达性分析找垃圾(Java采取方案) 2. 垃圾回收算法2.1 标记-清除算法2.2 标记…

【QT】信号和槽(15)

前面的内容说了很多不同的控件如何使用&#xff0c;今天来看下QT的核心&#xff0c;信号与槽&#xff08;Signals and slots&#xff09;&#xff01; 简单理解一下&#xff0c;就是我们的信号与槽连接上了之后&#xff0c;发射一个信号给到槽&#xff0c;槽函数接收到了这个信…

0103水平分片-jdbc-shardingsphere-中间件

文章目录 1 准备服务器1.1 创建server-order0容器1.2 创建server-order1容器 2、基本水平分片2.1、基本配置2.2、数据源配置2.3、标椎分片表配置2.4、行表达式2.5、分片算法配置2.6、分布式序列算法 3、多表关联3.1、创建关联表3.2、创建实体类3.3、创建Mapper3.4、配置关联表3…

Linux 桌面上的 Firefox 面临着大问题

导读毫无疑问&#xff0c;无论是在桌面、笔记本电脑还是移动设备上&#xff0c;浏览器都是任何操作系统中最重要的应用之一。 如果没有一个功能强大、快速且稳定的浏览器&#xff0c;操作系统的实用性将大幅度降低&#xff0c;以至于我相当确定&#xff0c;如果一个操作系统没有…

哈佛商学院教授:每个老板使用ChatGPT之类AI工具的理由

哈佛商学院教授Karim Lakhani表示&#xff0c;每个老板都应该使用生成式人工智能工具&#xff0c;生成式AI为老板提供了一种更高效的工作方式&#xff0c;在提高生产力、提高规模、与客户沟通以及促进销售、社交媒体内容更新和新产品开发等方面都有积极意义。 Karim Lakhani表…

Vulnhub系列靶机---JIS-CTF-VulnUpload-CTF01靶机

文章目录 1、网卡配置2、信息收集主机发现端口扫描目录扫描 3、漏洞探测4、漏洞利用一句话木马蚁剑 GetShellSSH连接提权 JIS文档说明 JIS-CTF-VulnUpload-CTF01靶机下载地址 该靶机有5个flag 1、网卡配置 开启靶机&#xff0c;看见加载的进度条按shift&#xff0c;看到如下界…

大数据扫盲(2): 数据分析BI与ETL的紧密关系——ETL是成功BI的先决条件

着业务的发展每个企业都将产生越来越多的数据&#xff0c;然后这些数据本身并不能直接带来洞察力并产生业务价值。为了释放数据的潜力&#xff0c;数据分析BI&#xff08;商业智能&#xff09;成为了现代企业不可或缺的一部分。然而&#xff0c;在数据分析的背后&#xff0c;有…

SQLmap使用

文章目录 利用sqlmap 注入得到cms网站后台管理员账密获取数据库名称获取cms数据库的表名获取users表中的字段&#xff08;内容&#xff09;获取username字段和password字段的内容 salmap破解psot请求数据包salmap获取getshell 利用sqlmap 注入得到cms网站后台管理员账密 获取数…

关闭jenkins插件提醒信息

jenkins提醒信息和安全警告可以帮助我们了解插件或者jenkins的更新情况&#xff0c;但是有些插件是已经不维护了&#xff0c;提醒却一直存在&#xff0c;看着糟心&#xff0c;就像下面的提示 1、关闭插件提醒 找到如下位置&#xff1a;系统管理-系统配置-管理监控配置 打开管…

Error running ‘Tomcat 8.5.29‘ Address localhost:1099 is already in use

一、Error running ‘Tomcat 8.5.29’ Address localhost:1099 is already in use 原因&#xff1a;端口1099被占用了。 二、解决 2.1 解决方法一-结束该端口1099占用 //1-查看端口占用&#xff0c;根据端口号1099&#xff0c;获取PID(进程ID) netstat -ano | findstr "…

Plugin “Chinese (Simplified) Language Pack / 中文语言包“ was not installed

idea2020.3.4版本无法直接在下载汉化包 1、通常情况下&#xff0c;直接在idea里面下载插件即可&#xff0c;这里下载失败后进行下一步操作&#xff1a; 2、https://plugins.jetbrains.com/plugin/13710-chinese-simplified-language-pack----/versions 第一步&#xff1a;找到…

在iPhone 15发布之前,iPhone在智能手机出货量上占据主导地位,这对安卓来说是个坏消息

可以说这是一记重拳&#xff0c;但似乎没有一个有价值的竞争者能与苹果今年迄今为止的智能手机出货量相媲美。 事实上&#xff0c;根据Omdia智能手机型号市场跟踪机构收集的数据&#xff0c;苹果的iPhone占据了前四名。位居榜首的是iPhone 14 Pro Max&#xff0c;2023年上半年…
最新文章