最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

java反序列化漏洞及其檢測(cè)

2022-10-13 13:19 作者:不吃晚飯la  | 我要投稿

1 java反序列化簡(jiǎn)介

java反序列化是近些年安全業(yè)界研究的重點(diǎn)領(lǐng)域之一,在Apache Commons Collections、JBoss、WebLogic 等常見(jiàn)容器、庫(kù)中均發(fā)現(xiàn)有該類(lèi)漏洞,而且該類(lèi)型漏洞容易利用,造成的破壞很大,因此影響廣泛。

在本文中將先介紹java反序列化漏洞的原理,然后在此基礎(chǔ)上介紹安全工具如何檢測(cè)、掃描此類(lèi)漏洞。

1.1 什么是反序列化

Java序列化是指把Java對(duì)象轉(zhuǎn)換為字節(jié)序列的過(guò)程,序列化后的字節(jié)數(shù)據(jù)可以保存在文件、數(shù)據(jù)庫(kù)中;而Java反序列化是指把字節(jié)序列恢復(fù)為Java對(duì)象的過(guò)程。如下圖所示

?

?


序列化和反序列化通過(guò)ObjectInputStream.readObject()ObjectOutputStream.writeObject()方法實(shí)現(xiàn)。

在java中任何類(lèi)如果想要序列化必須實(shí)現(xiàn)java.io.Serializable接口,例如:

public class Hello implements java.io.Serializable {String name;}

java.io.Serializable其實(shí)是一個(gè)空接口,在java中該接口的唯一作用是對(duì)一個(gè)類(lèi)做一個(gè)標(biāo)記讓jre確定這個(gè)類(lèi)是可以序列化的。

同時(shí)java中支持在類(lèi)中定義如下函數(shù):

private void writeObject(java.io.ObjectOutputStream out)?????? throws IOExceptionprivate void readObject(java.io.ObjectInputStream in)?????? throws IOException, ClassNotFoundException;

這兩個(gè)函數(shù)不是java.io.Serializable的接口函數(shù),而是約定的函數(shù),如果一個(gè)類(lèi)實(shí)現(xiàn)了這兩個(gè)函數(shù),那么在序列化和反序列化的時(shí)候ObjectInputStream.readObject()ObjectOutputStream.writeObject()會(huì)主動(dòng)調(diào)用這兩個(gè)函數(shù)。這也是反序列化產(chǎn)生的根本原因

例如:

public class Hello implements java.io.Serializable {??? String name;private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {??????? Runtime.getRuntime().exec(name);}}

該類(lèi)在反序列化的時(shí)候會(huì)執(zhí)行命令,我們構(gòu)造一個(gè)序列化的對(duì)象,name為惡意命令,那么在反序列化的時(shí)候就會(huì)執(zhí)行惡意命令。

在反序列化的過(guò)程中,攻擊者僅能夠控制“數(shù)據(jù)”,無(wú)法控制如何執(zhí)行,因此必須借助被攻擊應(yīng)用中的具體場(chǎng)景來(lái)實(shí)現(xiàn)攻擊目的,例如上例中存在一個(gè)執(zhí)行命令的可以序列化的類(lèi)(Hello),利用該類(lèi)的readObject函數(shù)中的命令執(zhí)行場(chǎng)景來(lái)實(shí)現(xiàn)攻擊。

1.2 反序列化漏洞示例復(fù)現(xiàn)

在這里我們構(gòu)造一個(gè)有漏洞的靶場(chǎng)進(jìn)行漏洞復(fù)現(xiàn)測(cè)試:使用spring-boot編寫(xiě)一個(gè)可以接收http數(shù)據(jù)并反序列化的應(yīng)用程序。

使用https://start.spring.io/生成一個(gè)spring-boot應(yīng)用,選擇Maven Project、java8

?


?

下載到本地,導(dǎo)入IDE,修改pom.xml加入Apache Commons Collections 3.1依賴(lài)(該版本存在反序列化漏洞)

<dependency>? <groupId>commons-collections</groupId>? <artifactId>commons-collections</artifactId>? <version>3.1</version></dependency>

修改DemoApplication.java 為如下代碼

?

?


?

?

此時(shí)我們就完成了一個(gè)有Apache Commons Collections漏洞的驗(yàn)證靶場(chǎng),啟動(dòng)該靶場(chǎng)應(yīng)用

我們使用 ysoserial 生成攻擊payload:

java -jar ysoserial-master-8eb5cbfbf6-1.jar CommonsCollections5 "calc.exe" > poc

然后使用 httpie 發(fā)送攻擊payload(poc)

http post http://127.0.0.1:8080/rmi < poc

這時(shí)候就可以看到poc中的命令執(zhí)行了

?


1.3 反序列化漏洞解析

在1.2 的示例中我們使用了 ysoserial 的 CommonsCollections5 這個(gè)payload,本節(jié)我們對(duì)此poc進(jìn)行分析

?


?

可以最終反序列化的對(duì)象為 javax.management.BadAttributeValueExpException ,在該類(lèi)提供了 readObject 方法,在其中有問(wèn)題的地方為

val = valObj.toString();

這里的 valObj 為 TiedMapEntry(lazyMap, “foo”) ,該類(lèi)的toString方法

public String toString() {return this.getKey() + "=" + this.getValue();}

其中 this.getValue 為

