前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >代码审计| Spring框架实例篇

代码审计| Spring框架实例篇

作者头像
漏斗社区
发布2018-08-20 14:28:45
1.1K0
发布2018-08-20 14:28:45
举报
文章被收录于专栏:漏斗社区漏斗社区

Java代码审计Spring框架思路篇中,斗哥为大家讲述了如何得到Spring审计的Demo,审计源码,根据IDEA与Spring框架审计思路初步判定是否存在漏洞。

Java代码审计Spring框架知识篇中,斗哥讲述Spring框架漏洞分析和利用的必备知识,如java命令执行函数、SpEL表达式使用,两者的配合使用构造Spring框架漏洞的命令执行POC。

本期Java代码审计Spring框架实例篇将结合前两篇的知识,以Spring Messaging 远程命令执行漏洞为例,根据审计思路来分析,深入学习Spring框架的代码审计。

0X01 漏洞环境说明

Spring曝出的漏洞并不多但危害都很大,比如Spring Messaging 远程命令执行漏洞。

1.Spring框架中通过spring-messaging模块来实现STOMP。 2.客户端定义headers并且其中包含selector,传入SpEL(可带有恶意代码),向服务器端发送消息。 3.服务端和客户端建立起连接后,服务端接收到SUBSCRIBE订阅消息后获取headers并且在当前会话中查找headers中的selector值最终执行。

0X02 漏洞流程复现

1、STOMP说明:

STOMP(Simple Text-Orientated Messaging Protocol) 面向消息的简单文本协议,用于服务器在客户端之间进行异步消息传递,它定义了服务端与客户端之间的格式化文本传输方式。 STOMP是基于帧的协议:由命令和一个或多个头信息、一个空行及负载(文本或字节)所组成。 其中可用的命令包括: CONNECT、SEND、SUBSCRIBE、UNSUBSCRIBE、BEGIN、COMMIT、ABORT、ACK、NACK、DISCONNECT 客户端可以使用SEND命令来发送消息以及编辑消息的内容,用SUBSCRIBE命令来订阅消息以及确定接收对象。

2、WebSocket说明:

WebSocket 协议提供了 通过一个套接字实现全双工通信的功能。也能够实现 web 浏览器 和 server 间的 异步通信。(支持SockJS,用来解决浏览器端、服务器以及代理不支持WebSocket的问题。)

WebSocket是底层协议,而 STOMP 是基于 WebSocket(SockJS)的上层协议 就像HTTP在TCP套接字之上添加了请求-响应模型层一样,STOMP在WebSocket之上提供了一个基于帧的线路格式(frame-based wire format)层,用来定义消息的语义。

3、建立连接:

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

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

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

4.客户端通过SUBSCRIBE向服务端订阅消息。

连接服务器JS代码:

代码语言:javascript
复制
function run() {
  selector = document.getElementById('expression').value
  stompClient = Stomp.client('ws://' + window.location.hostname + ':' + window.location.port + '/hello');
  //向服务器发起连接
  stompClient.connect({}, function(frame) {
    //连接成功时,服务器响应CONNECT帧的回调方法
    stompClient.subscribe('/topic/greetings', function() {}, {
      "selector": selector
    })
  });
}

headers如果客户端进行定义,也就是说只要我们在headers当中的selector传入SpEL命令执行的poc就可以达到表达式注入的目的。

0X03 动态分析

分析流程: 1.已爆出漏洞方法或自认为可疑处打上断点 2.debug运行 3.在客户端发送初步POC 4.动态调试 5.在客户端发送POC,调试修改直到成功执行 (1)动态调试发现服务器根据订阅ID来确定会话,从客户端获取headers和selector进行绑定。

(2)然后从会话headers中获取selector值当作expression最后执行(上文提到headers可以在客户端定义,所以我们在headers当中的selector传入poc就可以达到表达式注入的目的。而selector则是用SpEL表达式编写)。 DefaultSubscriptionRegistry类的addSubscriptionInternal方法中,有expression = this.expressionParser.parse Expression(selector)

如果要命令执行,则还需要expression.getValue或epression.setValue。 (3)查看调用栈,客户端在发送send message时会调用getValue。 服务器调用filterSubscription对消息进行过滤,最终到通过expression.getValue()执行了POC。

Boolean.TRUE.equals(expression.getValue(context, Boolean.class))最终到通过expression.getValue()执行了POC。

0X04 小小总结

相信通过本期Java代码审计Spring框架实例篇。相信小伙伴们对Spring框架的代码审计有了更深入的了解,当你要审计某个源码时一定要先知道整个代码的逻辑流程,再进行动态调试这样可以事半功倍。 下期斗哥将带来Java代码审计Spring框架修复篇,对Spring Messaging 远程命令执行漏洞demo进行修改与补丁分析。

PS:回答文章下方的选择题,回答正确者即有机会获得斗哥独家赠送的文章源码与材料哦!(答案请在文章下方留言)

STOMP协议中什么命令是用来订阅消息与服务器进行交互?

A. SEND

B. SUBSCRIBE

C. BEGIN

D. COMMIT

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 漏斗社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
代码审计
代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档