這篇文章主要介紹了Java JDBC導(dǎo)致的反序列化攻擊原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
創(chuàng)新互聯(lián)主營(yíng)北辰網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都APP應(yīng)用開(kāi)發(fā),北辰h5重慶小程序開(kāi)發(fā)搭建,北辰網(wǎng)站營(yíng)銷(xiāo)推廣歡迎北辰等地區(qū)企業(yè)咨詢(xún)
背景
上周BlackHat Europe 2019的議題《New Exploit Technique In Java Deserialization Attack》中提到了一個(gè)通過(guò)注入JDBC URL實(shí)現(xiàn)反序列化攻擊的場(chǎng)景,簡(jiǎn)單分析一下。
分析
首先,當(dāng)java應(yīng)用使用MySQL Connector/J(官方的JDBC驅(qū)動(dòng),本文基于其8.0+版本)連接mysql時(shí),JDBC URL的格式如下:protocol//[hosts]/[database]?properties,具體可看mysql官方文檔,示例:jdbc:mysql://localhost:3306/test?useSSL=true
其中,protocol、host、database都比較好理解,URL中的properties可以設(shè)定MySQL Connector/J連接mysql服務(wù)器的具體方式,關(guān)于properties的官方文檔地址,其中和本文相關(guān)的連接屬性有兩個(gè),分別是autoDeserialize和queryInterceptors,前者是設(shè)定MySQL Connector/J是否反序列化BLOB類(lèi)型的數(shù)據(jù),后者是攔截器,在查詢(xún)執(zhí)行時(shí)觸發(fā),由com.mysql.cj.protocol.a.NativeProtocol#sendQueryPacket方法源碼可知,會(huì)在執(zhí)行查詢(xún)語(yǔ)句前后分別調(diào)用攔截器的preProcess和postProcess方法。
接下來(lái)定位下反序列化的觸發(fā)點(diǎn),在mysql-connector-java組件下全局搜索關(guān)鍵字“.readObject()”,定位到com.mysql.cj.jdbc.result.ResultSetImpl類(lèi)中的getObject(int columnIndex)方法,部分核心代碼如下:
public Object getObject(int columnIndex) throws SQLException { …… case BLOB: byte[] data = getBytes(columnIndex); if (this.connection.getPropertySet().getBooleanProperty(PropertyDefinitions.PNAME_autoDeserialize).getValue()) { Object obj = data; // Serialized object? try { ByteArrayInputStream bytesIn = new ByteArrayInputStream(data); ObjectInputStream objIn = new ObjectInputStream(bytesIn); obj = objIn.readObject(); } } }
變量data即為mysql返回結(jié)果集,當(dāng)JDBC URL中設(shè)定屬性autoDeserialize為true時(shí),會(huì)對(duì)類(lèi)型為bit、binary以及blob的數(shù)據(jù)進(jìn)行反序列化,如何觸發(fā)getObject(int columnIndex)方法的調(diào)用呢?議題中給出的調(diào)用鏈如下:
> com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor#preProcess/postProcess > com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor#populateMapWithSessionStatusValues > com.mysql.cj.jdbc.util.ResultSetUtil#resultSetToMap > com.mysql.cj.jdbc.result.ResultSetImpl#getObject
ServerStatusDiffInterceptor即為此前提到過(guò)的攔截器,在JDBC URL中設(shè)定屬性queryInterceptors為ServerStatusDiffInterceptor時(shí),執(zhí)行查詢(xún)語(yǔ)句會(huì)調(diào)用攔截器的preProcess和postProcess方法,進(jìn)而通過(guò)上述調(diào)用鏈最終調(diào)用getObject(int columnIndex)方法。
實(shí)際利用還有一個(gè)問(wèn)題,最終調(diào)用getObject方法的對(duì)象是數(shù)據(jù)庫(kù)返回的結(jié)果集,由populateMapWithSessionStatusValues方法可知:
try { toPopulate.clear(); stmt = this.connection.createStatement(); rs = stmt.executeQuery("SHOW SESSION STATUS"); ResultSetUtil.resultSetToMap(toPopulate, rs); }
這個(gè)結(jié)果集是執(zhí)行SQL語(yǔ)句“SHOW SESSION STATUS”后數(shù)據(jù)庫(kù)返回的值,SQL語(yǔ)句“SHOW SESSION STATUS”返回當(dāng)前數(shù)據(jù)庫(kù)連接的狀態(tài)值,實(shí)際是讀取系統(tǒng)表INFORMATION_SCHEMA.SESSION_VARIABLES的值,也可能是PERFORMANCE_SCHEMA.SESSION_VARIABLES(Mysql版本差異導(dǎo)致)。但是mysql中INFORMATION_SCHEMA和PERFORMANCE_SCHEMA都是不允許被修改的,所以需要想辦法操縱返回的數(shù)據(jù)。
利用條件
1.本質(zhì)上還是Java原生的反序列化利用,所以需要環(huán)境中有可用的Gadget;
2.需要能偽造相關(guān)系統(tǒng)表的數(shù)據(jù),將“SHOW SESSION STATUS”的執(zhí)行結(jié)果設(shè)置為我們精心構(gòu)造的反序列化數(shù)據(jù),或者基于mysql連接協(xié)議,自定義返回?cái)?shù)據(jù),后面有時(shí)間的時(shí)候會(huì)寫(xiě)寫(xiě)這塊兒。
3.可控的JDBC URL
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)頁(yè)名稱(chēng):JavaJDBC導(dǎo)致的反序列化攻擊原理解析
本文URL:http://m.rwnh.cn/article46/jdgohg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開(kāi)發(fā)、網(wǎng)站策劃、企業(yè)建站、品牌網(wǎng)站制作、做網(wǎng)站、響應(yīng)式網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)