freeBuf
主站

分类

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

特色

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

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

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

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

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

Java漏洞分析-Spring Messaging 远程代码执行漏洞(CVE-2018-1270)
Artio 2022-03-08 10:59:26 217692
所属地 北京

一:漏洞简介

Spring框架中通过spring-messaging模块来实现STOMP(Simple Text-Orientated Messaging Protocol),STOMP是一种封装WebSocket的简单消息协议。攻击者可以通过建立WebSocket连接并发送一条消息造成远程代码执行。

二:协议介绍

STOMP(Simple Text-Orientated Messaging Protocol) 面向消息的简单文本协议,用于服务器在客户端之间进行异步消息传递。STOMP帧由命令,一个或多个头信息、一个空行及负载(文本或字节)所组成

客户端可以使用SEND命令来发送消息以及描述消息的内容,用SUBSCRIBE命令来订阅消息以及由谁来接收消息。这样就可以建立一个发布订阅系统,消息可以从客户端发送到服务器进行操作,服务器也可以推送消息到客户端

通讯过程:

客户端与服务器进行HTTP握手连接

客户端通过发送CONNECT帧建立连接

服务器端接收到连接尝试返回CONNECTED帧

客户端通过SUBSCRIBE向服务端订阅消息主题

客户端通过SEND向服务端发送消息

要从浏览器连接,对于SockJS,可以使用sockjs-client。对于STOMP来说,许多应用程序都使用了jmesnil/stomp-websocket库(也称为STOMP.js),它是功能完备的,已经在生产中使用了多年,但不再被维护。目前jsteunou/webstom-client是该库最积极维护和发展的继承者

三:影响版本

Spring Framework 5.0 to 5.0.4

Spring Framework 4.3 to 4.3.14

四:漏洞复现

使用官方demo:https://github.com/spring-guides/gs-messaging-stomp-websocket

Git clone 后切换到指定分支,因为SpringBoot的版本问题需要使用旧版本

Git checkout 6958af0b02bf05282673826b73cd7a85e84c12d3

Checkout后目录如下:

其中complete文件夹下是一个完整的SpringBoot项目,可以使用Maven或Gradle的方式在本地构建该项目,这里使用Gradle的方式

1、将complete文件夹导入到IDEA中,等待依赖都下载完成

2、查看pom文件中spring-boot的版本是否是漏洞版本

3、修改resources/static/app.js文件(注意:这里修改app.js代码不是修改源码,appjs是返回给用户交给浏览器执行的,用户可以随意修改。)

4、然后启动项目,网页访问127.0.0.1:8080,点击connect,然后在send一个消息就可以执行命令



五:漏洞分析

1、根据参考链接中的相关文章我们知道,解析SpEL发生在org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry#filterSubscriptions方法中,查看该方法只有selectorHeaderInUse为True时才能继续往下执行后续逻辑,但该属性默认值为False

2、然后通过搜索发现在org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry#addSubscriptionInternal方法中将selectorHeaderInUse属性值设置成了True,于是在如下位置设置断点,页面点击connect按钮时,会执行到该断点处并且可以看到sessinId、subsId、订阅地址、selector等参数的值,我们传入的执行命令的类就是selector的值,然后这些值都被使用addSubscription方法加入到了this.subscriptionRegistry属性中。

3、我们直接去看命令是怎么执行的,在org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry#filterSubscriptions方法中设置断点,在页面点击send按钮往服务器发送消息之后同时操作直接从上一个断点跳到这个断点,程序会运行到该断点处。

4、然后继续执行,程序会首先获取sessionId的值

5、然后根据sessionId的值最终从this.subscriptionRegistry属性中获取前边用addSubscription方法传进去的信息

6、然后查看获取到的信息发现有我们传入的selector的值(执行命令的类以及命令T(java.lang.Runtime).getRuntime().exec(‘calc.exe’))被创建为expression对象并且可以被执行

7、然后继续往下发现在执行expression对象的getvalue方法时,我们传入的表达式已经被解析

8、需要注意到上图中执行expression.getValue方法时传入的EvaluationContext对象类型为StandardEvaluationContext,该Context类型的对象支持执行任意SpEL表达式。


个人github链接:https://github.com/Artio-Li

六:参考链接

https://blog.csdn.net/qsort_/article/details/105906256

https://4ra1n.love/post/ZWiWbaVfk/

https://paper.seebug.org/562/

https://github.com/spring-guides/gs-messaging-stomp-websocket/wiki

# web安全 # 漏洞分析 # 网络安全技术 # Java代码审计 # JAVA安全
本文为 Artio 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
Artio LV.4
这家伙太懒了,还未填写个人描述!
  • 14 文章数
  • 3 关注者
利用CDN进行攻击以及检测思路
2025-01-06
CSDN挂马事件及其检测思路
2025-01-02
浅谈DNS重绑定攻击
2023-05-19
文章目录