天天看點

Java反序列化(四)Common Collection 2分析

jdk 1.7,jdk1.8也測試成功。

Commons Collections 4.0

idea

idea建立maven項目,在pom.xml添加即可

後半段鍊和cc1差不多,正向分析,從readObject方法開始分析。

找到關鍵類​<code>​java.util.PriorityQueue​</code>​的readObject方法。

Java反序列化(四)Common Collection 2分析

可以看到方法比較簡單。可以看到queue[i]的值是由s.readObject方法得到的。為什麼會這樣,這是因為序列化的時候依次對queue[i]中的值進行序列化了,如下圖。是以當反序列化的時候,也依次進行了反序列化。

Java反序列化(四)Common Collection 2分析

既然這樣的話,隻要我們通過反射執行個體化PriorityQueue類的對象,并且給queue指派即可,,實作了queue[i]控制。

接下來進入​<code>​heapify​</code>​方法

Java反序列化(四)Common Collection 2分析

跟進​<code>​siftDown​</code>​方法,注意這裡在第二個參數傳入了queue[i],并且還要注意,這裡進入for循環需要一個條件,就是size&gt;1,因為​<code>​size &gt;&gt;&gt; 1​</code>​進行了右移位操作,是以隻有當size&gt;1的時候才會進入循環,這是第一個條件。

Java反序列化(四)Common Collection 2分析

這裡的x即為queue[i],跟進​<code>​siftDownUsingComparator​</code>​方法。

Java反序列化(四)Common Collection 2分析

重點在​<code>​comparator.compare(x, (E) c)​</code>​,comparator其實是一個Comparator接口,而​<code>​org.apache.commons.collections4.comparators.TransformingComparator​</code>​實作了​<code>​Comparator​</code>​接口,重寫了​<code>​compare​</code>​方法,

Java反序列化(四)Common Collection 2分析

可以看到compare方法中執行了​<code>​this.transformer.transform​</code>​。後面就是CC1鍊了。

分析幾個關鍵地方

1.這裡為了add了兩個值主要是為了上面說到的第一個條件,size&gt;1

2.必須在add後,再反射設定​<code>​comparator​</code>​值。

這是由于在add方法中調用了offer方法。

Java反序列化(四)Common Collection 2分析

offer方法中調用了siftUp方法

Java反序列化(四)Common Collection 2分析

在siftUp方法中,需要讓​<code>​comparator​</code>​為null,才會走else,走else才可以添加到queue中,否則會報錯。

Java反序列化(四)Common Collection 2分析

在yso中用的CC2涉及到了另一個點:​<code>​TemplatesImpl​</code>​。jdk1.7和1.8都測試成功。

需要先去大概了解一下上面是​<code>​javassit​</code>​。

想了半天,最終還是從readObject來學習​<code>​TemplatesImpl​</code>​這條鍊。然後配合Poc中的代碼結合來了解。

先放出完整的exp,雖然不是yso的實際代碼,但原理是一樣的。

我們最終序列化的是PriorityQueue的對象。是以從PriorityQueue的readObject方法來說起。

找到該方法。

Java反序列化(四)Common Collection 2分析

注意圖中的​<code>​queue​</code>​變量,這個變量我們已經在exp中修改過值了。對應的exp如下。

由此可知,queue裡有兩個值,第一個值是​<code>​templates​</code>​,第二個值是​<code>​1​</code>​。

并且​<code>​size​</code>​變量也已經在exp中修改了,對應exp代碼如下,将size修改為2。至于為什麼我覺得應該不用說了,上面已經解釋過了。

跟進​<code>​heapify​</code>​方法,

Java反序列化(四)Common Collection 2分析

跟進​<code>​siftDown​</code>​方法,傳入了queue[i],

Java反序列化(四)Common Collection 2分析

在這裡遇到了​<code>​comparator​</code>​變量,對應的exp代碼如下。

而comparator如下對應exp代碼如下

繼續跟進​<code>​siftDownUsingComparator​</code>​方法。

Java反序列化(四)Common Collection 2分析

關鍵代碼​<code>​comparator.compare​</code>​,通過前面的分析可知,這裡的​<code>​comparator​</code>​是TransformingComparator執行個體化的對象,而變量x是queue[0],因為在​<code>​heapify​</code>​函數中是依次循環的,而queue[0]是exp中的​<code>​templates​</code>​,仔細對照上面的分析及exp代碼。

接下來則調用的是​<code>​TransformingComparator​</code>​的​<code>​compare​</code>​方法

跟蹤該方法。

Java反序列化(四)Common Collection 2分析

注意看這裡的​<code>​this.transformer​</code>​對應的exp代碼是,即​<code>​this.transformer​</code>​就是exp代碼中的​<code>​transformer​</code>​。(注意執行個體化的時候傳了一個參數為"newTransformer"。)

即調用了​<code>​InvokerTransformer​</code>​的​<code>​transform​</code>​方法,而​<code>​obj1​</code>​就是上面的​<code>​x​</code>​,即​<code>​templates​</code>​,

跟蹤這個​<code>​transform​</code>​方法,

Java反序列化(四)Common Collection 2分析

這裡分析一下:

input變量就是上面的obj1,即傳過來的​<code>​templates​</code>​,而this.iMethodName的值為​<code>​newTransformer​</code>​。因為​<code>​templates​</code>​是​<code>​TemplatesImpl​</code>​類的對象,是以調用的是​<code>​TemplatesImpl.newTransformer​</code>​。

跟蹤​<code>​TemplatesImpl.newTransformer​</code>​方法。

Java反序列化(四)Common Collection 2分析

跟蹤​<code>​getTransletInstance​</code>​方法

Java反序列化(四)Common Collection 2分析

圖中,我們看到三處地方,第一處對應的exp代碼如下,想必大家都知道為什麼。隻要不為null就好。

第二處,必須是null,因為我們想要進入​<code>​defineTransletClasses​</code>​方法。

第三處​<code>​_class[_transletIndex].newInstance();​</code>​會執行我們構造的static代碼塊,後面會說到。

跟進​<code>​defineTransletClasses​</code>​方法

Java反序列化(四)Common Collection 2分析

可以看到​<code>​_bytecodes​</code>​變量,這個變量對應exp代碼如下,

這麼多代碼就是通過javassti建立一個類,并且添加了一個static代碼塊,内容為​<code>​java.lang.Runtime.getRuntime().exec("calc.exe");​</code>​。如下圖,這就是我們通過javassti生成的class檔案。隻不過在代碼中,将該class轉為了位元組數組,即​<code>​_bytecodes​</code>​變量。

Java反序列化(四)Common Collection 2分析

繼續看​<code>​defineTransletClasses​</code>​方法

Java反序列化(四)Common Collection 2分析

可以看到,上面已經将​<code>​_bytecodes​</code>​數組變成一個類了,後面判斷該類的父類是否是​<code>​ABSTRACT_TRANSLET​</code>​,看下圖,值為​<code>​com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet​</code>​。

Java反序列化(四)Common Collection 2分析

是以我們要在exp代碼中

因為我們要進入if判斷,才能執行​<code>​_transletIndex = i;​</code>​,指派給​<code>​_transletIndex​</code>​後,​<code>​_class[_transletIndex].newInstance();​</code>​才會執行我們惡意的static代碼塊。

至此也應該算是分析結束了。