上传文件的漏洞复现与修复

2023-10-27

本文只说一些我遇到过的上传文件的漏洞。毕竟漏洞太多,我又不可能全部发现。

(安全方面的小菜鸟)

可能你们的系统比较完善,针对这些漏洞,已有相应的防御手段。我们针对的是那种比较简单的系统(就是各位上大学时自己开发的小系统,哈哈哈)。

利用漏洞的具体效果,就不演示了。本文只是提供一些思路和方向。

工具:我装了kali,使用 burpsuite;Linux环境下的VirtualBox

要配一下,burpsuite的 proxy-->options

自己去哔哩哔哩找一下资料了解一下burpsuite的使用。

漏洞一:直接上传jsp、php、jspx、exe等这种在黑名单的文件。上传成功后,可以使用冰蝎等webshell工具去getshell

        如果系统没有对上传文件进行检测的话,直接上传这种带恶意代码的文件,再利用webshell的工具,就可以进入系统后台了。然后就可以做一些危险的事情:删除文件。

漏洞二:系统有个功能,编辑文件内容。写入新的内容后,点击提交,能修改文件内容。

        我们可以写入恶意代码,然后用burpsuite 抓包,修改文件名。

 

 点击放行。

漏洞三:系统中上传压缩包。上传成功后,系统会自动解压压缩包。这时,我们可以搞很多层深度的文件夹的压缩包(文件夹里有10000000层深度的文件夹);压缩包里有10000000000个文件;在压缩包中放非法文件(jsp/jspx/php等);上传的文件特别大(10G)

漏洞四:通过更改文件名后缀来绕过前端检测

.jspx改为 .html或者 .jpg 

然后上传,用burpsuite抓包,再修改文件名后缀。

 漏洞五:在图片中加入恶意代码,用文本编辑器打开,写东西

漏洞六:删除文件时,用burpsuite抓包,然后加一些特殊字符来删除其他目录下的文件

将"path":"/def.xml" 的文件修改为 "path":"../../../../../../XXXXX"

后面系统中会拼接出这样的路径(在生成File对象时用到的),

  

如果在/home/zcm目录下,恰好有 def.xml。

那么,就可以删除/home/zcm目录下的 def.xml。

"/home/zcm/workspace/git/DKEYAM/target/var/portal/realm/848e34b1-4829-4cdf-ac26-3afc7108cf81/login/mobile/../../../../../../../../../../def.xml"

如果将realm 改为 portal/文件夹中 一个不存在的文件夹名字,比如 no(随便起的),就找不到了。

即"/home/zcm/workspace/git/DKEYAM/target/var/portal/realm/848e34b1-4829-4cdf-ac26-3afc7108cf81/login/mobile/../../../../../../../../../../def.xml"   这个路径中的每一部分都要存在。

 

防御手段:(只说一下大体的思路)

因为是公司的代码,就不方便贴出来。就提示一些jar包吧。你们去查一下对应jar包的对应的类,有哪些方法,基本应该能搞定的。

        先使用枚举类,记录文件格式的文件幻数与文件格式的映射。这个文件幻数是用来防止:

一个.jspx的文件,手动重命名为 .png        这种情况的。

可以通过文件幻数来,看出真实的文件名后缀(真实的后缀名不一定是表面上的文件名后缀)。

比如HTML的十六进制流

 docx的


/**
 * @Author: zcm
 * @DateTime: 2021/10/22 下午5:20
 * @Description:
 * 各种格式的文件,经过一套特定的计算后,可以得到一个十六进制流。
 * 这个十六进制流的开头的一小段,就是所谓的文件幻数。
 * 不同格式的文件,它们十六进制流的开头的那一小段十六进制流是独特的,可以把这部分十六进制流当做ID,来识别对应的格式。
 */