public Object getValue() {return this.map.get(this.key);}

而 this.map 為 lazyMap = LazyMap.decorate(innerMap, transformerChain),在 lazyMap 中

public Object get(Object key) {??? if (!super.map.containsKey(key)) {? // 當(dāng)找不到key的時(shí)候調(diào)用transform??????? Object value = this.factory.transform(key);??????? super.map.put(key, value);??????? return value;??? } else {??????? return super.map.get(key);}}

在其中看到,沒(méi)有找到key的時(shí)候,調(diào)用了 this.factory.transform(key)

而this.factory為我們構(gòu)造的包含payload的執(zhí)行鏈 transformerChain 該transformer會(huì)最終通過(guò)反射執(zhí)行命令。

2 java反序列化漏洞檢測(cè)

在1中的原理介紹中,我們可以看到,反序列化漏洞需要依賴(lài)執(zhí)行鏈來(lái)完成攻擊payload執(zhí)行。由于反序列化漏洞的特性,在檢測(cè)的時(shí)候漏洞掃描工具一般聚焦已知漏洞的檢測(cè),而未知漏洞的檢測(cè),安全工具能力非常有限,一般需要專(zhuān)業(yè)人員通過(guò)安全審計(jì)、代碼審計(jì)等方式發(fā)現(xiàn)。

java反序列化漏洞依賴(lài)于兩個(gè)因素:

1.應(yīng)用是否有反序列化接口

2.應(yīng)用中是否包含有漏洞的組件

因此對(duì)應(yīng)的漏洞掃描工具也需要根據(jù)這兩個(gè)因素進(jìn)行檢測(cè)。

2.1 白盒工具檢測(cè)

白盒代碼審計(jì)工具,可通過(guò)在調(diào)用鏈中查找是否有發(fā)序列化的操作:

·??????? 調(diào)用鏈的入口不同框架是不同的,例如在1.2例子中調(diào)用鏈的入口為spring-boot的controller。

·??????? 調(diào)用鏈中一旦發(fā)現(xiàn)有發(fā)序列化操作ObjectInputStream.readObject()則該接口存在序列化操作

但僅僅依靠以上信息不足以判斷是否存在漏洞,還需要判斷代碼中是否有存在*執(zhí)行鏈**的三方依賴(lài)。在java中,一般通過(guò)分析 pox.xml build.gradle 文件來(lái)分析是否包含有漏洞的組件。

2.2 黑盒漏洞掃描器檢測(cè)

web漏洞掃描器檢測(cè)原理和白盒工具不一樣。

首先漏洞掃描器要解決的是識(shí)別出反序列化的請(qǐng)求,在這里需要注意的是web漏洞掃描是無(wú)法通過(guò)爬蟲(chóng)方式直接發(fā)現(xiàn)反序列化接口的,因此往往需要配合其他web漏洞掃描器的組件(例如代理組件)來(lái)識(shí)別反序列化接口,如下圖所示

?

?


?

如今web漏洞掃描器都提供了代理組件來(lái)發(fā)現(xiàn)應(yīng)用的http請(qǐng)求,爬蟲(chóng)組件可通過(guò)前臺(tái)頁(yè)面觸發(fā)請(qǐng)求進(jìn)入代理組件;但在API場(chǎng)景下,還是需要測(cè)試人員進(jìn)行API調(diào)用該操作才能夠產(chǎn)生http請(qǐng)求數(shù)據(jù)。

在截獲到http請(qǐng)求數(shù)據(jù)后,代理組件可以通過(guò)兩種方式判斷一個(gè)請(qǐng)求是否是序列化請(qǐng)求:

1.????? 通過(guò)http請(qǐng)求的Content-Type,具體來(lái)說(shuō)ContentType: application/x-java-serialized-object 是序列化請(qǐng)求的請(qǐng)求頭

2.????? 檢查請(qǐng)求數(shù)據(jù)的開(kāi)頭是否是 0xaced,有時(shí)候序列化請(qǐng)求不存在正確的content-type,此時(shí)需要根據(jù)數(shù)據(jù)來(lái)判斷是否是序列化請(qǐng)求

在確定一個(gè)接口是序列化接口的時(shí)候會(huì)漏洞掃描器會(huì)發(fā)送探測(cè)payload判斷接口是否有反序列化漏洞,這里的攻擊payload類(lèi)似于1.2節(jié)中使用的ysoserial 工具,由于絕大多數(shù)情況下不可能看到回顯(http返回?cái)?shù)據(jù)沒(méi)有攻擊執(zhí)行結(jié)果),因此只能進(jìn)行盲注,即發(fā)送 sleep 10 這樣的命令,根據(jù)響應(yīng)時(shí)間判斷是否有漏洞。

?


java反序列化漏洞及其檢測(cè)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
于都县| 泰宁县| 栖霞市| 南靖县| 金坛市| 松桃| 壤塘县| 文昌市| 交城县| 福清市| 巨鹿县| 呼和浩特市| 千阳县| 云浮市| 邢台市| 新乐市| 汶川县| 泉州市| 唐河县| 三都| 寿阳县| 肇庆市| 吴桥县| 明水县| 江安县| 仪征市| 贺州市| 易门县| 塘沽区| 清流县| 苗栗市| 宁蒗| 霸州市| 呈贡县| 清远市| 合江县| 儋州市| 元氏县| 游戏| 客服| 积石山|