Java 安全之 CC4 鏈
0x00 前言
繼續來分析一波CC4的鏈,在寫該文前,看到網上大部分的文章都只給了一個調用鏈和POC。其實看CC4調用鏈的時候,能看出來CC4的調用鏈用到的也是前面的一些類去構造,只不過把CC2 和CC3的鏈給拼接了一下。
Java安全之Commons Collections2分析
https://www.cnblogs.com/nice0e3/p/13860621...
Java安全之Commons Collections3分析
https://www.cnblogs.com/nice0e3/p/13854098...
0x01 POC
package com.test;
用網上的POC做了一個小小的改動。前面的一大段代碼,在這里就不分析了,因為在CC2和CC3的鏈中,都是一樣的。
Transformer[] trans = new Transformer[]{
CC4鏈中在這段代碼中就做了一個簡單的修改。
第一步是new了一個ConstantTransformer對象存儲在Transformer[]數組中傳入的參數是TrAXFilter.class。
如果調用到ConstantTransformer實例化對象的transform方法會直接返回一個TrAXFilter對象。
第二步new了一個InstantiateTransformer對象傳入的是Templates.class和構造的惡意templates實例化對象。
第三步是使用了ChainedTransformer的修飾器將Transformer[]數組傳入參數,當調用transform方法將給Transformer[]數組給遍歷調用transform方法。
第四步將ChainedTransformer修飾后的對象再使用TransformingComparator修飾器給修飾一遍,這里再使用TransformingComparator來修飾一下,這樣等調用到該實例化對象的compare,方法的時候就會去遍歷調用Transformer[]的transform方法。

Field com = PriorityQueue.class.getDeclaredField("comparator");
這里反射獲取PriorityQueue的成員變量comparator,然后設置PriorityQueue的comparator值為transCom。
其他的都和前面的一模一樣,這里就不做具體分析了,感興趣的可以去看看前面3條鏈的一個調試和分析過程。下面來做CC鏈的調試。
0x03 POC調試
該鏈中利用的也是通過PriorityQueue的readObject作為入口點。在該readObject復寫點打個斷點進行跟蹤。

在readObject會調用到heapify方法。跟進一下heapify方法。

heapify方法會再去調用siftDown方法。

在這里如果comparator不為空,還會繼續調用siftDownUsingComparator方法,comparator在這里是被修飾的Transformer[]數組。前面使用反射去進行設置的。繼續跟進siftDownUsingComparator方法。

到了這一步后,就會調用comparator的compare方法,在前面使用到了TransformingComparator來修飾,所有調用到TransformingComparator的compare方法。

在被TransformingComparator修飾前,還使用了ChainedTransformer修飾器進行修飾,在this.transformer為ChainedTransformer的實例化對象。所以這里調用的是ChainedTransformer的transform。前面也提過該方法會遍歷調用Transformer[]數組的transform方法。

在第一次遍歷調用transform方法時i,因為前面Transformer[]存儲的第一個是ConstantTransformer。ConstantTransformer的transform會直接返回TrAXFilter對象。
第二次調用的時候則是傳入TrAXFilter調用InstantiateTransformer的transform方法。

這里的this.iParamTypes為templates,而this.iArgs為構造的惡意TemplatesImpl實例化對象。
那么這一步就是獲取TrAXFilter為templates的構造方法。然后調用該構造方法實例化對象,并且傳入TemplatesImpl惡意類。跟進到TrAXFilter構造方法里面,查看一下具體實現。
在他的構造方法里面還會對傳入的對象調用newTransformer方法。
此時傳入的是惡意的TemplatesImpl實例化對象。調用的則是TemplatesImpl的newTransformer方法。繼續跟進。

在該方法還會調用到getTransletInstance方法。繼續跟進。

到了這里會判斷_class為空的話就會去調用defineTransletClasses進行賦值。跟蹤一下defineTransletClasses方法查看是如何賦值的。

_bytecodes對_class進行賦值。_bytecodes為Runtime類執行命令代碼的字節碼。在執行完方法后,來到下一步。

對_class進行newInstance,進行實例化對象。執行完這一步后,就會彈出計算器,也就是說執行了我們前面構造好的命令執行代碼。

調用鏈
getTransletInstancePriorityQueue.readObject->PriorityQueue.heapify
0x04 結尾
在CC1和CC3里面只能在低版本執行,而CC2和CC4可以在1.8的版本下執行,調試CC1,3用的是JDK7u21版本,而2和4使用的是jdk8U181版本,親測可用。
CC4的鏈在一開始并不想去做一個分析,因為和前面分析的鏈基本一樣。但是還是需要把它給記錄下來,也可以去加深一下影響。
原創: Keefe SecIN技術平臺
原文鏈接:https://mp.weixin.qq.com/s/pWjK-nndbIAoDBy...