public enum TrustFileType {
    /* image */
    JPEG("FFD8FFE0", ".jpg.jpeg"),   // jpg
    JPEG2("FFD8FFE1", ".jpg.jpeg"),   // jpg
    PNG("89504E47", ".png"),         // png
    GIF("47494638", ".gif"),         // gif
    /* 压缩包 */
    RAR("52617221", ".rar"),         // ARAR Archive
    GZ("1F8B08", ".gz"),             // gz
    /* 办公文档类 */
    XLS_DOCX("504B0304", "docx.pptx.xlsx.zip.jar"),  // pptx、docx、xlsx; zip压缩文件的文件幻数也一样
    RTF("7B5C727466", ".rtf"),
    PDF("255044462D312E", ".pdf"),
    /* 视频或音频类 */
    MP4("49443303000000002176", ".mp4"),   // mp4
    /* 程序文件 */
    XML("3C3F786D6C", ".xml"),     // XML
    HTML("3C21444", ".html"),   // HTML
    CSS("48544D4C207B0D0A0942", ".css"),   // css
    JS("696B2E71623D696B2E71", ".js"),     // js
    CLASS("CAFEBABE0000002E00", ".class"); // class
    // JAVA("7061636B", ".java"),  // java (任何时候禁止上传.java文件)
    // JSP("3C254020", ".jsp"),    // jsp  (任何时候禁止上传.jsp文件)
    // exe("4D5A9000", ".exe"),    // exe  (任何时候禁止上传.exe文件)
    
    private String fileSuffix = "";
    private String fileMagicNumber = "";

    TrustFileType(String fileSuffix) {
        this.fileSuffix = fileSuffix;
    }

    @Override
    public String toString() {
        return "TrustFileType{" +
                "fileSuffix='" + fileSuffix + '\'' +
                ", fileMagicNumber='" + fileMagicNumber + '\'' +
                '}';
    }

    TrustFileType(String fileSuffix, String fileMagicNumber) {
        this(fileSuffix);
        this.fileMagicNumber = fileMagicNumber;
    }

    public String getFileMagicNumber() {
        return fileMagicNumber;
    }
    public String getfileSuffix() {
        return fileSuffix;
    }
}
//文件幻数的计算
        InputStream is = File对象.getInputStream();
        byte[] src = new byte[28];
        is.read(src, 0, 28);
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v).toUpperCase();
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        stringBuilder.toString()这个StringBuilder的开头一小段十六进制流,就是文件幻数。这一小段是多长,自己看着截取就好。反正能标识出对应的文件格式就好。

1、对于压缩包,要检测文件夹的深度、里面的文件数量、压缩包大小。

解压前先 遍历一波文件,就直接过滤一波表面上的文件名后缀。

解压后,

checkCompressedFileMaxDepthAndMaxCount

检测一下文件的深度,文件的数量。

然后,在逐个遍历检查每个File 对象的文件幻数。

最后,要删除解压出来的临时文件。

对于非法文件的处理,如果发现有非法文件或者其他异常,就统一抛出异常,在这个调用链的上层(就是URL直接访问到的那个方法体内)去捕获异常。

throw new RuntimeException("含有非法文件!操作失败。");

异常往上抛出,抛到URL访问的方法体中,在这个方法体中去 catch

import com.google.common.io.Files;
import org.apache.commons.io.FileUtils;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
Files.createTempDir();
File.createTempFile

可以去这些包里面看看它们的方法,找找灵感。

2、对于图片中含有恶意代码

就搞个压缩函数,把这里面的代码打乱就好了。

3、对于含有特殊字符的文件路径(删除文件的方法)

/**
     * @Author: zcm
     * @DateTime: 2021/10/22 下午2:47
     * @Params: [java.lang.String, java.lang.String]
     * @Return boolean
     * @Description: 检测文件名是否合法。比如“/../../../../../../../../../../def.xml”
     * 这种就是不合法的。
     * 先检测 . 的个数
     * 再 将 dir目录下的文件名和filename 做比较。如果dir目录中没有这个filename,就返回 false
     */
    public static boolean isLegalFileName(String dir, String fileName){
        boolean isLegal = false;
        //检测 . 字符是否超过1个
        if (fileName.split("\\.").length > 1 ){
            return isLegal;
        }

        File dirFile = new File(dir);
        File[] files = dirFile.listFiles();
        String name = fileName.substring(fileName.indexOf("/") + 1);
        for (File i :files){
            if (i.getName().equals(name)){
                isLegal = true;
                break;
            }
        }
        return isLegal;
    }
