Java代码审计篇——ofcms

环境搭建:

参考 从零开始-IDEA部署开源CMS:ofcms1.1.4 问题及解决汇总

版本: v1.1.3

漏洞分析

后台任意文件上传

漏洞点

模板文件 -> 模板文件 -> 模板目录 -> 修改index.html

对应代码

对应的代码在ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/cms/TemplateController控制器中的save方法

image-20220806110022744
/**
 * 保存模板
 */
public void save() {
    String resPath = getPara("res_path");
    File pathFile = null;
    if("res".equals(resPath)){
        pathFile = new File(SystemUtile.getSiteTemplateResourcePath());
    }else {
        pathFile = new File(SystemUtile.getSiteTemplatePath());
    }
    String dirName = getPara("dirs");
    if (dirName != null) {
        pathFile = new File(pathFile, dirName);
    }
    String fileName = getPara("file_name");
    // 没有用getPara原因是,getPara因为安全问题会过滤某些html元素。
    String fileContent = getRequest().getParameter("file_content");
    fileContent = fileContent.replace("&lt;", "<").replace("&gt;", ">");
    File file = new File(pathFile, fileName);
    FileUtils.writeString(file, fileContent);
    rendSuccessJson();
}

这里是直接通过上传文件,来替换掉原文件来达到修改文件的功能。但是没有对传入的file_namefile_content进行过滤,导致可以直接任意上传文件

如果resPath=res,那么新建文件的位置就在resource/defaultfile_name=../../static/le1a.jsp

image-20220806112003716

如果respath=空,那么新建文件的位置就在WEB-INF/page/default,file_name=../../../static/le1a.jsp

image-20220806112810995

默认res是空的,这里直接抓包修改file_name=../../../static/le1a.jsp,然后发包

file_path=F%3A%5CCTF2%5Capache-tomcat-9.0.58%5Cwebapps%5Cofcms_admin_war%5CWEB-INF%5Cpage%5Cdefault%5Cindex.html&dirs=%2F&res_path=&file_name=../../../static/le1a.jsp&file_content=哥斯拉jsp马的url编码
image-20220806122436172
image-20220806114726959
image-20220806122636469

存储型XSS

评论接口 ofcms-api/src/main/java/com/ofsoft/cms/api/v1/CommentApi.java

/**
 * 评论接口
 *
 * @author OF
 * @date 2019年2月24日
 */
@Action(path = "/comment")
public class CommentApi extends ApiBase {
    /**
     * 获取内容信息
     */
    @ApiMapping(method = RequestMethod.GET)
    @ParamsCheck(
            {@ParamsCheckType(name = "comment_content"), @ParamsCheckType(name = "content_id"),
                    @ParamsCheckType(name = "site_id")})
    public void save() {
        try {
            Map params = getParamsMap();
            params.put("comment_ip", IpKit.getRealIp(getRequest()));
            Db.update(Db.getSqlPara("cms.comment.save", params));
            rendSuccessJson();
        } catch (Exception e) {
            e.printStackTrace();
            rendFailedJson();
        }
    }

}

在save方法中调用了getParamsMap方法,获取用户提交的所有参数。然后通过getRealIp()方法把获取到的IP写入params参数的comment_ip键,然后调用 Db.update()方法把数据更新到数据库中。在这当中没有对用户传入的comment_content进行过滤。

可以直接传入<script>alert("23333")</script>导致XSS,我本地环境好像有问题,直接网络连接失败,换了个环境测试了一下

image-20220806133638162