kkFileView远程代码执行漏洞分析

kkFileView远程代码执行漏洞分析

哈拉少安全小队 2024-04-24 12:17

kkFileView由于前台上传功能在处理压缩包时,从仅获取文件名改为获取文件名及其目录,导致出现了Zip Slip漏洞。这使得攻击者可上传包含恶意代码的压缩包并覆盖系统文件,随后通过调用这些被覆盖的文件实现远程代码执行。

影响版本

漏洞复现

复测版本:4.2.1

下载地址:
https://github.com/kekingcn/kkFileView/tree/v4.2.1

使用IDEA搭建,并运行

RCE漏洞复现

构造恶意的zip包

将zip包上传并预览,路径为我当前本地搭建的,不一定通用

成功将内容写入到了
uno.py

接着上传任意odt后缀的文件,并预览

成功执行弹窗计算器

漏洞分析

根据
https://github.com/kekingcn/kkFileView/issues/553
给出的漏洞点分析

关键代码在CompressFileReader 类,该类主要将上传的zip解压,但是解压时获取文件名及其目录,导致可以覆盖任意文件内容和写入任意文件

我们一步步调试看看,下断点

在56行代码中,extractPath为文件路  folderName为上传的zip文件名称

File file = new File(extractPath, folderName + “_” + File.separator + str1);

在57行代码中  判断文件是否为空,为空就创建目录

接着创建文件流,但是他写入文件是将目录一下写入了,使用
../../
即可导致任意文件内容覆盖

虽然写入文件,但是没有调用uno.py的方法,根据大佬的方法

目标在使用odt转pdf时会调用系统的Libreoffice,而此进程会调用库中的uno.py文件

接着分析预览odt


OfficeToPdfService
类中 将
.odt
文件转为PDF文件

并成功执行
calc

下面代码就是执行 LibreOffile  

builder.build().convert(inputFile).to(outputFile).execute();

来分析一下
builder

从代码中  
builder
是  
LocalConverter.Builder
定义的

build

LocalConverter.Builder
类实现  
build

execute()

这段代码定义了一个名为
doExecute()
的方法,该方法用于执行文档转换任务。让我们逐步分析它:
1. useStreamAdapters
变量用于确定是否使用流适配器。它的值取决于
LocalConverter
对象的
loadDocumentMode
属性和
officeManager
的类型。

  1. 如果
    loadDocumentMode

    REMOTE
    ,或者
    loadDocumentMode

    AUTO

    officeManager

    ExternalOfficeManager
    的实例,则设置为
    true
    ;否则设置为
    false

  2. 创建一个
    LocalConversionTask
    对象,用于表示本地文档转换任务。构造方法接受源文件、目标文件、是否使用流适配器、加载属性、存储属性和过滤器链等参数。

  3. 使用
    officeManager
    执行上述创建的文档转换任务
    task

总结

OutputStream out = new FileOutputStream( extractPath+ folderName + “_” + File.separator + str[0], true);
 使用
../../
即可导致任意文件内容覆盖

builder.build().convert(inputFile).to(outputFile).execute();
转换pdf是启动了LibreOffile 并执行
C:\Users\26927\Downloads\kkFileView-4.2.1\server\libreoffice\program\uno.py
脚本中内容导致RCE

文中漏洞分析可能不准确,个人java水平有限