漏洞出现于com.seeyon.ctp.portal.engine.templete.PortalCssEngine#getCss,漏洞点在replace = String.valueOf(ScriptEvaluator.getInstance().eval(eval.trim(), context));可以将eval.trim()作为Groovy表达式执行,参数来自经过一些处理的template匹配Pattern.compile(":(.+?);/\\*\\[this row need calculate\\]\\*/");的行,对template的处理:

for (Map.Entry<String, String> entry : defaultValue.entrySet()) {
	String k = entry.getKey().trim();
	String v = "";
	if (datas != null && datas.size() > 0) {
	String varKey = k.substring(1, k.length()).trim();
	v = datas.get(varKey);
	if ("wrapperBgi".equals(varKey) && Strings.isNotBlank(v) && null != (wrapperBgiArr = v.split(",")) && wrapperBgiArr.length > 1) {
		v = wrapperBgiArr[0] + "\")";
		logger.info("wrapperBgi:=" + v);
	}
}
if (Strings.isNotBlank(v)) {
	template = template.replace(k, v);
} else {
	template = template.replace(k, entry.getValue());
}

看样子对后面的逻辑影响不大。获取template的逻辑:

String template = templates.get(templateName);
Map<String, String> defaultValue = null;
if (Strings.isBlank(template)) {
	try {
		if (Strings.isNotBlank(defaultPath) && defaultPath.contains(";")) {
			if (portalManagerObj != null && (portalManagerObj instanceof PortalManager)) {
				String[] ids = defaultPath.split(";");
				if (ids.length == 2) {
				String scssfileId = ids[0];
				String valueScssFileId = ids[1];
				PortalManager portalManager = (PortalManager) portalManagerObj;
				try {
				CtpFile valueScssFile = portalManager.getFileFromResrouceFolder(PortalFileTypeEnum.SCSS, valueScssFileId);
				CtpFile scssFile = portalManager.getFileFromResrouceFolder(PortalFileTypeEnum.SCSS, scssfileId);
				if (valueScssFile != null && valueScssFile.exists() && scssFile.exists()) {
					defaultValue = readDefaultValues(valueScssFile.getAbsolutePath());
					template = FileUtils.readFileToString(scssFile, encode);
					}
				} catch (BusinessException e) {
				logger.error(e);
				}
			}
		}
	} else {
		String prefixPath = defaultPath.replace(".css", "");
		template = FileUtils.readFileToString(new CtpLocalFile(SystemEnvironment.getApplicationFolder() + prefixPath + ".scss"), encode);
		defaultValue = readDefaultValues(SystemEnvironment.getApplicationFolder() + prefixPath + "_value.scss");
	}
} catch (IOException e2) {
	logger.error("样式模板加载失败!", e2);
}

如果templates.get(templateName)的值为空,则从文件读取,大概观察了一下,如果要控制这里,应该是要走if里面的逻辑。既然需要控制template就要控制文件内容并且需要知道对应的templateName,直接去找代码有点大海捞针,先去看看能不能找到对应的功能点。