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

news2024/11/18 6:04:33

文件上传漏洞-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.coloradmin.cn/o/920256.html

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

相关文章

内网安全:WMI协议与SMB协议横向移动

目录 网络拓扑图 网络环境说明 WMI协议 SMB协议 域内信息收集 WMI协议 - 横向移动 利用方式一&#xff1a;wmic命令 利用方式一&#xff1a;cscript 利用方式一&#xff1a;impacket SMB协议 - 横向移动 利用方式一&#xff1a;psexec 利用方式二&#xff1a;psexe…

外贸客户开发:如何通过谷歌地图找到外贸大客户?

前言&#xff1a;这篇文章分享的实操案例对于外贸从业者特别有用&#xff0c;并分享了一款免费可用的浏览器插件进行如何批量获客。 做外贸需要找客户成交&#xff0c;外贸业务员成单的前提是就是找到国外客户。 外贸找客户的方法无外乎两种&#xff1a; 第一种是主动出击第…

三、pikachu之文件上传

文章目录 1、文件上传概述2、客户端检测2.1 客户端检测原理及绕过方法2.2 实际操作之client check 3、服务端检测3.1 MIME type3.3.1 检测原理3.3.2 绕过方法3.3.3 实际操作之MIME type 3.2 文件内容检测3.2.1 检测原理3.2.2 绕过方式3.2.3 实际操作之getimagesize() 3.3 其他服…

前端学习记录~2023.8.10~JavaScript重难点实例精讲~第6章 Ajax

第 6 章 Ajax 前言6.1 Ajax的基本原理及执行过程6.1.1 XMLHttpRequest对象&#xff08;1&#xff09;XMLHttpRequest对象的函数&#xff08;2&#xff09;XMLHttpRequest对象的属性 6.1.2 XMLHttpRequest对象生命周期&#xff08;1&#xff09;创建XMLHttpRequest对象&#xff…

[C++入门]---vector深度剖析及模拟实现

文章目录 1. vector功能函数模拟实现vector成员变量定义vecor构造函数vector迭代器vector的size函数vector的capacity函数vector的operator[]函数vector的reserve函数vector的resize函数vector的insert函数vector的erase函数vector的push_back函数vector的pop_back函数vector的…

三维重建_体素重建_空间雕刻法/体素着色法

目录 1. 三角化和体素重建的区别 2. 空间雕刻法 空间雕刻法的一致性定义 空间雕刻法具体实现 基于八叉树的空间雕刻法具体实现​编辑 空间雕刻法效果展示 3. 体素着色法 体素着色法的缺点&#xff1a;不唯一性​编辑 体素着色法不唯一性解决措施​编辑 体素着色发实验环境与…

edge浏览器使用jupyter notebook删除快捷键没有用?

按快捷键删除没有用&#xff0c;出现一个黑色方框&#xff0c;里面的数字不断在加 解决方法&#xff1a; 在扩展中将Global Speed控制视频速度的插件关掉&#xff0c;或者将控制速度的快捷键改一下 可以在浏览器设置 》扩展 》管理扩展 里面关掉该插件 可以在Global Speed 的…

安达发APS|三分钟了解智能制造!

智能是由“智慧”和“能力”两个词语构成。从感觉到记忆到思维这一过程&#xff0c;称为“智慧”&#xff0c;智慧的结果产生了行为和语言&#xff0c;将行为和语言的表达过程称为“能力”&#xff0c;两者合称为“智能”。 因此&#xff0c;将感觉、记忆、回忆、思维、语言、…

1631. 最小体力消耗路径

你准备参加一场远足活动。给你一个二维 rows x columns 的地图 heights &#xff0c;其中 heights[row][col] 表示格子 (row, col) 的高度。一开始你在最左上角的格子 (0, 0) &#xff0c;且你希望去最右下角的格子 (rows-1, columns-1) &#xff08;注意下标从 0 开始编号&…

Python+TinyPNG熊猫网站自动化的压缩图片

前言 本篇在讲什么 PythonTinyPNG自动化处理图片 本篇需要什么 对Python语法有简单认知 依赖Python2.7环境 依赖TinyPNG工具 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f449;…

