Skip to main content
  1. Posts/

DreamerCMS Vulnerable Collection

··757 words·
loading
·
Table of Contents
Vulnerable - This article is part of a series.
Part 3: This Article

Ref
#

DreamerCMS V4.0.1 Tips: 原始项目已跑路, 该仓库为我的一个 fork, 选择 fuzz 分支或者对应的标签
DreamerCMS V4.0.1 代码审计1
DreamerCMS V4.0.1 代码审计2

Vulnerables
#

SQL Injection
#

${typeid}注入
#

  • dreamer_cms/src/main/resources/mapping/ArchivesMapper.xml
<select id="queryListByKeywords" parameterType="java.util.Map" resultType="cn.itechyou.cms.vo.ArchivesVo">
    select 
        a.id
        , a.title
        , a.properties
        , a.image_path imagePath
        , a.tag
        , a.description
        , a.category_id categoryId
        , a.category_ids categoryIds
        , a.comment
        , a.subscribe
        , a.clicks
        , a.weight
        , a.status
        , a.create_by createBy
        , a.create_time createTime
        , a.update_by updateBy
        , a.update_time updateTime
        , CASE WHEN a.category_id = '-1' THEN '顶级栏目' ELSE c.cnname END AS categoryCnName
        , CASE WHEN a.category_id = '-1' THEN 'Top Column' ELSE c.enname END AS categoryEnName
    from system_archives a
    LEFT JOIN system_category c ON a.category_id = c.id
    where 1 = 1 
    <if test="keywords != null and keywords != ''">
    	and title like concat('%',concat(#{keywords,jdbcType=VARCHAR},'%'))
    </if>
    <if test="typeid != null and typeid != ''">
    	and c.code in (${typeid})
    </if>
</select>

可以看到 ${typeid} 为潜在注入点
使用 IDE 寻找调用接口

  • cn.itechyou.cms.dao.ArchivesMapper#queryListByKeywords

    • cn.itechyou.cms.service.impl.ArchivesServiceImpl#queryListByKeywords
      • cn.itechyou.cms.controller.admin.SearchController#doSearch
    • cn.itechyou.cms.taglib.tags.PageListTag#parse
      • cn.itechyou.cms.taglib.ParseEngine#parsePageList
        • cn.itechyou.cms.controller.FrontController#search
  • admin/search/dosearch, 即 admin 模式下的全局搜索功能

@RequestMapping("/doSearch")
public String doSearch(Model model ,SearchEntity params) {
	if(params.getEntity() == null) {
		Map<String,Object> entity = new HashMap<String,Object>();
		params.setEntity(entity);
	}
	PageInfo<ArchivesVo> archives = archivesService.queryListByKeywords(params);
	model.addAttribute("keywords", params.getEntity().containsKey("keywords") ? params.getEntity().get("keywords") : "");
	model.addAttribute("archives", archives);
	return "admin/search/result";
}

只需要注入 key 值为 typeid 即可

POST /admin/search/doSearch HTTP/1.1

entity%5B%27typeid%27%%5D=SQL_INJECTION
  • /search, 前台搜索功能
@RequestMapping(value = "/search")
public void search(Model model, SearchEntity params) throws CmsException {
	System system = systemService.getSystem();
	StringBuffer templatePath = new StringBuffer();
	Theme theme = themeService.getCurrentTheme();
	String templateDir = fileConfiguration.getResourceDir() + "templates/";
	if(theme == null) {
		
	}
	templatePath.append(theme.getThemePath());
	templatePath.append("/search.html");

	if(params.getPageNum() == null)
		params.setPageNum(1);
	if(params.getPageSize() == null)
		params.setPageSize(10);
	
	try {
		Map<String, Object> entity = params.getEntity();
		if(entity == null || !entity.containsKey("keywords")) {
			throw new FormParameterException(
					ExceptionEnum.FORM_PARAMETER_EXCEPTION.getCode(),
					ExceptionEnum.FORM_PARAMETER_EXCEPTION.getMessage(),
					"请仔细检查Form表单参数结构,正确参数格式应该包含entity['keywords']、pageNum、pageSize。");
		}
		
		String keywords = params.getEntity().get("keywords").toString();
		if(keywords.getBytes("GBK").length < 3) {
			throw new FormParameterException(
					ExceptionEnum.FORM_PARAMETER_EXCEPTION.getCode(),
					ExceptionEnum.FORM_PARAMETER_EXCEPTION.getMessage(),
					"搜索关键字不能少于5个字符,请重新输入后进行搜索。");
		}
		
		String path = templateDir + templatePath;
		File template = new File(path);
		if(!template.exists()) {
			throw new TemplateNotFoundException(
					ExceptionEnum.TEMPLATE_NOTFOUND_EXCEPTION.getCode(),
					ExceptionEnum.TEMPLATE_NOTFOUND_EXCEPTION.getMessage(),
					"请仔细检查" + template.getAbsolutePath() + "文件,或检查application.yml中的资源目录配置项(web.resource-path)。");
		}
		String newHtml = "";
		String html = FileUtils.readFileToString(template, "UTF-8");
		//如果为静态浏览,则生成页面
		if(2 == system.getBrowseType()) {
			newHtml = parseEngine.generate(html);
		}else {
			newHtml = parseEngine.parse(html);
		}
		newHtml = parseEngine.parsePageList(newHtml, params);
		
		//记录搜索关键词
		SearchRecord sr = new SearchRecord();
		sr.setId(UUIDUtils.getPrimaryKey());
		sr.setKeywords(keywords);
		sr.setCreateTime(new Date());
		searchRecordService.add(sr);
		
		//输出HTML
		outHtml(newHtml);
	} catch (IOException e) {
		throw new TemplateReadException(
				ExceptionEnum.TEMPLATE_READ_EXCEPTION.getCode(),
				ExceptionEnum.TEMPLATE_READ_EXCEPTION.getMessage(),
				"请仔细检查模版文件,或检查application.yml中的资源目录配置项(web.resource-path)。");
	}
}

可以看出有一定的约束条件, 需要保留 keyword

POST /search HTTP/1.1

entity%5B%27keywords%27%5D=qwert&entity%5B%27typeid%27%5D=')SQL_INJECTION
Vulnerable - This article is part of a series.
Part 3: This Article

Related