S2-019、S2-020
前言
“Struts2系列起始篇”是我整各系列的核心,希望大家能花些时间先看看。
正文
我发现关于一些早期的Struts2的漏洞,网上的分析文章并不多,不知道是不是我打开浏览器的方式不对,唯一看到的两篇文章也仅有poc,没有细节分析。于是我在官方上看了下漏洞详情,如下:
大概意思是动态方法调用开启了会导致安全问题,给出的信息太少了,于是我又看了下网上的poc(我做了一点修改):
老实说根据这个poc我还是什么都看不出来(并且公告中说和动态方法调用有关,但是这里并没有用到类似xxx.action!method啊),但运行它确实能执行代码,没办法我只好一步步调试了。由于过程有点坎坷,这里就只说下我自己的思路吧,我先是在StrutsPrepareFilter的doFilter方法中下断点(当然也有可能是StrutsPrepareAndExecuteFilter,看大家在web.xml中是怎么配置的了,详细情况参考系列文章的第一篇),然后就是一步步往下走了:
关于这段代码DefaultActionInvocation.invoke(),在第一篇文章中介绍过了,在执行action之前会先循环调用Struts2的默认拦截器栈。说明Ognl表达式是在某个自带的拦截器中执行的,看下此时的变量栈,发现此时的拦截器是DebuggingInterceptor(实际上我测试的时候是根据poc后带的参数猜出来了,哈哈哈嗝~),进入DebuggingInterceptor.intercept方法中:
方法看起来很长,但实际上流程很简单,首先判断“org.apache.struts2.interceptor.debugging.DebuggingInterceptor.devMode”这个常量是否被设置为true了,如果是true说明项目开启了开发者模式(此漏洞的鸡肋之处),DebuggingInterceptor才会工作,进入if语句中,162行处获取请求中的“debug”参数,随后根据“debug”参数的值进入不同的分支中。总共有四个分支,但是很明显后面两个分支中调用了OgnlValueStack.findValue方法,熟悉Struts2的同学都知道该方法中会执行ognl表达式(第二篇文章中在分析S2-016时跟进过这个函数),而findValue方法的参数也是直接使用的请求中的另一个参数。这样构造poc起来也很简单(另外表达式也要url编码下):
?debug=command&expression=exp
?debug=browser&object=exp
到这里就S2-019就分析完了,问题是官网上说和动态方法调用有关,为什么我在struts.xml中配置了<constant
name="struts.enable.DynamicMethodInvocation"
value="false"/>,但是还是可以RCE啊,且分析过程中并没涉及动态方法调用~~~
S2-20
我不准备详细分析这个漏洞了,主要是因为漏洞较难利用起来,不过我觉得思路有独特之处,所以还是要介绍下。漏洞出现的地方是Struts2的另一个默认拦截器ParametersInterceptor,该拦截器其主要功能是把ActionContext中的请求参数设置到ValueStack中,看下他的代码:
跟进setParameters方法中:
先对请求参数名做判断是否合法,合法才会加入到acceptableParameters中,循环acceptableParameters中的实体,调用OgnlValueStack.setValue,我调试的时候最先想到的就是Ognl表达式注入,但是失败了原因一言难尽~
看下acceptableName方法,该方法就是为了防范一些安全问题:
isExcluded用于将参数名和配置文件中的一些特殊参数进行对比,禁止访问一些特殊参数,不过从下图可以看到,配置文件中的正则一直在修改,因为经常被绕过,S2-20之后就禁用了class开头的参数。。。
isAccepted方法也是做正则,防止ognl表达式注入,使用的正则如下图:
禁用了一些特殊字符,我尝试FUZZ了一下,都没成功,不过这里我说下我测试的结果吧。
禁用逗号是防止执行多条语句,例如我们之前使用的poc中
new java.lang.ProcessBuilder(new java.lang.String[]{'cmd.exe', '/c','calc'})).start() 但是我们使用
new java.lang.ProcessBuilder(new java.lang.String[]{'calc'})).start() 还是可以弹出计算机的
至于#,rce的poc中不使用#也是可以的,如下图(以S2-019为例)
冒号不让用我不知道是为什么,还有等号,大家可以看上面我并没有使用等号,而是用的“-”,实际上我fuzz了一下,逗号、点号、减号还有加号在这里有时候也可以,为什么是有时候呢,因为感觉像六脉神功似的,时灵时不灵。但大多数时候都能成功,也有可能是tomcat缓存的原因?大家感兴趣可以自己尝试下,希望不要误导大家,最后我觉得使用“
?a%2d(new+java.lang.ProcessBuilder(new+java.lang.String%5b%5d%7b%27calc%27%7d)).start()=xxx”应该能成功,然而并不行。
算了不浪费大家的时间了,这里直接说别人的利用方法吧。这是百度src的一位师傅写的文章(https://www.freebuf.com/articles/web/31039.html)。写的很清楚,大概意思是可以通过class.xx这种方式遍历属性,通过修改web容器的日志文件的路径和文件名,写入一句话木马。细节上文章中写的很清楚了,我就不赘述了。
修复方法
针对S2-20,Struts2在isExcluded方法中过滤了class关键字。
参考文章:
https://www.freebuf.com/articles/web/31039.html
https://cwiki.apache.org/confluence/display/WW/Security+Bulletins
S2-019、S2-020的更多相关文章
- 电源相关知识—S0、S1(POS)、S2、S3(STR)、 S4、S5、睡眠、休眠、待机
转 http://blog.sina.com.cn/s/blog_52f28dde0100l3ci.html APM https://en.wikipedia.org/wiki/Advanced_Po ...
- 019、使用公共Registry (2019-01-10 周四)
参考https://www.cnblogs.com/CloudMan6/p/6896488.html 在DockerHub上注册一个账号,这样就可以将自己构建的镜像上传到DockerHub上供别人 ...
- 019、Java中定义字符
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 019、MySQL取本季度开始时间和本季度结束时间
SELECT QUARTER ( adddate( dy, ) ) QTR, date_add( dy, INTERVAL MONTH ) Q_start, adddate( dy, ) Q_end ...
- Java数据结构和算法(六)——前缀、中缀、后缀表达式
前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...
- Java数据结构和算法(六):前缀、中缀、后缀表达式
前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...
- C语言--关键字 typedef
一.typedef 1.基本使用 1> typedef 在基本数据类型中的使用 typedef int MyInt; // 相当于给 int 起了一个别名 typedef MyInt MyInt ...
- CCIE路由实验(8) -- QoS
1.查看端口缺省的队列机制2.配置CB-WFQ3.配置CB-LLQ4.配置CB-Shapping在以太接口下5.配置CB-Shapping在FR接口下6.配置帧中继流量整形FRTS7.配置CB-Pol ...
- Pyhton编程(四)之基本数据类型-字符串详解
一:字符串是什么? 字符串是Python最常用的一种数据类型,虽然看似简单,但能够以不同的方式来使用它们. 字符串就是一系列的字符,在Python中,用引号括起来的都是字符串,其中的引号可以是单引号, ...
- 一个对象toString()方法如果没有被重写,那么默认调用它的父类Object的toString()方法,而Object的toString()方法是打印该对象的hashCode,一般hashCode就是此对象的内存地址
昨天因为要从JFrame控件获取密码,注意到一个问题,那就是用toString方法得到的不一定是你想要的,如下: jPasswordField是JFrame中的密码输入框,如果用下面的方法是得不到密码 ...
随机推荐
- osg 3ds模型加载与操作
QString item1 = QString::fromStdString(groupParam->getChild(k)->getName()); QStandardItem* ite ...
- 25.Flutter中的表单 Radio RadioListTile Switch SwitchListTile 以及表单组件实现一个简单的学员登记系统(下)
四.Radio.RadioListTile单选按钮组件 Radio常用属性: value单选的值. onChanged改变时触发. activeColor:选中的颜色.背景颜色 groupValue: ...
- orcale11g安装
一.centos7.5安装orcale 安装环境 内存最小1G,推荐2G或者更高 内存为1-2g,swap是内存的1.5倍左右 内存大于2G, swap和内存相等 硬盘最小为30G oracle版本 ...
- Windows 10在2018四月更新中默认安装了OpenSSH客户端
客户端安装路径 C:\Windows\System32\OpenSSH 版本:
- jQuery和ajax【“Asynchronous Javascript And XML】
环境搭建 搭建一个jQuery的开发环境非常方便,可以通过下列几个步骤进行. 下载jQuery文件库 在jQuery的官方网站(http://jquery.com)中,下载最新版本的jQuery文件库 ...
- 用Python做一个简单的小游戏
学习总是枯燥的,对于Python小白的我来讲,更是乏味的.为了提高学习的兴趣,今天我就来写一个小程序练练手. 数字猜谜游戏相信大家都不陌生,A给出最小值最大值,B写一个该范围内的数,A猜测写下的是多少 ...
- rebbitMQ的实现原理
引言 你是否遇到过两个(多个)系统间需要通过定时任务来同步某些数据?你是否在为异构系统的不同进程间相互调用.通讯的问题而苦恼.挣扎?如果是,那么恭喜你,消息服务让你可以很轻松地解决这些问题.消息服务擅 ...
- luogu1972:HH的项链
题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链变得越来越长. ...
- 日常工作问题解决:centos7下配置网卡以及查询网卡UUID
目录 1.配置网卡 1.1 网卡查看命令:ifconfig -a 1.2 网卡配置文件说明 1.3 重启网络服务 2.查看确认网卡UUID 2.1 网卡配置文件正常时 2.2 网卡配置文件不可用或者配 ...
- Feign【开启GIZP压缩】
SpringCloudFeign支持对请求和响应进行gzip压缩,以此来提高通信效率. 1.搭建gzip-demo工程 1.1.工程依赖: <parent> <groupId> ...