JAVA代码审计之文件上传代码审计

news2024/11/30 8:41:33

1 文件上传简介

1.1 什么是任意文件上传漏洞

任意文件上传漏洞常发生在文件上传功能中,由于后端代码中没有严格限制用户上传的文件,导致攻击者可以上传带有恶意攻击代码的JSP 脚本到目标服务器,进而执行脚本,以达到控制操纵目标服务器等目的。

1.2 任意文件上传漏洞危害

如果目标服务器存在任意文件上传漏洞,服务将会面临巨大风险,包括但不限于:服务器的网页被篡改,网站被上传木马,服务器被远程控制,被安装后门,执行挖矿程序等。

2 任意文件上传漏洞代码审计

在对文件上传功能进行代码审计时我们主要分析整个上传流程对所上传文件做了什么样的操作。进而分析是否能够造成任意文件上传漏洞。

我们比较关注的几点:

①、SpringBoot对JSP的限制。

②、文件后缀名是否存在白名单。

③、文件类型是否存在白名单。

④、所保存的路径是否能够解析JSP。

⑤、文件头检测。

但是Springboot相关官方禁止使用一些JSP文件,并做了一些限制,若想使用,需要添加如下依赖:

<!--用于编译jsp-->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

2.1 会遇见的一些限制

2.1.1 文件后缀名校验

主要关注后端是否对上传的文件后缀名进行了检查判断。如果在后端对后缀名没有限制。那么就极有可能存在任意文件上传漏洞。很多项目是通过前端限制文件上传类型。但是我们都可以通过抓包的方式修改后缀为webshll文件(php,jsp),以达到上传Webshell的目的。下图就是一个案例,后端获取文件名(26行),然后进行"目录"+"文件"进行拼接,无过滤情况。这时候就可以上传webshell了。

2.1.2文件后缀名校验黑白名单

如果后端使用了黑白名单限制后缀名已经初步起到了一定的防护作用。但具体还需要根据实际情况分析。如果是黑名单是否存在遗漏的情况,或者一些解析漏洞,例如添加%00,或者Windows对大小写并不敏感,甚至利用windows的特性DATA,可能就会绕过黑名单检测。

2.1.3 文件名操作

在这里我们关注上传的文件名是否有所改动。常见的情况是后端直接接受保存我们上传的文件名。但也常后端自定义不可预测的文件名,比如使用UUID。比如以下代码:

String originalFileName = file.getOriginalFilename();
String extension = originalFileName.substring(originalFileName.lastIndexOf('.'));
String fileName = UUID.randomUUID() + extension;

将文件名随机命名可以增加一些攻击利用难度。但并没有直接修复任意文件上传漏洞。很多时候由于代码编写不规范会将上传后的路径,文件名也会显示在前端。

除此之外,可能还会存在一种情况,就是可能会对图片进行操作,也就是存在二次渲染的情况,这时候就要判断未改变的字节位置,插入webshell。

2.1.4 保存路径

在这里我们关注是否保存在本地,保存文件路径是否是在非解析路径,保存路径是否可控。

文件保存在云存储服务器:

存在以下一种情况,可能将文件保存在云存储服务器,例如七牛云OSS,阿里OSS等,假若保存在了OSS上,尽管成功上传了Webshell,但是无法执行,也没有任何作用。如果允许上传html文件,也可以尝试上传html文件,进而造成xss漏洞获取cookie。

文件保存在本地,但是无法执行:

可能我们幸幸苦苦找到了一个文件上传点,绕过了层层限制,上传成功后,却发现无法解析,这时候就得想想文件上传后,目录是否可以穿越了,在获取文件名后,大多会进行路径拼接操作。如果保存图片的地址是非解析目录,我们可以配合目录穿越漏洞操作WebShell存储到其他地方,尝试执行。例如下列代码,没有进行校验,可以拼接相关文件名。

String fileName = file.getOriginalFilename();
String filePath = path + fileName;

2.2 文件上传功能关键字

大家在对完整项目进行代码审计时,尽量整理收集尽可能多的信息,确定系统功能点,进而可以针对性的进行代码审计。

在面对一个完整的项目中有我常用以下方式定位上传功能,比如:查看需求文档,查看Controller层,部署后通过前端定位功能点,全局搜索关键字等等。

下面给出一些文件上传关键字,帮助你快速定位是否存在文件上传功能。

