代码审计| Spring框架实例篇

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代码:

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

原文发布于微信公众号 - 漏斗社区(newdooneSec)

原文发表时间:2018-08-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Coding迪斯尼

java开发操作系统:同时运行多窗口多任务

1405
来自专栏Porschev[钟慰]的专栏

Nodejs学习笔记(九)--- 与Redis的交互(mranney/node_redis)入门

简介和安装 redis简介: 开源高性能key-value存储;采用内存中(in-memory)数据集的方式,也可以采用磁盘存储方式(前者性能高,但数据可能丢失...

4088
来自专栏SpringBoot 核心技术

SpringCloud组件:Eureka服务注册中心内置的REST节点列表

你有没有考虑过Eureka Client与Eureka Server是通过什么方式进行通讯的? 为什么Client启动成功后Server就会被注册到Serve...

7962
来自专栏liulun

kotlin web开发教程【一】从零搭建kotlin与spring boot开发环境

IDEA中文输入法的智能提示框不会跟随光标的问题 我用的开发工具是IDEA image.png 这个版本的IDEA有一个问题; 就是中文输入法的智能提示框不...

3796
来自专栏乐沙弥的世界

Linux 下安装及配置heartbeat

a、配置主机host解析 b、配置等效验证 c、高可用的相关服务配置(如httpd,myqld等),关闭自启动 d、如需要用到共享存储,还应配置相关...

3994
来自专栏颇忒脱的技术博客

远程Debug Java进程的方法

远程debug的意思是启动一个Java进程,启动一个debugger进程,将两者连接起来,利用debugger来debug Java进程。

1932
来自专栏老码农专栏

ActFramework r1.3.0 - 激动人心的特性一览

1322
来自专栏JetpropelledSnake

ELK学习笔记之Logstash和Filebeat解析对java异常堆栈下多行日志配置支持

logstash官方最新文档。 假设有几十台服务器,每台服务器要监控系统日志syslog、tomcat日志、nginx日志、mysql日志等等,监控OOM、内存...

4881
来自专栏Jackson0714

PHP内核之旅-1.生命周期

1232
来自专栏Java后端技术栈

Redis简介以及和其他缓存数数据库的区别

Redis 是一个开源的内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。

1312

扫码关注云+社区

领取腾讯云代金券