漏洞出现于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,直接去找代码有点大海捞针,先去看看能不能找到对应的功能点。