if (!SecureFileUtils.isLegalFileName(root.getAbsolutePath(), path)){
            throw new RuntimeException("删除失败!存在非法路径!");
        }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

上传文件的漏洞复现与修复 的相关文章

  • 在 Linux 上访问 main 之外的主要参数

    是否可以访问参数main在外面main 即在共享库构造函数中 在 Linux 上除了通过解析之外 proc self cmdline 您可以通过将构造函数放入 init array部分 功能在 init array 不像 init 使用相同
  • dlopen 或 dlclose 未调用信号处理程序

    我在随机时间内收到分段错误 我注册了信号 但发生分段错误时未调用信号处理程序 include
  • 从 Python 访问 802.11 无线管理帧

    我想从 Linux 上的 Python 嗅探 802 11 管理 探测请求 帧 这可以从 Scapy 中实现 如下所示 coding utf 8 from scapy all import def proc p if p haslayer
  • Linux“屏幕”的 Windows 等效项还是其他替代方案?

    我正在寻找一种在 Windows 环境中控制程序的方法 我希望它与 Linux 软件有点相似 screen 我搜索的原因是我需要使用标识符启动一个程序 在 Windows 上 这样我以后就能够关闭该特定程序 而无需关闭其他任何程序 即使实际
  • 如何确定代码是否在信号处理程序上下文中运行?

    我刚刚发现有人正在从信号处理程序调用我编写的绝对不是异步信号安全的函数 所以 现在我很好奇 如何避免这种情况再次发生 我希望能够轻松确定我的代码是否在信号处理程序上下文中运行 语言是 C 但该解决方案不适用于任何语言吗 int myfunc
  • 如何从 Linux 内核模块获取使用计数?

    我对正在开发的内核模块的使用计数有疑问 我想打印它以进行调试 如何从模块代码中获取它 有问题的内核版本 Linux 2 6 32 module refcount http lxr linux no linux v2 6 34 1 inclu
  • 错误:命令“c++”失败,退出状态为 1

    所以我尝试按照以下说明安装 Pyv8https andrewwilkinson wordpress com 2012 01 23 integrating python and javascript with pyv8 https andre
  • 如何设置Java线程的CPU核心亲和力?

    我搜索了以前关于类似主题的帖子 但找不到合适的答案 因此提出这个问题 非常感谢您帮助回答 我知道在 Linux 中通过任务集命令设置进程与特定 CPU 核心的关联性 但我想设置 Java 线程与特定 cpu 核心的亲和力 以便属于同一进程的
  • 如何重命名 .tar.gz 文件而不提取内容并在 UBUNTU 中创建新的 .tar.gz 文件?

    我有一个命令将创建一个新的 tar gz现有文件中的文件 sudo tar zcvf Existing tar gz New tar gz 该命令将创建一个新的New tar gz从现有的文件Existing tar gz file 谁能告
  • XAMPP Windows 上的 Php Cron 作业

    嗯 我是这个词的新手CRON 据我所知 这是一个Unix安排特定操作在定义的时间间隔后执行的概念 我需要运行一个php文件 每小时更新一次数据库 但我的困惑在于安排执行 我在用XAMPP用于 Windows 7 上的本地开发测试 我发现了什
  • 使用 ProcessBuilder 运行 shell 脚本

    我正在尝试使用 Java 和 ProcessBuilder 运行脚本 当我尝试运行时 我收到以下消息 error 2 没有这样的文件或目录 我不知道我做错了什么 但这是我的代码 ps 我尝试只执行不带参数的脚本 错误是相同的 String
  • 计算 TCP 重传次数

    我想知道在LINUX中是否有一种方法可以计算一个流中发生的TCP重传的次数 无论是在客户端还是服务器端 好像netstat s解决了我的目的
  • 完整的 C++ i18n gettext()“hello world”示例

    我正在寻找完整的 i18ngettext 你好世界的例子 我已经开始了一个基于的脚本使用 GNU gettext 的本机语言支持教程 https web archive org web 20130330233819 http oriya s
  • 提高mysql导入速度[关闭]

    Closed 这个问题是与编程或软件开发无关 help closed questions 目前不接受答案 我有一个很大的数据库22GB 我曾经用过进行备份mysqldumpgzip 格式的命令 当我提取 gz 文件时 它会生成 sql文件的
  • 如何将 elf 解释器(ld-linux.so.2/ld-2.17.so)构建为静态库?

    如果我的问题不准确 我深表歉意 因为我没有太多 Linux 相关经验 我目前正在构建一个 Linux 从头开始 主要遵循 linuxfromscratch org 版本的指南 7 3 我遇到了以下问题 当我构建可执行文件时 获取一个称为 E
  • 为什么默认情况下不启用 arp 忽略/通告 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我有一个需要经验才能回答的具体问题 为什么 arp ignore arp announce 在 Linux 安装 例如 debian 上默认不启用 有
  • Bash - 比较 2 个文件列表及其 md5 校验和

    我有 2 个列表 其中包含带有 md5sum 检查的文件 即使文件相同 列表也具有不同的路径 我想检查每个文件的 md5 和 我们正在讨论数千个文件 这就是为什么我需要脚本来仅显示差异 第一个列表是普通列表 第二个列表是文件的当前状态 我想
  • 如何在特定的Java版本上运行应用程序?

    如何运行具有特定 Java 版本的应用程序 我安装了三个 Java 版本 myuser mysystem sudo update alternatives config java There are 3 choices for the al
  • 在用户程序中使用 或在驱动程序模块代码中使用 ...这有关系吗?

    我正在开发一个设备驱动程序模块和关联的用户库来处理ioctl 来电 该库获取相关信息并将其放入一个结构中 该结构被传递到驱动程序模块中并在那里解压 然后进行处理 我省略了很多步骤 但这就是总体思路 一些数据通过结构体传递ioctl is u
  • Apache LOG:子进程 pid xxxx 退出信号分段错误 (11)

    Apache PHP Mysql Linux 注意 子进程 pid 23145 退出信号分段错误 11 tmp 中可能存在 coredump 但 tmp下没有找到任何东西 我怎样才能找到错误 PHP 代码中函数的无限循环导致了此错误

