IBM WebSphere Portal 多個未授權SSRF&RCE漏洞深入分析
漏洞信息
IBM WebSphere Portal是一種用于構建和管理 Web 門戶的企業軟件,提供對Web內容和應用程序的訪問,同時為用戶提供個性化體驗。IBM WebSphere Portal是WebSphere應用程序軟件的一個組件。
近日網上爆出IBM WebSphere Portal 9及可能更新的版本存在多個SSRF和RCE漏洞。未授權用戶可利用SSRF訪問內網URL資源,認證后用戶可以實現RCE。
調試環境
搭建IBM WebSphere Portal分析環境確實太費勁了。。。直接docker拉取環境并啟動服務:

進入容器,找到啟動腳本位于`/opt/IBM/WebSphere/AppServer/bin/startServer.sh`,取消`WAS_DEBUG`注釋:

重啟啟動容器成功打開遠程調試端口:

但是發現當端口`30015`端口啟動后,遠程調試端口`7777`將會關閉,經過分析發現`IBM Websphere Portal`的啟動模式比較獨特,`startServer.sh`啟動的Java進程并不是最終的進程,它會首先啟動一個Script,啟動完畢后退出導致`7777`端口關閉,為了方便調試,這里想了個“笨辦法“,先拷貝`java`運行進程命令,然后手動`kill`該進程,加入調試信息后,再手動啟動新的Java進程,最終成功解決了遠程調試問題:


未授權SSRF漏洞
存在多次SSRF漏洞,這里以其中的一個觸發點為例。定位`WebSphere/wp_profile/installedApps/dockerCell/Quickr_Document_Picker.ear/qkr.docpicker.widgets.war`,這里定義的URL規則如下:

找到一個`Servlet`:


在`com.ibm.lotus.quickr.ecm.servlet.AjaxProxy#doGet`打下斷點,構造請求訪問,成功觸發斷點:

進入`getUrl`函數:

按照上面函數的處理方式,重新構造請求:
http://***:30015/docpicker/internal_proxy/http/IP/test
最終通過`getConnection`觸發HTTP請求,導致SSRF漏洞:

接口訪問無需認證,但是限制為HTTP GET或者HEAD請求。完整SSRF觸發點梳理如下:
GET full read SSRF: /docpicker/internal_proxy/https/example.com/docpicker/internal_proxy/http/example.com/docpicker/internal_proxy/https/127.0.0.1:9043/ibm/console/docpicker/internal_proxy/http/127.0.0.1:9100/aa Redirect chain - turning "bad" SSRF to "good" SSRF /docpicker/common_proxy/http/www.redbooks.ibm.com/Redbooks.nsf/RedbookAbstracts/sg247798.html?Logout&RedirectTo=http://example.com/wps/proxy/http/www.redbooks.ibm.com/Redbooks.nsf/RedbookAbstracts/sg247798.html?Logout&RedirectTo=http://example.com/wps/myproxy/http/www.redbooks.ibm.com/Redbooks.nsf/RedbookAbstracts/sg247798.html?Logout&RedirectTo=http://example.com/wps/common_proxy/http/www.redbooks.ibm.com/Redbooks.nsf/RedbookAbstracts/sg247798.html?Logout&RedirectTo=http://example.com/wps/cmis_proxy/http/www.redbooks.ibm.com/Redbooks.nsf/RedbookAbstracts/sg247798.html?Logout&RedirectTo=http://example.com/wps/contenthandler/!ut/p/digest!8skKFbWr_TwcZcvoc9Dn3g/?uri=http://www.redbooks.ibm.com/Redbooks.nsf/RedbookAbstracts/sg247798.html?Logout&RedirectTo=http://example.com Arbitrary HTTP method + body: /wps/PA_WCM_Authoring_UI/proxy/http/example.com/wps/PA_WCM_Authoring_UI/proxy/https/example.com
從路徑穿越到RCE
用戶登錄后,在`Script Application`處:

可以上傳自定義樣式的zip壓縮包:


通過功能點很容易找到漏洞,下面從代碼審計角度分析下導致漏洞的原因。經過分析對比,發現上傳處理模塊的代碼位于`/opt/IBM/WebSphere/wp_profile/installedApps/dockerCell/wps.ear`:


`uploadForm_InputPage_NextAction`位于`_ScriptImport`,此時action取值為`uploadFormSubmitForm`,進入`com.bowstreet.webapp.engine#processAction`:

繼續往下走:

上傳的zip文件將緩存在`/opt/IBM/WebSphere/wp_profile/installedApps/dockerCell/wp.scriptportlet.importexport.ear/wp.sp.importexpor.war/WEB-INF/upload/`目錄下,往下將調用`parseZip`來解壓zip壓縮包:

可以構建一個特殊的zip壓縮包,網上一般建議都是使用`Evilarc`這個開源項目來生成惡意壓縮包,因為這里是zip壓縮方式,所以我們可以采用更加簡單的方式,利用二進制編輯器修改zip文件名稱,`../../`替換文件名稱,保證長度一致即可。

將生成的新zip文件上傳,最終通過`extractFile`函數解壓文件:


路徑穿越可以將文件保存到任意位置,但是在解壓前在`unzipFile`函數中會檢查壓縮包里文件的類型:

雖然無法直接上傳一些惡意后門,但是我們仍然可以寫入一些自啟動腳本,實現系統重啟后RCE,具體過程這里不過多贅述,有興趣的小伙伴請自行研究。