关注我们

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

悠然悠然 安全文摘 2019-07-16 246498 0

在本篇文章中,我们将对CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞进行分析。

声明:本篇文章由 77@奇安信A-TEAM原创,仅用于技术研究,不恰当使用会造成危害,严禁违法使用,否则后果自负。

漏洞描述

Atlassian Jira是澳大利亚Atlassian公司的一套缺陷跟踪管理系统。该系统主要用于对工作中各类问题、缺陷进行跟踪管理。

Atlassian Jira Server和Jira Data Center存在服务端模板注入漏洞,成功利用此漏洞的攻击者可在运行受影响版本的Jira Server或Jira Data Center系统上执行任意命令。

目前PoC已放出,建议受影响的客户尽快升级或采用临时缓解措施。

  • 第一种情况,Jira服务端已配置好SMTP服务器,且“联系管理员表单”功能已开启(默认配置不开启);

  • 第二种情况,Jira服务端已配置好SMTP服务器,且攻击者具有"JIRA管理员"的访问权限。在第一种情况下,“联系管理员表单”功能开启的情况下,攻击者可以未经任何认证,通过向/secure/ContactAdministrators.jspa发起请求利用此漏洞。在第二种情况下,攻击者具有"JIRA 管理员"的访问权限下可通过/secure/admin/SendBulkMail!default.jspa利用此漏洞。

影响版本

  • 4.4.x

  • 5.x.x

  • 6.x.x

  • 7.0.x

  • 7.1.x

  • 7.2.x

  • 7.3.x

  • 7.4.x

  • 7.5.x

  • 7.6.x < 7.6.14

  • 7.7.x

  • 7.8.x

  • 7.9.x

  • 7.10.x

  • 7.11.x

  • 7.12.x

  • 7.13.x < 7.13.5

  • 8.0.x < 8.0.3

  • 8.1.x < 8.1.2

  • 8.2.x < 8.2.3

修复版本

  • 7.6.14

  • 7.13.5

  • 8.0.3

  • 8.1.2

  • 8.2.3

修复建议

升级到修复版本(7.6.14、7.13.5、8.0.3、8.1.2、8.2.3)。

漏洞简析

第二种利用场景前提是拿到Jira管理员的权限,利用条件较难满足,这里主要分析第一种情况。原因在于atlassian-jira/WEB-INF/classes/com/atlassian/jira/web/action/user/ContactAdministrators 未对Subject(邮件主题)处进行过滤,用户传入的邮件主题被当作template(模板)指令执行。在任何一种情况下,成功利用此漏洞的攻击者都可在运行受影响版本的Jira Server或Jira Data Center的系统上执行任意命令。

第一种,未授权代码执行利用条件:Jira已配置好SMTP服务器,且需开启“联系网站管理员表单”功能。(从WEB界面设计上看,实际上如果没配置SMTP服务器,无法开启此功能)

代码追踪

以Jira Server 7.13.0版本为例。

HTTP请求中的payload如何传入到服务端的subject对象中?

com.atlassian.jira.config.webwork.JiraActionFactory$SafeParameterSettingActionFactoryProxy#getActionImpl中调用setActionParameters方法,通过

webwork.action.ActionContext.getParameters();

拿到HTTP请求的各个参数。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

参考:https://docs.atlassian.com/DAC/javadoc/opensymphony-webwork/1.4-atlassian-17/reference/webwork/action/ActionContext.html 通过反射调用com.atlassian.jira.web.action.user.ContactAdministrators对象的setSubject(java.lang.String)方法,并将HTTP请求中的Subject参数传入进去。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

设置完之后,com.atlassian.jira.web.action.user.ContactAdministrators对象的subject属性已被设置成我们的payload。

payload如何传入到邮件对象的Subject中被Velocity模板引擎解析?

部分调用过程为:

...
=> com.atlassian.jira.web.action.user.ContactAdministrators#doExecute
=> com.atlassian.jira.web.action.user.ContactAdministrators#send
=> com.atlassian.jira.web.action.user.ContactAdministrators#sendTo
=> com.atlassian.jira.mail.builder.Email.Builder#withSubject(用户可控的Subject模板)
=> com.atlassian.jira.mail.builder.Email.Builder#renderLater
...

看具体代码 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞


   protectedStringdoExecute()throwsException{        if(!this.getShouldDisplayForm()) { //若“联系管理员表单”功能已开启,则进入else逻辑
           return"modebreach";
       } else {            this.send();            returnthis.getRedirect("/secure/MyJiraHome.jspa");
       }
   }    publicbooleangetShouldDisplayForm(){        //判断“联系管理员表单”功能是否开启
       returnthis.jiraContactHelper.isAdministratorContactFormEnabled();
   }