随机推荐

  • 简述ApplicationContext和BeanFactory的区别

    ApplicationContext和BeanFactory都能获取到spring上下文对象 spring框架 他们二者有什么区别 区别一 他们属于不同的包 区别二 BeanFactory 和ApplicationContext都是属于Sp
  • 【程序设计】设计模式

    文章目录 概述 分类 创建型模式 Creational Patterns 结构型模式 Structural Patterns 行为型模式 Behavioral Patterns 各分类中的模式的关键点 策略模式与状态模式 策略模式与简单工厂
  • linux 开发 及 “发行版库” (**)

    linux 开发 与 发行版所提供的 库 做内核的做内核 做紫铜周边支持软件的做周边支持 做高级应用的做应用 linux 开发 与 发行版所提供的 库 Debian Sources Debian Sources Package list p
  • Dockerfile详解,以及构建自定义镜像

    Dockerfile使用 前面的操作我们一直下载下载官方已经构建好的镜像 直接下载后就可以run 如果我们想要在镜像中添加自己的应用 比如在tomcat中添加自己的app 构建一个自定义的镜像 那么我们应该怎么做 这个时候就用到了Docke
  • 径向基函数(RBF):如何将向量映射到无穷维?

    引言 假如气球是红黑颜色各涂一半的 爆炸之后落在地上时各色碎片相互交错 基本没有一条二维曲线可以将其分开 但是在气球没有爆炸之前 是不是可以用一个平面将两种颜色的 碎片 分开呢 是不是完全可分呢 因此 低维数据若不可分 将其映射到高维空间
  • Linux内核模块管理命令

    1 insmod命令 在Linux系统下 insmod命令用于将给定的模块加载到内核中去 Linux系统有许多功能是通过模块的方式 在需要时才载入kernel 这样做可以使kernel较为精简 进而提高效率 这类可载入的模块 通常是设备驱动
  • Pytorch学习笔记(六)

    简单的LeNet网络模型 torchvision datasets torchvision是pytorch的一个图形库 它服务于PyTorch深度学习框架的 主要用来构建计算机视觉模型 以下是torchvision的构成 torchvisi
  • 推荐一款好用的数据库 对比工具

    github https gitee com otman dbcompare
  • 设计模式(十八) 中介者模式

    当我们进行多人聊天的时候 如果程序写成一对一的结构 那么当人数一多的时候程序就无法维护了 所以更好的做法就是抽象出一个聊天服务器 每个用户只和服务器进行通信 这样抽取出一个中介者的设计模式 就是中介者模式 如果系统中有大量对象需要互相通信
  • (DecisionTreeRegressor)决策树回归实例-加州房价数据 学习笔记

    import matplotlib pyplot as plt import pandas as pd from sklearn dataset california housing import fetch california hous
  • 从组合中估计概率

    一些分类算法缺乏输出结果为概率的能力 比如rf 这个时候使用calibratedclassifiercv 它使用2种方法将分类结果转化为概率 第一种 platte的归类方法 第二种 isotonic回归 import pandas as p
  • Spring Cloud Gateway 添加统一前缀思路探讨

    1 前言 今天学习一下Spring Cloud Gateway 就先再其他博客上逛了逛 遇到有java开发者在某博客问一个问题 Spring Cloud Gateway 如何添加统一的前缀 当时没有在意 但是脑子里也带着这个问题看起了文档
  • git代码回滚

    git回退历史 有以下步骤 1 已push后回退 1 使用git log命令 查看分支提交历史 确认需要回退版本的
  • Vue.2.0.5-模板语法

    Vue js 使用了基于 HTML 的模版语法 允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据 所有 Vue js 的模板都是合法的 HTML 所以能被遵循规范的浏览器和 HTML 解析器解析 在底层的实现上 Vue 将模板编
  • 日志异常检测-机器学习

    日志搜集 大规模系统通常会生成日志来记录系统状态和运行时信息 每个日志都包括时间戳和指示发生了什么的日志消息 日志解析 日志是非结构化的 包含自由形式的文本 日志解析的目的是提取一组事件模板 从而可以构造原始日志 更具体地说 每个日志消息都
  • Java虚拟机:Java模块化系统

    Java模块化系统目录 1 Java模块化系统 2 模块化的兼容性 1 模块路径 2 模块化系统访问路径规则 3 它本身面临的模块间的管理和兼容性问题 3 模块化的类加载器 1 模块化下的类加载器变动 2 类加载的委派关系变动 1 Java
  • (jsp和servlet功能篇)jsp+servlet+jquery分页代码

    首先看运行效果图 第一步 编写servlet 代码 package com rf servlet import java io IOException import java io OutputStream import java sql
  • 继续干IT的十个理由

    在其文章 不干IT的十个理由 中 Jack Wallen列举了一些离开IT这个行业的理由 而我呢 则愿意提供一个不同的观点 下面有我自己的一些思考 这些也许能对阐明为什么你应当留在IT有所帮助 1 钱 钱 钱 对 我们努力工作就是为了赚钱
  • python实现Lasso回归

    Lasso原理 Lasso与弹性拟合比较python实现 import numpy as np import matplotlib pyplot as plt from sklearn metrics import r2 score def
  • 上传文件的漏洞复现与修复

    本文只说一些我遇到过的上传文件的漏洞 毕竟漏洞太多 我又不可能全部发现 安全方面的小菜鸟 可能你们的系统比较完善 针对这些漏洞 已有相应的防御手段 我们针对的是那种比较简单的系统 就是各位上大学时自己开发的小系统 哈哈哈 利用漏洞的具体效果