Struts2系列漏洞起始篇
前言
到目前位置struts2的漏洞编号已经到了S2-057,一直想系统的学习下Struts2的漏洞,但由于工作量较大,一直搁浅。最近由于工作需要,借此机会来填下坑。个人认为一个框架漏洞出来了仅仅看下别人分析的文章是远远不够,因为这些文章往往都只针对个别漏洞,可能框架中还存在类似的漏洞你依然发现不了。所以我说需要系统的学习下,从框架的源码开始分析它的工作流程(当然这里我会有所取舍,全部都讲没意义),同时这样也会加深自己对该框架的理解,之后如果一个新的漏洞出来了,你可以仅根据官方的公告或变动的代码很简单地还原整个漏洞,同时这样做对代码审计也会有一定的帮助。这是我struts2系列文章的第一篇,篇幅会比较长(实际上分析源码的地方我已经省了很多)。之后我还会写spring、tomcat等系列的漏洞分析文章。
准备工作
我使用的是eclipse+struts-core2.1.6,struts2的各版本是由些许区别的,但是大致流程都是相同的,这里采用较老的版本是因为S2早期的漏洞都可以在里面找到,方便分析。
Struts2的工作流程
在原生的jsp+servlet项目中,常用会到Filter过滤器来过滤一些参数等等,这里struts2就是将自己的核心过滤器配置在web.xml中,这样可以让指定的HTTP请求都经过Struts2。早期struts2的核心过滤器是FilterDispathcer (org.apache.struts2.dispatcher.FilterDispatcher),但是struts2>=2.1.3之后就变为了StrutsPrepareAndExecuteFilter,而StrutsPrepareAndExecuteFilter在配置的时候也经常会分开为StrutsPrepareFilter和StrutsExecuteFilter,这是方便开发者更加灵活的使用,配置信息如下:
Filter的执行顺序是然配置顺序来的,所以这里我们先从StrutsPrepareFilter开始分析。
一个Filter比较重要的两个方法,一个是init一个doFilter,init是Filter初始化的时候才会调用,一般是容器刚启动时,而传入的参数FilterConfig实际上就是对应web.xml中的Filter配置信息,doFilter方法是一个Filter功能实现的核心。Filter处理StrutsPrepareFilter的init方法主要是初始化dispatcher,这是由于dispatcher是一个非常重要的类,但是由于如果详细解释dispatcher比较麻烦,大家有兴趣可以自行了解。
这里主要分析doFilter方法,59行处调用了工具类PrepareOperations的createActionContext创建一个action的上下文。
由于是第一次,所以会进入到else分支中,74行处通过工厂模式创建了一个ValueStack(值栈),大家到这里debug一下就知道这里创建的实例实际上是一个OgnlValueStack对象,而它就是Struts2的ognl表达式注入的元凶(后面我们分析漏洞的时候再进入该类中看下源码)。随后又将request对象、response对象以及servlet上下文放入了OgnlValueStack中的Context属性(一个map),并用该Context又创建了action上下文并返回。
回到StrutsPrepareFilter的doFilter方法中,assignDispatcherToThread将当前dispatcher放入到当前本地线程中,setEncodingAndLocale用于设置请求的本地化,语言以及编码格式,不用管。需要注意的是wrapRequest方法,该方法根据请求类型的不同,采用不同的request包装类,当为'multipart/form-data'时代表文件下载,将使用JakartaMultiPartRequest类,此类与S2-045有关,我们之后的文章再详细分析。findActionMapping方法用于构建action的映射类,最后调用do.Filter进入到下一个过滤器(这里是StrutsExecuteFilter)。
更进findActionMapping函数:
同样的,大家在184行处debug一下就知道了这里调用的是DefaultActionMapper的getMpping方法,跟进:
该方法内就是通过uri来解析对应的action配置信息,例如namespace、actionname、method。parseNameAndNamespace方法根据uri和配置文件中的namespace进行对比来判断namespace,S2-057漏洞就和该函数相关(后面的文章分析)。handleSpecialParameters是struts2识别请求url后的特殊参数然后做一些特殊做处理,S2-016、S2-017、S2-018都与此函数相关。会识别如下四种特殊字符:
parseActionName方法用于,当项目开启了动态方法调用时,也就是struts.xml配置了常量<constant name="struts.enable.DynamicMethodInvocation" value=
"true" />时,识别 !后面字符串作为action的method。
到这里StrutsPrepareFilter就分析完了,主要工作有两点:一是为struts2执行做一些相关的准备,如加载相关的配置信息。二是为struts2的request请求处理相关的信息。
接下来到了StrutsExecuteFilter,该拦截器才是真正执行action请求的,进入doFilter方法:
跟进executeAction发现实际上是调用了Dispatcher.serviceAction,这里直接跟进serviceAction就好了:
值得注意的是如果此时的mapping中已经有了Result说明该请求时直接访问的页面,将会进入if分支,执行StrutsResultSupport.execute方法,关于这个方法,我们后面会讲到。
StrutsActionProxy的execute方法中实际上又是通过调用了DefaultActionInvocation的invoke来执行action的
也就是说Dispatcher类是重要的调结者,而DefaultActionInvocation类才是执行action类实例的行动者。action代理类(ActionProxy类)则是他们之间的中间人。相当于Dispatcher类通过action代理类(ActionProxy类)命令DefaultActionInvocation类去执行action类实例。跟进DefaultActionInvocation的invoke方法:
struts2自动的默认拦截器中也存在很多问题,不仅只有S2-019,还有S2-020(ParametersInterceptor)、S2-021(ParametersInterceptor)、S2-022(CookieInterceptor)
跟进invokeActionOnly中又通过调用了invokeAction,跟进invokeAction:
大家可以看到invokeAction中才是真正执行action的地方,不过由于版本的不同,高版本中该函数内并不是通过反射机制而是ognl表达式来的执行的action。执行完action中的方法后将会返回一个Result对象。Result对象就是将mvc模式中controller层和view层连接起来的地方。
回到DefaultActionInvocation的invoke方法中,执行完action后就是操作返回的result了。
跟进executeResult方法:
createResult()就是我们之前说的,执行完action后如果返回的是字符串,需要去配置文件(struts.xml)中找对应的Result类型,如果没有设置type默认是dispatcher,对应着的Result类是org.apache.struts2.result.ServletDispatcherResult。所有的Result类都会继承StrutsResultSupport类,这里execute方法时父类StrutsResultSupport的(前面提到过这个),跟进:
1.conditionalParse用于处理房前的location,也就是跳转地址,里面会判断location是否有ognl表达式,有的话将会执行表达式,也是因为可能是动态返回结果。我们后面分析漏洞时后详细介绍该函数。
2.接着就是调用StrutsResultSupport子类的doExecute了。
Struts2自带多个Result类型,在struts-default.xml中可以看到
strut2的部分漏洞也是和他们相关的,比如说S2-031就和xslt这个返回类型有关。
这里我们只进入ServletDispatcherResult类中的doExecute看看
里面的内容比较简单,大概就是通过请求转发到下一个servlet(jsp本身就是一个servlet)。到这里struts2的基本工作流程就分析完了
参考文章:
https://www.cnblogs.com/hayasi/category/869760.html
https://cwiki.apache.org/confluence/display/WW/Security+Bulletins
Struts2系列漏洞起始篇的更多相关文章
- 【中间件】Struts2系列漏洞POC小结
#Struts2-045 ''' CVE-2017-5638 影响范围:Struts 2.3.5 – Struts 2.3.31,Struts 2.5 – Struts 2.5.10 触发条件:基于J ...
- 程序世界系列之-struts2安全漏洞引发的安全杂谈(上)
目录: 1.讨论关于struts 安全问题. 2.黑客文化. 3.如何降低安全漏洞的出现. 4.忠告建议. 题记: 这篇文章本来很早应该和大家见面的,中间由于个人原因调整了系列文章发布时间,实属罪过. ...
- margin系列之内秀篇(二)
本系列摘自 飘零雾雨的博客 可挖掘性 之前已经写过一篇关于 margin 应用场景的文章:margin系列之内秀篇,当然,它的应用场景会远大于文中所述,无法一一列举. 所以本篇权当是对此的补遗好了, ...
- 跟Google学习Android开发-起始篇-构建你的第一个应用程序(4)
说明:此系列教程翻译自Google Android开发者官网的Training教程,利用Chome浏览器的自动翻译功能作初译,然后在一些语句不顺或容易造成误解的地方作局部修正.方便英文不好的开发者查看 ...
- 【SSH框架】之Struts2系列(二)
微信公众号:compassblog 欢迎关注.转发,互相学习,共同进步! 有任何问题,请后台留言联 1.Struts2常量配置 (1).Struts2默认常量配置文件路径,如下图: (2).Strut ...
- 【SSH框架】之Struts2系列(一)
微信公众号:compassblog 欢迎关注.转发,互相学习,共同进步! 有任何问题,请后台留言联系 1.Struts2框架概述 (1).什么是Struts2 Struts2是一种基于MVC模式的轻量 ...
- Mysql高手系列 - 第10篇:常用的几十个函数详解,收藏慢慢看
这是Mysql系列第10篇. 环境:mysql5.7.25,cmd命令中进行演示. MySQL 数值型函数 函数名称 作 用 abs 求绝对值 sqrt 求二次方根 mod 求余数 ceil 和 ce ...
- Mysql高手系列 - 第24篇:如何正确的使用索引?【高手进阶】
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第24篇. 学习索引,主要是 ...
- javascript面向对象系列第三篇——实现继承的3种形式
× 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...
随机推荐
- Greenwich.SR2版本的Spring Cloud Ribbon实例
上次我们了解了eureka(参见Greenwich.SR2版本的Spring Cloud Eureka实例),里面的服务消费方(服务实例a-beautiful-client)我们其实已经用到了ribb ...
- Jmeter响应断言--正则表达式判断纯数字
如图所示,这样是匹配14位数字,如果响应是纯数字可以直接用上
- Linux hostname介绍
以下操作均时基于 Centos 6.8 操作. 一.现象 在平时工作中,当需要修改主机名时,我们一般会这样操作: 第一步,通过 hostname 命令临时修改主机名. hostname kwang-t ...
- java构造方法前加void有什么作用
构造方法前面是没有任何返回符,不能加任何返回类型,包括void.一个构造方法一旦加了void,那么这个就不是构造方法了,变成了一个普通的方法.至于你程序出现的情况,是这样的.任何一个Java类,如果你 ...
- 《Django企业开发实战 高效Python Web框架指南》胡阳
链接:https://pan.baidu.com/s/1NmN_IT5RvevCMt9bZCW1-g提取码:2ki9
- .Net Core 常用开发工具
组件名 描述 可选版本 推荐版本 Visual Studio Community 社区免费版 For Visual Studio 2017 For Visual Studio 2019 Visual ...
- win10 安装MySQL过程和遇到的坑
环境:win10系统,MySQL5.7.18 “mysql-5.7.18-winx64.msi” 首先是要运行mysql-5.7.18-winx64.msi,选择安装在C盘(可自定义安装) 第一步 打 ...
- 网络损伤仪细分市场:eCPRI网络损伤的技术要求
关于“网络损伤仪”的叫法 网络损伤仪,也称作为广域网仿真仪,广域网损伤仪,WAN Emulation,Network Impairment Emulator. 为什么会带WAN广域网这个限定词? 应该 ...
- 排序算法三:Shell插入排序
排序算法三:Shell插入排序 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 引言 在我的博文<"主宰世界"的10种算法短评> ...
- 最新 字节跳动java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.字节跳动等10家互联网公司的校招Offer,因为某些自身原因最终选择了字节跳动.6.7月主要是做系统复习.项目复盘.Leet ...