用户
搜索
  • TA的每日心情
    开心
    2018-9-11 11:32
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]经常看看I

    i春秋-核心白帽

    Rank: 4

    73

    主题

    98

    帖子

    1071

    魔法币
    收听
    0
    粉丝
    18
    注册时间
    2016-6-6
    发表于 2018-8-14 17:06:11 513760

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

    0X01 漏洞环境说明

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

    执行.webp.jpg

    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的问题。)

    问题.webp.jpg

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

    3.建立连接:

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

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

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

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

    订阅.webp.jpg

    连接服务器JS代码:

    [PHP] 纯文本查看 复制代码
    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就可以达到表达式注入的目的。

    目的.webp.jpg

    0X03 动态分析

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

    绑定.webp.jpg

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

    tor.webp.jpg

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

    C1.webp.jpg

    C2.webp.jpg

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

    最终.webp.jpg

    0X04 小小总结

    相信通过本期Java代码审计Spring框架实例篇。相信小伙伴们对Spring框架的代码审计有了更深入的了解,当你要审计某个源码时一定要先知道整个代码的逻辑流程,再进行动态调试这样可以事半功倍。

    下期斗哥将带来Java代码审计Spring框架修复篇,对Spring Messaging 远程命令执行漏洞demo进行修改与补丁分析。

    qrcode_for_gh_223e082fe8a7_344.jpg

    学习一下~
    使用道具 举报 回复
    发表于 2018-8-15 14:54:05
    基本是一些废话
    使用道具 举报 回复
    发表于 2018-8-20 14:21:01
    zsd2018 发表于 2018-8-15 14:54
    基本是一些废话

    那请表哥多指教啊
    使用道具 举报 回复
    发表于 2018-8-22 10:39:57
    666666666666666666
    q 36222404 一起嗨啊
    使用道具 举报 回复
    发表于 2018-8-29 13:38:08
    学习了谢谢楼主
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册