在send方法中,遍历系统所有管理员账号,看是否存在已激活的管理员,若至少有一个(administrator.isActive()),则传入该管理员对象,调用:this.sendTo(administrator)。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

    publicvoidsend()throwsMailException{
       Collection<ApplicationUser> administrators = this.userUtil.getJiraAdministrators();        //遍历系统所有管理员账号,看是否存在已激活的管理员
       Iterator var2 = administrators.iterator();        while(var2.hasNext()) {
           ApplicationUser administrator = (ApplicationUser)var2.next();            if (administrator.isActive()) {//若至少有一个
               this.sendTo(administrator);//传入该管理员对象
           }
       }

   }

在sendTo中,

    privatevoidsendTo(ApplicationUser administrator)throwsMailException{        try{
           Map<String, Object> velocityParams = Maps.newHashMap();            //from为客户端指定的邮箱地址,会校验邮箱格式
           velocityParams.put("from",this.replyTo);
           velocityParams.put("content",this.details);
           velocityParams.put("padSize", PADSIZE);            //获取该传入管理员的email地址,作为收件邮箱
           Email email = newEmail(administrator.getEmailAddress());
           email.setReplyTo(this.replyTo);            //将payload传入邮件发送队列
           MailQueueItem item = (newEmailBuilder(email,this.getMimeType(administrator), I18nBean.getLocaleFromUser(administrator))).withSubject(this.subject).withBodyFromFile(this.getTemplateDirectory(administrator) + "contactadministrator.vm").addParameters(velocityParams).renderLater();            this.mailQueue.addItem(item);
       } catch (Exception var5) {            this.log.error("Error sending JIRA Administrator email", var5);
       }

   }

com.atlassian.jira.mail.builder.EmailBuilder对象 通过withSubject(this.subject)方法传入用户指定的模板(template)命令,作为Subject(主题), 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

这里的payload是subjectTemplate,一个TemplateSource$Fragment对象。然后调用renderLater(),在atlassian-jira/WEB-INF/classes/com/atlassian/jira/mail/builder/EmailBuilder中,

    publicMailQueueItemrenderLater(){        returnnewRenderingMailQueueItem(this.createEmailRenderer());
   }    
   privateEmailRenderercreateEmailRenderer(){        returnnewEmailRenderer(this.email,this.subjectTemplate,this.bodyTemplate,this.attachments,this.templateParameters);
   }

将payload传入,得到一个com.atlassian.jira.mail.builder.EmailRenderer对象,然后把这个EmailRender对象作为参数构造com.atlassian.jira.mail.builder.Email.RenderingMailQueueItem对象。而RenderingMailQueueItem继承了com.atlassian.mail.queue.SingleMailQueueItem类。在其构造器中,调用父类构造器 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

SingleMailQueueItem 又继承了AbstractMailQueueItem类。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

至此,一个RenderingMailQueueItem对象已经构造完成, 得到了一个com.atlassian.mail.queue.MailQueueItem(这是一个接口)对象,然后将该对象加入到邮件发送队列com.atlassian.mail.queue.MailQueue中。轮到这个对象对应的邮件发送时,才会渲染这个待发邮件的Subject(主题),所以可能会有一定的延迟。

邮件发送线程

在启动邮件队列的线程中,调用栈如下:

renderEmailSubject:87, EmailRenderer (com.atlassian.jira.mail.builder)
render:149, EmailRenderer (com.atlassian.jira.mail.builder)
send:29, RenderingMailQueueItem (com.atlassian.jira.mail.builder)
sendBufferUnderLock:103, MailQueueImpl (com.atlassian.mail.queue)
sendBuffer:56, MailQueueImpl (com.atlassian.mail.queue)
apply:51, JiraMailQueue$1 (com.atlassian.jira.mail)
apply:48, JiraMailQueue$1 (com.atlassian.jira.mail)
runWithStaticBaseUrl:110, DefaultVelocityRequestContextFactory (com.atlassian.jira.util.velocity)
runWithStaticBaseUrl:50, DefaultBaseUrl (com.atlassian.jira.util)
sendBuffer:48, JiraMailQueue (com.atlassian.jira.mail)
run:21, MailQueueService (com.atlassian.jira.service.services.mail)
run:68, JiraServiceContainerImpl (com.atlassian.jira.service)
runService:62, ServiceRunner (com.atlassian.jira.service)
runServiceId:44, ServiceRunner (com.atlassian.jira.service)
runJob:32, ServiceRunner (com.atlassian.jira.service)
runJob:153, JobLauncher (com.atlassian.scheduler.core)
launchAndBuildResponse:118, JobLauncher (com.atlassian.scheduler.core)
launch:97, JobLauncher (com.atlassian.scheduler.core)
launchJob:443, CaesiumSchedulerService (com.atlassian.scheduler.caesium.impl)
executeLocalJob:410, CaesiumSchedulerService (com.atlassian.scheduler.caesium.impl)
executeQueuedJob:388, CaesiumSchedulerService (com.atlassian.scheduler.caesium.impl)
consume:285, CaesiumSchedulerService$1 (com.atlassian.scheduler.caesium.impl)
consume:282, CaesiumSchedulerService$1 (com.atlassian.scheduler.caesium.impl)
executeJob:65, SchedulerQueueWorker (com.atlassian.scheduler.caesium.impl)
executeNextJob:59, SchedulerQueueWorker (com.atlassian.scheduler.caesium.impl)
run:34, SchedulerQueueWorker (com.atlassian.scheduler.caesium.impl)
run:745, Thread (java.lang)

