Java安全之Cas反序列化漏洞分析

nice_0e3發表於2021-05-27

Java安全之Cas反序列化漏洞分析

0x00 前言

某次專案中遇到Cas,以前沒接觸過,藉此機會學習一波。

0x01 Cas 簡介

CAS 是 Yale 大學發起的一個開源專案,旨在為 Web 應用系統提供一種可靠的單點登入方法,CAS 在 2004 年 12 月正式成為 JA-SIG 的一個專案,開源的企業級單點登入解決方案。

0x02 遠端除錯環境搭建

下載地址,將環境war包下載,部署到tomcat即可

tomcat目錄bin檔案下,startup_debug.bat

call %EXECUTABLE%" start %CMD_LINE_ARGS%

改為

set JPDA_TRANSPORT=dt_socket
set JPDA_ADDRESS=5005
set JPDA_SUSPEND=n
call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%

IDEA中設定Remote遠端除錯5005即可完成。

0x03 漏洞分析

漏洞詳情

4.1.7版本之前存在一處預設金鑰的問題,利用這個預設金鑰我們可以構造惡意資訊觸發目標反序列化漏洞,進而執行任意命令。

  • 影響版本 Apereo CAS <= 4.1.7
    實際上 4.2.X也能打,但是 <= 4.1.7使用的是硬編碼,而後者屬於隨機金鑰
    感覺上和Shiro的 550有點類似

解析流程分析

看web.xml得知,該專案基於Spring MVC開發。

上圖請求路徑是/login的這裡來直接找login的處理方法進行跟蹤。

從web.xml中可見,交給了DispatcherServlet去處理。

這時候可以檢視springmvc的配置檔案cas-servlet.xml

注意loginHandlerAdapter這個配置的bean,其中的屬性有supportedFlowId的值為"login",同時屬性flowExecutor-ref的引用值為loginFlowExecutor

再看loginFlowExecutor這個bean中所配置的登入流程屬性引用值就是我們webflow上下文配置中的loginFlowRegistry這個屬性。

因此我們來看一下loginHandlerAdapter這個bean對應的類為org.jasig.cas.web.flow.SelectiveFlowHandlerAdapter所起的作用,是如何來處理登入動作的。先來看一下這個類的父類org.springframework.webflow.mvc.servlet.FlowHandlerAdapter,這個是Springmvc中的一個類。

FlowHandlerAdapter實現介面HandlerAdapter,而SelectiveFlowHandlerAdapter繼承自FlowHandlerAdapter

SelectiveFlowHandlerAdapter類在cas-server-webapp-actions模組下的org.jasig.cas.web.flow包下。
因此Spring的DispatcherServlet找到要處理的handleAdapterSelectiveFlowHandlerAdapte。並且根據地址http://localhost:8080/cas/login?service=XXX,得到handler的flowId="login",即流程:loginFlowRegistry

然後進入下面的handle方法,開始調取流程:

當有登入請求時,spring則會呼叫該org.jasig.cas.web.flow.SelectiveFlowHandlerAdapter

跟進this.flowUrlHandler.getFlowExecutionKey(request)可見,該方法會獲取請求中的execution引數。

而後會進行呼叫 this.executionRepository.parseFlowExecutionKey(flowExecutionKey);獲取到key。

跟進檢視

可見從execution引數,後分割UUID和_後面部分,而後面部分進行base64解密。對返回id和data進行賦值,然後返回ClientFlowExecutionKey物件

下面呼叫this.executionRepository.getFlowExecution(key);,將剛剛獲取到的ClientFlowExecutionKey物件,即key變數傳遞。跟進。

這地方進行了資料的反序列化操作。先來看到構造方法,使用AES/CBC/PKCS7加密方式,並且金鑰使用預設的金鑰進行加密。

而在解密後還會對資料進行解壓縮GZIPInputStream處理後進行反序列化。

漏洞復現與利用

根據以上資料解析分析,我們只需要將cas中加密部分扣出來,然後進行GZIPOutputStream處理,而後將他進行base64加密,將處理後的gadgets加入到execution引數裡面即可,當然還需要構造一下前面UUID的值。

從github找到現成工具

Reference

https://www.anquanke.com/post/id/198842

0x04 結尾

除此外,還有一些值得探討的地方例如,回顯方式的構造

相關文章