代码审计Spring Integration Zip不安全解压(CVE-2018-1261)漏洞分析

Posted sqyysec

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码审计Spring Integration Zip不安全解压(CVE-2018-1261)漏洞分析相关的知识,希望对你有一定的参考价值。

1.漏洞相关信息

漏洞名称:Spring Integration Zip不安全解压

漏洞编号:CVE-2018-1261

漏洞描述:在spring-integration-zip.v1.0.1.RELEASE之前的版本中,恶意用户通过在压缩文件中构造包含有特定文件名称的文件(受影响文件格式有bzip2, tar, xz, war, cpio, 7z),应用程序使用spring-integration-zip进行解压时,会导致跨目录任意写入文件漏洞的攻击。进而有可能被Getshell,远程控制。

漏洞原理:攻击者可以通过构造一个包含名称带../前缀的文件的压缩包,在spring-integration-zip进行解压时文件跳出解压文件的目录限制,创建文件

漏洞利用前置条件

1.使用了spring-integration-zip库

2.接收并解压了来自不可信来源的压缩文件

2.环境搭建

Libraries:

技术分享图片

3.漏洞复现

恶意压缩包文件内容

技术分享图片

技术分享图片

测试代码如下

unZipTransformer.setWorkDirectory(path);设置了解压文件的路径,在CVE-2018-1261目录下会生成good.txt文件,而eval文件就会逃出限制,在根目录生成文件

import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.zip.transformer.UnZipTransformer;
import org.springframework.messaging.Message;

import java.io.File;
import java.io.InputStream;

public class Main {
    private static ResourceLoader resourceLoader = new DefaultResourceLoader();
    private static File path =  new File("./CVE-2018-1261/");
    public static void main(final String... args) {
        final Resource evilResource = resourceLoader.getResource("classpath:zip-malicious-traversal.zip");
        try{
            InputStream evilIS = evilResource.getInputStream();
            Message<InputStream> evilMessage = MessageBuilder.withPayload(evilIS).build();
            UnZipTransformer unZipTransformer = new UnZipTransformer();
            //设置解压文件的目录为CVE-2018-1261
            unZipTransformer.setWorkDirectory(path);
            unZipTransformer.afterPropertiesSet();
            //漏洞入口点
            unZipTransformer.transform(evilMessage);
        }catch (Exception e){
            System.out.println(e);
        }
    }
}

示例中的UnZipTransformer.transform()会调用doZipTransform()来处理压缩包

技术分享图片

在遍历压缩包内目录及文件时,回调ZipEntryCallback中的process()对其进行处理

ZipUtil.iterate(inputStream, new ZipEntryCallback() {
    @Override
    public void process(InputStream zipEntryInputStream, ZipEntry zipEntry) throws IOException {
    
        final String zipEntryName = zipEntry.getName();
        ...
        if (ZipResultType.FILE.equals(zipResultType)) {
            final File tempDir = new File(workDirectory, message.getHeaders().getId().toString());
            tempDir.mkdirs(); //NOSONAR false positive
            final File destinationFile = new File(tempDir, zipEntryName);
    
            if (zipEntry.isDirectory()) { ...   }
            else {
                SpringZipUtils.copy(zipEntryInputStream, destinationFile);
                uncompressedData.put(zipEntryName, destinationFile);
            }
        }
    ...
}

../../../那一串是通过zipEntry.getName()得到的

final File destinationFile = new File(tempDir, zipEntryName);确定解压目录

接着就是调用copy put

技术分享图片

获取传过来的输入数据以及从文件系统中的某个文件中获得输入字节,把数据写到destinationFile处

技术分享图片

要提前在根目录下创建tmp文件夹

技术分享图片

以上是关于代码审计Spring Integration Zip不安全解压(CVE-2018-1261)漏洞分析的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Integration JDBC Outbound Gateway 更新数据

spring integration:如何从 Spring Controller 调用 Spring Integration?

Spring-Integration:在异常时不发送Tcp服务器响应

什么时候应该使用 Spring Integration 或相关框架?

Shiro系列之Shiro+Spring MVC整合(Integration)

Shiro系列之Shiro+Spring MVC整合(Integration)