主要看前面三个,

renderEmailSubject:87,EmailRenderer(com.atlassian.jira.mail.builder)render:149,EmailRenderer(com.atlassian.jira.mail.builder)send:29,RenderingMailQueueItem(com.atlassian.jira.mail.builder)

RenderingMailQueueItem的send方法中,调用了EmailRender的render方法 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

atlassian-jira/WEB-INF/classes/com/atlassian/jira/mail/builder/EmailRenderer中:

render
=>renderEmailSubject
=>getTemplatingEngine().render(this.subjectTemplate).applying(contextParams).asPlainText();

使用默认的模板引擎对payload(Velocity模板)进行解析。

注:我们的payload对象subjectTemplate是一个com.atlassian.jira.template.TemplateSource$Fragment对象,通过之前的EmailRender的withSubject(this.subject)方法传入。而EmailRender的subject私有成员变量是通过反射调用ContactAdministratorssetSubject()方法从HTTP请求中传入(前面已分析)。

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

先是getTemplatingEngine()得到一个com.atlassian.jira.template.velocity.DefaultVelocityTemplatingEngine对象,然后调用render()方法: 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

调用applying生成一个org.apache.velocity.VelocityContext对象。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

调用

asPlainText()
=>asPlainText(StringWriter)
=>toWriterImpl()
=>writeEncodedBodyForContent()
=>VelocityEngine.evaluate()

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

其中fragment.getContent()就是我们的payload,传入进writeEncodedBodyForContent方法的第二个参数 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

再作为VelocityEngine#evaluate()的第四个参数,在操作系统上成功执行命令。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

具体到Velocity的API调用栈可以在catalina日志里看到。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

下图显示启动的计算器进程为Jira的子进程。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

漏洞修复

下载7.13.5版本代码,对比atlassian-jira/WEB-INF/classes/com/atlassian/jira/web/action/user/ContactAdministrators.java文件:

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

虽然用户输入的Subject为恶意payload,作为参数传进了 atlassian-jira/WEB-INF/classes/com/atlassian/jira/web/action/user/ContactAdministrators对象, 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

但是其subjectTemplate为硬编码的模板$subject,并没有将用户传入的payload直接传入这里的withSubject方法。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

于是无法在这里触发。

Demo

无需认证触发

实际触发时间可能为几秒到几十秒(终于录屏到一个快的作为演示...) 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

后台管理员权限触发

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

缓解措施

若无法及时升级Jira,可采取以下缓解措施:

  • 1、禁用”联系网站管理员“功能。设置=> 系统=> 编辑设置=> 联系管理员表单处选择“关”,然后点击最下面的“更新”保存设置。具体操作方式参考:https://confluence.atlassian.com/adminjiraserver/configuring-the-administrator-contact-form-974375905.html#Configuringtheadministratorcontactform-DisablingtheContactAdministratorsForm

验证生效方法:访问/secure/ContactAdministrators!default.jspa 出现:“您的Jira管理员尚未配置此联系表。”或“Your Jira administrator has not yet configured this contact form”。 

CVE-2019-11581 Atlassian Jira未授权服务端模板注入漏洞

  • 2、并且,禁止对/secure/admin/SendBulkMail!default.jspa的访问。

参考

  • https://confluence.atlassian.com/jira/jira-security-advisory-2019-07-10-973486595.html

  • https://jira.atlassian.com/browse/JRASERVER-69532


版权声明

本文仅代表作者观点,不代表黑白网立场。
如文章侵犯了您的权利,请通过邮箱联系我们删除。
详情查看:版权纠纷
E-Mail:server@heibai.org

喜欢0发布评论

评论列表

发表评论

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