File
FileUpload
FileUploadBase
FileItemIteratorImpl
FileItemStreamImpl
FileUtils
UploadHandleServlet
FileLoadServlet
FileOutputStream
DiskFileItemFactory
MultipartRequestEntity
MultipartFile
com.oreilly.servlet.MultipartRequest
......

3 演示案例

在实际代码审计过程中,我们可以结合白+黑的模式来进行审计,首先找到上传功能点,然后通过上传功能点进一步审计,找到绕过的方法。

3.1 寻找上传点

以下为一个演示案例

这里找到了一个上传的前端页面,我们先上传一个测试文件试试。发现接口为"/image/gok4"。

进入源码中,全局搜索相关关键字,但是发现并没有找到这个接口。

有可能在引入的jar包中,在jar包中进行搜索,找到了相关接口。

3.2 代码审计

源代码如下

public String gok4(HttpServletRequest request, HttpServletResponse response,
                   @RequestParam(value = "uploadfile", required = true) MultipartFile uploadfile,
                   @RequestParam(value = "param", required = false) String param,
                   @RequestParam(value = "fileType", required = true) String fileType,
                   @RequestParam(value = "pressText", required = false) String pressText) {
    try {
        long maxSize = 4096000L;
        System.out.println(uploadfile.getSize());
        if (uploadfile.getSize() > maxSize) {
            return this.responseErrorData(response, 1, "上传的图片大小不能超过4M。");
        } else {
            String[] type = fileType.split(",");
            this.setFileTypeList(type);
            String ext = FileUploadUtils.getSuffix(uploadfile.getOriginalFilename());
            if (fileType.contains(ext) && !"jsp".equals(ext)) {
                String filePath = this.getPath(request, ext, param);
                File file = new File(this.getProjectRootDirPath(request) + filePath);
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }

                uploadfile.transferTo(file);
                return this.responseData(filePath, 0, "上传成功", response);
            } else {
                return this.responseErrorData(response, 1, "文件格式错误,上传失败。");
            }
        }
    } catch (Exception var13) {
        logger.error("gok4()--error", var13);
        return this.responseErrorData(response, 2, "系统繁忙,上传失败");
    }
}

首先是2-5行的代码,这几行代码含义是需要添加的参数,true为必须携带的参数,false为可以选择携带或者不携带的参数。uploadfile和fileType必须携带。

接着是7-10行的代码,这几行是判断文件大小的参数,文件需要小于4mb,否则上传失败