VMware Workstation Pro 无法使用开机状态下拍的快照来克隆虚拟机,怎么解决?

环境: VMware Workstation Pro16.0 Win10 专业版 问题描述: VMware Workstation Pro有台虚拟机在开机状态下拍了个6.7快照这个win10初始版,现在想在这个快照下直接克隆,无法使用开机状态下拍的快照创建克隆 解决方案: 1.关闭当前虚拟机 2.到虚拟机文件夹复制一份Wind…

web---Vue2_语法学习

文章目录 1、Vue2 常用指令1.1 初始Vue1.2 Vue的两种模板语法1.3 数据绑定1.4 el和data的两种写法1.5 MVVM模型1.6 Vue中的数据代理1.7 事件处理--事件的基本使用1.7 事件处理--事件修饰符1.7 事件处理--键盘事件1.8 计算属性1.9 监视属性1.9 深度监视2.0 绑定css样式2.1 条件渲…

如果将PC电脑变成web服务器:使用python3监测公网IP实现DDNS

如果将PC电脑变成web服务器&#xff1a;使用python3监测公网IP实现DDNS 上一篇文章中&#xff0c;我们使用Nignx的反向代理和端口转发实现域名访问家里主机上的web了。 由于家庭宽带基本都是动态IP&#xff0c;每当你重启一次光猫&#xff0c;IP地址就会变化一次。当光猫因为…

网络知识点之-堆叠与集群(2-集群)

本文章收录至《网络》专栏&#xff0c;点击右上角专栏图标可访问本专栏&#xff01; 集群是一种用于集团调度指挥通信的​​​​​​移动通信系统&#xff0c;主要应用在专业移动通信领域。该系统具有的可用信道可为系统的全体用户共用&#xff0c;具有自动选择信道功能&#x…

5G NR:PRACH频域资源

PRACH在频域位置由IE RACH-ConfigGeneric中参数msg1-FrequencyStart和msg1-FDM所指示&#xff0c;其中&#xff0c; msg1-FrequencyStart确定PRACH occasion 0的RB其实位置相对于上行公共BWP的频域其实位置(即BWP 0)的偏移&#xff0c;即确定PRACH的频域起始位置msg1-FDM的取值…

UNIX网络编程卷一 学习笔记 第二十八章 原始套接字

原始套接字提供普通的TCP和UDP套接字不具备的以下3个能力&#xff1a; 1.有了原始套接字&#xff0c;进程可以读写ICMPv4、IGMPv4、ICMPv6等分组。例如&#xff0c;ping程序就使用原始套接字发送ICMP回射请求并接收ICMP回射应答。多播路由守护程序mrouted也使用原始套接字发送和…

Linux服务——http协议及nginx服务

目录 一、HTTP协议 1、跨网络的主机间通讯方式 套接字相关的系统调用 2、HTTP协议访问网站的过程 3、http协议状态码分类 常见的http协议状态码 4、MIME 5、URL组成 6、HTTP协议版本 7、系统处理http请求的工作模式 8、apache与nginx的区别 二、I/O模型 I/O模型相关…

春秋云镜 CVE-2019-16113

春秋云镜 CVE-2019-16113 Bludit目录穿越漏洞 靶标介绍 在Bludit<3.9.2的版本中&#xff0c;攻击者可以通过定制uuid值将文件上传到指定的路径&#xff0c;然后通过bl-kernel/ajax/upload-images.php远程执行任意代码。 启动场景 漏洞利用 exp https://github.com/Kenun…

Matlab绘制灰度图像

灰度图介绍 灰度图像是指每个像素的信息由一个量化的灰度级来描述的图像。如果每个像素的灰度值用一个字节表示&#xff0c;灰度值级数就等于256级&#xff0c;每个像素可以是0-255之间的任何一个数。其特点是&#xff1a;它只有亮度信息&#xff0c;没有颜色信息。占据存储空…

Java IO流(四)Netty理论[模型|核心组件]

概述 Netty是由JBOSS提供的一个Java开源框架,可从Github获取独立项目Netty是一个异步的、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端(摘录官网)Netty所谓的异步是针对用户使用Channel进行IO操作,会立即返回ChannelFuture。但IO操作的任务是提…