作者:且聽安全
原文鏈接:https://mp.weixin.qq.com/s/nCMtSD7QH8ai6fpurJBXTg
漏洞信息
最近 Confluence 官方通報了一個嚴重漏洞 CVE-2022-26134 :

從漏洞描述來看,這仍然是一個 OGNL 表達式注入漏洞。影響版本如下:
- from 1.3.0 before 7.4.17
- from 7.13.0 before 7.13.7
- from 7.14.0 before 7.14.3
- from 7.15.0 before 7.15.2
- from 7.16.0 before 7.16.4
- from 7.17.0 before 7.17.4,
- from 7.18.0 before 7.18.1
補丁描述:

主要是修改了 xwork-1.0.3-atlassian-10.jar 。下面將深入分析漏洞原理,并嘗試繞過沙箱構造命令執行結果回顯。
漏洞分析
新版本主要是修改了 xwork-1.0.3-atlassian-10.jar 。首先簡單進行一下補丁對比:

改動的地方很多,但是最關鍵的地方位于 ActionChainResult#execute 函數,對提取 finalNamespace 和 finalActionName 的過程進行了更新。
Confluence 基于 Struts 架構進行開發。我們首先以登錄請求為例,對 Confluence 請求處理的流程進行動態調試。訪問 /login.action ,經過一系列 Filter 處理后,將進入Servlet 的分發器 ServletDispatcher (本質上是其子類 ConfluenceServletDispatcher 對象):



分別通過函數 getNameSpace 、 getActionName 、 getRequestMap 、 getSessionMap 、 getApplicationMap 提取相應參數,對應關系如下:
getNameSpace(request)->namespacegetActionName(request)->actionNamegetRequestMap(request)->requestMapgetParameterMap(request)->parameterMapgetSessionMap(request)->sessionMapgetApplicationMap()->applicationMap
然后調用 serviceAction 函數,進入子類 ConfluenceServletDispatcher 的 serviceAction 函數:

實例化 DefaultActionProxy 對象,調用其 execute 函數:

進入 DefaultActionInvocation#invoke :

這里開始調用 Struts Interceptor 攔截器對象對請求進行處理, DefaultActionInvocation 對象攔截器集合 interceptors 一共有 32 個:

函數 invoke 嘗試通過 next 獲取下一個攔截器對象,然后調用其 intercept 方法,大部分 Interceptor 對象的 intercept 函數格式如下所示:

繼續調用 DefaultActionInvocation#invoke ,從而形成迭代循環。但是在調試中我們發現也有特殊的一些 Interceptor ,比如 ConfluenceAccessInterceptor :

當滿足一定條件時并不會繼續調用 DefaultActionInvocation#invoke ,而是返回字符串 notpermitted ,我們分析一下 isAccessPermitted 函數:

主要是通過請求的 *.action 和 methdName ,來判斷當前用戶 currentUser 是否有訪問權限。也就是說,當訪問一個無權訪問的 *.action 時,DefaultActionInvocation#invoke 在迭代調用到 ConfluenceAccessInterceptor#intercept 后,將返回 notpermitted 并賦值給 resultCode,從而跳出迭代。我們替換測試請求為 /index.action:

當處理到 ConfluenceAccessInterceptor 攔截器時,將不會繼續迭代調用下一個攔截器,而是繼續往下走,進入 executeResult 函數:

進入 ActionChainResult#execute :

提取 namespace 參數,并調用 translateVariables 函數,進入:

典型的 OGNL 表達式解析過程,前面分析中可知, namespace 參數通過 ServletDispatcher#getNameSpace 函數獲取,查看定義:

可見 namespace 取值為請求 servletPath 最后一個 / 之前的部分。
根據上面正則表達式規則,要想觸發 OGNL 解析,我們很容易構造出相應的 URL :

成功觸發 OGNL 表達式注入。
沙箱繞過與命令執行
網上現在已經公開的一些利用方式簡單粗暴,只能針對 v7.14 及以下系列有效,因為從 v7.15 系列開始,Confluence 在 OGNL 表達式解析時加入了沙箱設置:

進入 isSafeExpression 函數:

主要的黑名單如下:
(1) unsafePropertyNames

(2) unsafePackageNames

(3) unsafeMethodNames
0 = "getClass"
1 = "getClassLoader"
白名單 allowedClassNames 如下:

此外,對成員函數等也進行了檢查( containsUnsafeExpression 函數 ):

小伙伴看到這里,應該很容易想到多種繞過的方法,感興趣的小伙伴可以進入漏洞空間站進行交流。其中一種實現命令執行結果回顯的方式如下(適用全部受影響的版本):

本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1912/
暫無評論