long maxSize = 4096000L;
System.out.println(uploadfile.getSize());
if (uploadfile.getSize() > maxSize) {
    return this.responseErrorData(response, 1, "上传的图片大小不能超过4M。");

再看12-14行代码,首先是12行的代码,获取filetype参数的内容,并以","进行分割,获取每条数据,最后,将上传的文件名赋值给ext

 String[] type = fileType.split(",");
            this.setFileTypeList(type);
            String ext = FileUploadUtils.getSuffix(uploadfile.getOriginalFilename());

最后就是15-20行的内容了,这里首先是判断上传文件的扩展名并检查是否在允许的文件类型列表中,且不为JSP文件。 如果满足以上两个条件,即可直接保存该文件。

if (fileType.contains(ext) && !"jsp".equals(ext)) {
                String filePath = this.getPath(request, ext, param);
                File file = new File(this.getProjectRootDirPath(request) + filePath);
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }

这里我们回到原来的数据包,原来filename的文件后缀需要满足filetype的参数,只要存在filetype里的参数,即可上传。

我们尝试在fileType上添加一个jsp文件,并将文件后缀改为jsp进行尝试,发现上传失败,因为在第15行代码已经明确提示,不能上传jsp文件。

3.3 绕过分析

有什么绕过方法呢,这里有两种绕过方法,一种是上传jspx格式的文件,还有一种就说利用windows特性了,利用DATA方式进行绕过。

3.3.1 利用jspx进行绕过

首先介绍以下jspx,jspx实际上是一种JavaServer Pages(JSP)文件的格式,它扩展了标准的JSP技术。JSP是一种用于构建动态网页的技术,允许开发者在HTML中嵌入Java代码。jspx文件继承了JSP的这些特性,并添加了额外的功能。

修改fileType并添加jspx,发现可以上传成功。

3.3.2 利用windows特性DATA绕过

其次是DATA绕过,注:DATA绕过只能是目标主机是windows系统。

通过修改fileType,添加一个jsp::$DATA

访问上传地址,发现能够正常解析,相关webshell就不一一演示啦。

4 修复方案

列出允许的扩展。只允许业务功能的安全和关键扩展
确保在验证扩展名之前应用输入验证。
验证文件类型,不要相信Content-Type头,因为它可以被欺骗。
将文件名改为由应用程序生成的文件名
设置一个文件名的长度限制。如果可能的话,限制允许的字符
设置一个文件大小限制
只允许授权用户上传文件
将文件存储在不同的服务器上。如果不可能,就把它们存放在webroot之外。
在公众访问文件的情况下,使用一个处理程序,在应用程序中被映射到文件名(someid -> file.ext)。
通过杀毒软件或沙盒(如果有的话)运行文件,以验证它不包含恶意数据。
确保任何使用的库都是安全配置的,并保持最新。
保护文件上传免受CSRF攻击

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

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

相关文章

cesium 渐变虚线效果 PolylineDashMaterialProperty

cesium中有虚线材质PolylineDashMaterialProperty&#xff0c;可以在这个材质的基础上结合uv设置每个顶点的透明度&#xff0c;就能实现渐变的效果了。 一、原理&#xff1a;在glsl中结合uv设置每个顶点的透明度 vec2 st materialInput.st; material.alpha fragColor.a * (1…

【SpringCloud】创建新工程

前言 本文使用的是jdk17&#xff0c;mysql8。 以下用两个服务做演示&#xff1a; 订单服务&#xff1a;提供订单ID&#xff0c;获取订单详细信息。 商品服务&#xff1a;提供商品ID&#xff0c;获取商品详细信息。 对于订单服务和商品服务分别建立数据库&#xff1a; -- 订单服…

Javaweb避坑指北(持续更新)

内容较多可按CtrlF搜索 0.目录 1.获取插入数据后自增长主键的值 2.Controller中返回给ajax请求字符串/json会跳转到xxx.jsp 3.ajax请求获得的json无法解析 4.在Controller中使用ServletFileUpload获取的上传文件为null 5.莫名其妙报service和dao里方法的错误 6.ajax请求拿…

期权费的核心是什么

期权费的核心 在涉足股票期权投资的领域时&#xff0c;投资者们往往会将焦点首先锁定在期权费这一显性成本上。然而&#xff0c;实际操作中&#xff0c;一个更为核心且决定性的考量因素是&#xff0c;目标股票是否具备通过个股期权策略进行买入的潜在价值。特别是&#xff0c;…

NFTScan 正式上线 Sei NFTScan 浏览器和 NFT API 数据服务

2024 年 6 月 12 号&#xff0c;NFTScan 团队正式对外发布了 Sei NFTScan 浏览器&#xff0c;将为 Sei 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商&#xff0c;Sei 是继 Bitcoin、Ethereum、BNBChain、Polyg…

数据安全“大考”,双一流高校们来交卷!

又是一年高考落幕 埋头题山卷海的考生们 终于迎来“大解放”&#xff01; 在数字化浪潮中 众高校面临的重要考试 ——“数据安全大考”还在继续 如何作答&#xff1f; 这些双一流高校交出高分答卷&#xff01; 数据分类分级如何开展落地&#xff1f; 难点分析&#xff1…

python游标卡尺什么梗

python游标卡尺什么梗&#xff1f;下面给大家介绍一下这个梗&#xff1a; 因为 python 是通过缩进来区分代码块的&#xff08;而不是{}或者是其他符号&#xff09;&#xff0c;而不是像其他程序语言&#xff0c;缩进仅仅为了可读性。导致打印出来的 python 代码&#xff08;比…

神经气体生长算法【GNG】

当德国计算神经学家 Bernd Fritzke 在其 1995 年的开创性论文中提出后来被称为神经气体生长&#xff08;GNG&#xff09;的算法时&#xff0c;机器学习还是一个相对较新的领域&#xff0c;并且受到实际神经科学的极大启发。 当时&#xff0c;神经科学正处于一个突破性的时代—…

目标检测:将yolo标注的txt文本转为VOC标注的xml文件

1、准备工作 目标检测数据的标注分为两种格式&#xff1a; xml 解释性标签&#xff0c;左上角右下角的坐标txt 记事本文件&#xff0c;类别x&#xff0c;y中心坐标w&#xff0c;h的相对值 需要准备的数据有&#xff1a; 其中images为图像数据&#xff0c;labels为txt文本信息…

【Python】已解决报错:NameError: name ‘xxx‘ is not defined

【Python】已解决报错&#xff1a;NameError: name ‘xxx‘ is not defined &#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主。 &#x1f913; 同时欢迎大…

C++学习笔记(23)——二叉树进阶

系列文章 http://t.csdnimg.cn/QDR3y 目录 系列文章[TOC](目录) 1. 二叉树的优势2. 二叉搜索树概念3. 二叉搜索树操作1. 二叉搜索树的查找2. 二叉搜索树的插入——地址链接重设3. 二叉搜索树的删除——地址链接重设 4. 二叉搜索树的应用——以key为载体&#xff0c;承载复杂信…

618家用智能投影仪推荐:这个高性价比品牌不容错过

随着科技的不断进步&#xff0c;家庭影院的概念已经从传统的大屏幕电视逐渐转向了更为灵活和便携的家用智能投影仪。随着618电商大促的到来&#xff0c;想要购买投影仪的用户们也开始摩拳擦掌了。本文将从投影仪的基础知识入手&#xff0c;为您推荐几款性价比很高的投影仪&…

QGroupbox,Grid Layout,button 水平延伸 布局

实验 sizePolicy水瓶延伸 拖入一个groupbox控件 在groupbox控件中拖入一个grid layout 控件 然后拖入3个pushButton 使其水平排列&#xff0c; 设置button3的 sizePolicy 水平延展 为1 效果

工程项目管理系统:高效、专业的工程管理软件

在当今快速发展的工程行业&#xff0c;有效的项目管理是确保项目成功的关键。鸿鹄工程项目管理系统&#xff0c;基于Spring Cloud、Spring Boot、Mybatis、Vue和ElementUI技术栈&#xff0c;提供了一个全面、高效的解决方案&#xff0c;以应对复杂的工程项目管理挑战。 项目背景…

精益思维在人工智能中的应用体现

随着AI技术的广泛应用&#xff0c;如何提高其效率、降低成本、优化性能&#xff0c;成为了业界关注的焦点。精益思维作为一种追求卓越、持续改进的管理理念&#xff0c;其在人工智能中的应用正逐渐展现出巨大的潜力。 一、数据精益化管理。数据是AI技术的核心&#xff0c;而数据…

JavaScript知识之函数

javascript函数 在JavaScript基础之上提供了部分函数,同时也可以自定义函数,JavaScript基础详见之前的文章javascript基础知识 自定义函数 //关键字 函数名 参数列表 函数体 function test(a,b,c){alert(a":"b":"c) }function test1(a,b){return a;//不…

一文读懂Samtec分离式线缆组件选型 | 快速攻略

【摘要/前言】 2023年&#xff0c;全球线缆组件市场规模大致在2100多亿美元。汽车和电信行业是线缆组件最大的两个市场&#xff0c;中国和北美是最大的两个制造地区。有趣的是&#xff0c;特定应用&#xff08;即定制&#xff09;和矩形组件是两个最大的产品组。 【Samtec产品…

huggingface_hub LocalEntryNotFoundErroringface

报错详细 LocalEntryNotFoundError: An error happened while trying to locate the file on the Hub and we cannot find the requested files in the local cache. Please check your connection and try again or make sure your Internet connection is on.问题说明 在…

肾合养生秘诀:告别手心热出汗的困扰

如果将我们的身体比作一支精心编排的交响乐团&#xff0c;那么各个器官便是乐团中不可或缺的乐器和乐手&#xff0c;而气血则如同乐团中的乐谱和指挥棒&#xff0c;引领着整个乐团的演奏。当乐谱缺失&#xff0c;指挥棒失灵&#xff0c;或者乐团的协作出现问题&#xff0c;某些…

CAN转PROFINET,轻松实现降本增效!AGV行业必备连接通信方案大揭秘!

随着工厂自动化发展以及柔性制造系统、自动化立体仓库的广泛应用&#xff0c;已作为管理离散型装配、物流、仓储等系统不可或缺的自动化搬运装卸工具&#xff0c;智能化AGV系统可根据ERP订单进行仓库配料、分料、产品装配以及出入库、包装物流等环节。 AGV由导航系统、传感器系…