首發安全客:Java安全之Weblogic 2016-3510 分析html
續前面兩篇文章的T3漏洞分析文章,繼續來分析CVE-2016-3510漏洞,該漏洞同樣是基於,前面的補丁進行一個繞過。java
Java安全之Weblogic 2016-0638分析docker
這裏還須要拿出上次的weblogic_cmd的工具來看一下CVE-2016-3510的命令執行payload怎麼去進行構造。數組
來到源碼中的Main這個入口點這裏,前面的TYPE須要修改成marshall
,由於此次是須要使用到MarshalledObject
來進行封裝對象。安全
填入參數,打個斷點測試一下。工具
前面的都分析過了,在此略過,主要是這張圖片裏面的地方傳入命令,而且生成payload,跟蹤進行查看。post
這裏的blindExecutePayloadTransformerChain
方法是返回構造利用鏈的Transformer[]
數組內容,這裏主要來跟蹤serialData
方法。測試
該方法中是將剛剛構造好的Transformer[]
數組傳入進來,聯合下面的代碼構形成了一個惡意的對象,而後調用BypassPayloadSelector.selectBypass
方法處理這個惡意的對象。跟蹤查看該方法的實現。this
這個位置調用了marshalledObject
方法處理payload,跟蹤查看。
marshalledObject
內部使用了MarshalledObject
的構造方法,將payload做爲參數傳遞進去。而後獲得該值。這裏payload就構造好了。
跟蹤進MarshalledObject
裏面進行查看。
這個地方又new了一個MarshalledObject.MarshalledObjectOutputStream
對象,跟蹤查看。
MarshalledObject.MarshalledObjectOutputStream
繼承了ObjectOutputStream
對象,而且調用的是父類的構造器。這就和直接new一個ObjectOutputStream
沒啥區別。
var1是咱們傳遞進來的payload,在這裏使用的是CC1的利用鏈,var1也就是一個惡意的AnnotationInvocationHandler
對象。var2是ByteArrayOutputStream
對象,var3至關因而一個ObjectOutputStream
對象。在這裏會將var1 的內容進行序列化後寫入到var2裏面。
而序列化後的對象數據會被賦值給MarshalledObject
的this.objBytes
裏面。
執行完成,退回到這一步事後,則是對構造好的MarshalledObject
對象調用Serializables.serialize
方法進行序列化操做。
在前面並無找到CVE-2016-0638漏洞的補丁包,那麼在這裏也能夠直接來看到他的利用方式。
前面CVE-2016-0638這個漏洞是基於前面的補丁將payload序列化事後封裝在weblogic.jms.common.StreamMessageImpl
類裏面,而後進行反序列化操做,StreamMessageImpl
類會調用反序列化後的對象的readobject方法達成命令執行的操做。而補丁包應該也是在ClassFileter類裏面將上次咱們利用的weblogic.jms.common.StreamMessageImpl
類給進行拉入黑名單中。
那麼在該漏洞的挖掘中又找到了一個新的類來對payload進行封裝,而後繞過黑名單的檢測。
而此次使用得是weblogic.corba.utils.MarshalledObject
類來進行封裝payload,將payload序列化事後,封裝到weblogic.corba.utils.MarshalledObject
裏面,而後再對MarshalledObject
進行序列化MarshalledObject
,MarshalledObject
不在WebLogic黑名列表裏面,能夠正常反序列化,在反序列化時MarshalledObject
對象調用readObject
時,對MarshalledObject
封裝的序列化對象再次反序列化,這時候繞過黑名單的限制,對payload進行反序列化操做觸發命令執行。
下面來直接看到weblogic.corba.utils.MarshalledObject#readResolve
方法的位置
這地方就有意思了,前面在分析工具的時,咱們得知構造的繞過方式是將payload序列化放在這個this.objBytes
中,而在此若是調用MarshalledObject.readResolve
方法就能夠對被封裝的payload進行反序列化操做。達到執行命令的效果。
在這裏還須要思考到一個問題readResolve
這個方法會在何時被調用呢?
在Weblogic從流量中的序列化類字節段經過readClassDesc-readNonProxyDesc-resolveClass獲取到普通類序列化數據的類對象後,程序依次嘗試調用類對象中的readObject、readResolve、readExternal等方法。而上一個CVE-2016-0638的漏洞就是藉助的readExternal
會被程序所調用的特色來進行繞過。咱們此次使用的是readResolve
這個方法,這個方法也是同理。
後面也還須要知道一個點,就是反序列化操做事後,readResolve
具體是如何觸發的?下來來斷點查看就清楚了。
先在InboundMsgAbbrev.ServerChannelInputStream#resolveClass
方法先打一個斷點,payload發送完成後,在該位置停下。
在這這裏能夠看到傳遞過來的是一個MarshalledObject
對象,不在黑名單中。
那麼下面在readResolve
上下個斷點看一下調用棧。
在這裏面會被反射進行調用,再前面的一些方法因爲不是源代碼進行調式的跟蹤不了。
回到weblogic.corba.utils.MarshalledObject#readResolve
方法中查看
和前面說的同樣,這裏new了一個ByteArrayInputStream
對象,對this.objBytes
進行讀取,前面說過咱們的payload封裝在this.objBytes
變量裏面,而這時候new了一個ObjectInputStream
而且調用了readObject
方法進行反序列化操做。那麼這時候咱們的payload就會被進行反序列化操做,觸發CC鏈的命令執行。
先來查看docker容器裏面的內容
而後執行來到下一行代碼中。
readobject執行事後,再來查看一下docker裏面的文件有沒有被建立。
文件建立成功,說明命令可以執行。
本文內容略少,緣由是由於不少內容都是前面重複的,並不須要拿出來從新再敘述一遍。這樣的話並無太大的意義,若是沒有分析過前面的兩個漏洞,建議先從前面的CVE-2015-4852和CVE-2016-0638這兩個漏洞調試分析起,調試分析完前面的後面的這些繞過方式理解起來會比較簡單。