欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

CVE-2019-11580漏洞分析

来源:本站整理 作者:佚名 时间:2019-09-10 TAG: 我要投稿

CVE-2019-11580为Atlassian Crowd和Atlassian Crowd Data Center 输入验证错误漏洞,此漏洞是因为没有对上传的jar文件校验,直接当做插件进行安装,本文是对Atlassina Crowd的pdkinstall插件RCE漏洞的分析。Atlassian Crowd和Atlassian Crowd Data Center都是澳大利亚Atlassian公司的产品,Atlassian Crowd是一套基于Web的单点登录系统,该系统为多用户、网络应用程序和目录服务器提供验证、授权等功能,Atlassian Crowd Data Center是Crowd的集群部署版。集中式身份管理的管理来自多个目录(Active Directory、LDAP、OpenLDAP 或 Microsoft Azure AD)的用户,并在一个位置控制应用身份验证权限。而单点登录 (SSO)则为用户提供一组用户名和密码来登录需要访问的所有应用,让他们的生活更加轻松。无缝集成 Jira、Confluence 和 Bitbucket 等所有 Atlassian 产品,为你的用户提供单一登录 (SSO) 体验。
以下产品及版本受到影响:Atlassian Crowd 2.1.x版本,3.0.5之前的3.0.x版本,3.1.6之前的3.1.x版本,3.2.8之前的3.2.x版本,3.3.5之前的3.3.x版本,3.4.4之前的3.4.版本;Atlassian Crowd Data Center 2.1.x版本,3.0.5之前的3.0.x版本,3.1.6之前的3.1.x版本,3.2.8之前的3.2.x版本,3.3.5之前的3.3.x版本,3.4.4之前的3.4.版本。
目前该漏洞的危害等级被定义为超危,威胁类型属于远程漏洞。目前厂商已发布升级补丁以修复漏洞,补丁获取链接:https://confluence.atlassian.com/x/3ADVOQ。
原因分析
Atlassian Crowd和Atlassian Crowd Data Center在发布版本中错误地启用了pdkinstall开发插件,能够向Crowd或CrowdData Center实例发送未经身份验证或经过身份验证的请求的攻击者可以利用此漏洞安装任意插件,从而允许在运行受到影响版本的Crowd或CrowdData Center的系统上远程执行代码。
在网上搜索了一番之后,我找不到任何针对该漏洞的概念验证,因此我决定对其进行分析并尝试创建一个。
首先,我会复制插件的源代码,源代码可以在这里找到。
root@doggos:~# git clone https://bitbucket.org/atlassian/pdkinstall-plugin
Cloning into 'pdkinstall-plugin'...
remote: Counting objects: 210, done.remote: Compressing objects: 100% (115/115), done.remote: Total 210 (delta 88), reused 138 (delta 56)Receiving objects: 100% (210/210), 26.20 KiB | 5.24 MiB/s, done.Resolving deltas: 100% (88/88), done.
我们可以在./main/resources/atlassian-plugin.xml找到插件描述符文件(plugin descriptor )。每个插件都需要一个插件描述符文件,该文件只包含 “描述了一个插件和它所包含的用于主机应用程序的模块”的XML。
    ${project.version}
   
    /admin/uploadplugin.action
    /admin/plugins.action
我们可以看到通过访问/admin/uploadplugin.action来调用Java servlet类com.atlassian.pdkinstall.PdkInstallFilter。由于我们知道这个漏洞是通过任意插件安装的RCE,所以很明显,必须首先查看PdkInstallFilter servlet的源代码。
让我们将pdkinstall-plugin导入IntelliJ,这样就可以开始阅读源代码了。我们将从doFilter()方法开始。
我们可以看到,如果请求方法不是POST,它会退出并返回一个错误:
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) servletRequest;HttpServletResponse res = (HttpServletResponse) servletResponse;if (!req.getMethod().equalsIgnoreCase("post")){
    res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Requires post");
    return;}
接下来,它确定请求是否包含多部分内容。多部分内容是一个单独的主体,它包含一个或多个组合在一起的不同数据集。如果它包含多部分内容(Multipart Content),它将调用extractJar()方法来提取请求中发送的jar,否则它将调用buildJarFromFiles()方法,并尝试从请求中的数据构建插件jar文件。
// Check that we have a file upload requestFile tmp = null;boolean isMultipart = ServletFileUpload.isMultipartContent(req);if (isMultipart){
    tmp = extractJar(req, res, tmp);}else{
    tmp = buildJarFromFiles(req);}
现在,让我们将注意力转移到extractJar()方法。
private File extractJar(HttpServletRequest req, HttpServletResponse res, File tmp) throws IOException{
    // Create a new file upload handler
    ServletFileUpload upload = new ServletFileUpload(factory);
    // Parse the request
    try {
        List items = upload.parseRequest(req);
        for (FileItem item : items)
        {
            if (item.getFieldName().startsWith("file_") && !item.isFormField())
            {
                tmp = File.createTempFile("plugindev-", item.getName());
                tmp.renameTo(new File(tmp.getParentFile(), item.getName()));
                item.write(tmp);

[1] [2] [3]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载