泛微云桥e-Bridge任意文件上传漏洞分析
Harder 发表于 北京 技术文章 2184浏览 · 2024-08-09 01:57

泛微云桥e-Bridge任意文件上传漏洞分析

作者:Harder@微步漏洞团队

漏洞详情:

关于最近爆的泛微云桥e-Bridge文件上传感觉很有意思,这个文件上传是绕过了安全函数对.jsp后缀检测,一个多请求文件上传,通过后一个正常图片的请求覆盖Hash表,回传uploadFile对象实现回传而绕过isSafeFile方法对后缀的检测

入口点在weaver.weixin.app.recruit.controller.ResumeController

@ActionKey("/wxclient/app/recruit/resume/addResume")
@Before({Tx.class})
public void addResume() throws Exception {
    try {
        WxBaseFile wbFile = null;
        if (this.getContentType().toLowerCase().startsWith("multipart/form-data")) {
            wbFile = this.getWxBaseFile(this.wxBaseFileService, this.getPara("fileElementId"), (String)null, 2097152, (String)null);
        }

        ResumeModel model = (ResumeModel)this.getModel(ResumeModel.class, "resume");
        if (wbFile != null) {
            model.set("accessory", wbFile.getId());
        }

        if (this.resumeService.addResume(model, this.getPara("sysagentid"))) {
            this.renderJsonMsgForIE("提交成功", true);
        } else {
            this.renderJsonMsgForIE("提交失败", false);
        }

    } catch (Exception var3) {
        Exception e = var3;
        if (e.getMessage().indexOf("2097152") != -1) {
            this.renderJsonMsgForIE("上传文件大小不能超过2M", false);
        } else {
            this.log.error(e.getMessage(), e);
            this.renderJsonMsgForIE("程序异常,请联系管理员!", false);
        }

        throw e;
    }
}

跟着调用看看

public UploadFile getFile(String parameterName, String saveDirectory, Integer maxPostSize, String encoding) {  
    getFiles(saveDirectory, maxPostSize, encoding);  
    return getFile(parameterName);  
}

大概调用栈就是这样,跟着下面关键代码走就行

weaver.weixin.app.recruit.controller.ResumeController#addResume=>weaver.weixin.core.controller.BaseController#getWxBaseFile=>com.jfinal.core.Controller#getFile=>com.jfinal.core.Controller#getFiles=>com.jfinal.upload.MultipartRequest#MultipartRequest=>com.jfinal.upload.MultipartRequest#wrapMultipartRequest=>javax.servlet.http.HttpServletRequest#MultipartRequest

在这其实已经完成了第一个uploadFile对象的请求上传。然后进行了第二次请求,把第二个uploadFile对象也上传了。然后我们继续往下走

这里的函数multipartRequest.getFilesystemName跟踪进去可以看到,是非常有说法的,它返回的是files的name值的然后转换的UploadedFile对象,然后在根据这个UploadedFile对象的getFilesystemName()的方法获取filesystemName的名字。然后我们可以看看这个files是什么东西

files是类com.oreilly.servlet.MultipartRequest类中的Hash表,是用来存储文件上传的键值对的

其实回头看,我们可以发现我们请求一被覆盖掉了,因为在这个请求里面file是key,两个文件上传的name都是file,键值是一样的。然后就会导致我们第二个请求harder.png会覆盖掉之前的key,然后键值对就会变成png的键值对,后续的请求都是.png的UploadFile对象

这下面就利用这个.png的uploadFile对象绕过了isSafeFile方法的检测

然后就上传成功了。这个洞其实上传的jsp恶意文件是落地到文件夹里面的,所以我们可以用条件竞争的方法来Bypass。但是这个框架的路径是随机1-2位大写字母的,所以这个条件竞争难度较大。

对于JFinal的jsp文件解析绕过,这篇文章讲的很清楚了

我大概总结一下,产生的原因是因为tomcat和JFinal获取和处理路径的方式不同,所以进行了bypass。

绕过方法呢大概就是:

1.对后缀的jsp进行urlencode编码

2.对jsp后面加一个; 比如harder.jsp;就可以实现绕过了

最后十分感谢Le1a师傅的帮助

7 条评论
某人
表情
可输入 255