CVE-2020-28653-如何繞過反序列化漏洞補丁-Zoho ManageEngine OpManager
引言
CVE-2020-28653漏洞官方通報:

這是一個未授權的反序列化漏洞,評分為7.5分,初步感覺可能缺少Gadget,導致無法實現RCE。但分析后發現可以找到RCE Gadget。此外CVE-2020-28653補丁修復存在缺陷,導致很容易被繞過,形成新的RCE漏洞CVE-2021-3287。
反序列化流程
關注`SUMCommunicationServlet`接口:


`doPost`函數:

進入`process`函數:

對傳入的參數進行一系列處理后,進入`processSumPDU`函數:

跟進`SUMPDU.deSerializePDU`函數:

直接進行了反序列化操作。
參數構造
`requestHandler`賦值如下:

回到`doPost`函數,如果要進入`requestHandler.process`的處理流程,必須滿足獲取的`requestHandler`非空。這里我們看下與SUM相關的另一個接口`SUMHandShakeServlet`:

在處理POST請求時,會對相應的session會話的`requestHandler`進行賦值,只需要提交的參數滿足反序列化后為1002即可。那么可以自己編寫代碼完成構造。
發送請求后,會生成一個session:

該session含有`requestHandler`信息,可以在后續請求中帶上該session:

這樣就進入了`requestHandler.process`函數。下面嘗試構造序列化參數,進入`requestHandler.process`函數。

首先需要從數據流中反序列化得到一個整數`length`,然后讀取序列化數據傳入`ProcessSumPDU`函數。這就意味著首先需要在序列化payload前面加入一個整數類型的長度信息.。查看下 `DataInputStream.readInt`:

可以通過`DataOutputStream.writeInt`進行構建:

Gadget構造
按照上面分析過程,很容易構造DNSlog Gadget進行驗證嘗試:

在所有引用的jar包中發現了`commons-beanutils.jar`,但是沒有`commons-beanutils`,在前面的分析文章中提到過`Click1`利用鏈:
【經典回顧系列】 Java反序列化之ForgeRock OpenAM CVE-2021-35464漏洞分析
QCyber,公眾號:且聽安全【經典回顧系列】 Java反序列化之ForgeRock OpenAM CVE-2021-35464漏洞分析
可以參考上文利用`Click1`構造出RCE Gadget ,具體實現這里不再重復贅述。同時由于系統是運行在Tomcat之上的,可以利用Tomcat實現命令回顯:

補丁繞過分析
反序列化過程增加了白名單驗證,`ITOMObjectInputStream#resolveClass`函數如下:

這里修復存在隱患,因為只有`classResolved`為`false`的時候,才會進行白名單檢查,也就是說如果存在一個`ITOMObjectInputStream`對象連續多次`readObject`的話,由于`classResolved`在第一次反序列化時已經賦值為`true`,所以后面的反序列化操作存在繞過可能性,漏洞CVE-2021-3287就是這個原理。
繼續分析`SUMHttpRequestHandler#processSumPDU`函數,CVE-2020-28653通過`deSearialPDU`完成反序列化觸發,繼續往下走發現還存在一個`sockClient.process`函數:

進入`sockClient.process`函數:

正好滿足多次進行反序列化的要求,從而可以繞過CVE-2020-28653漏洞補丁。后面數據包構造具體過程與前面類似,這里就不過多贅述,有興趣的小伙伴可以自行研究。