<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>

          Java安全之原生readObject方法解讀

          共 3348字,需瀏覽 7分鐘

           ·

          2020-12-24 00:48

          點擊上方藍色字體,選擇“標星公眾號”

          優(yōu)質文章,第一時間送達

          ? 作者?|??nice_0e3

          來源 |? urlify.cn/Ef2iMr

          66套java從入門到精通實戰(zhàn)課程分享

          1、前言

          在上篇文章分析shiro中,遇到了Shiro重寫了ObjectInputStreamresolveClass導致的一些基于InvokerTransformer去實現(xiàn)的利用鏈沒法使用,因為這需要去定義一個InvokerTrans數(shù)組,而該數(shù)組傳入到Shiro重寫后的resolveClass方法中會報錯。但是在此之前,并沒有去對readObject方法去做一個解讀和分析。所以也不知道他具體的實現(xiàn)。包括在分析利用鏈的時候,只知道到調用了ObjectInputStream.readObject方法后,如果readObject被重寫的話,就會調用重寫后的readObject方法,但是我們也并不知道在內部是怎么樣去做一個實現(xiàn)的。那么下面來分析一下readObject的功能實現(xiàn)。


          2、 readObject方法分析

          在前面先貼一張readObject的執(zhí)行流程圖,這是一張weblogic的反序列化執(zhí)行流程圖。第一個readObject直接忽略,到下篇文weblogic再做講解。

          這里寫一段測試代碼去進行反序列化操作,然后進行動態(tài)跟蹤。

          User實體類:

          package?com.nice0e3;

          import?java.io.Serializable;

          public?class?User?implements?Serializable?{
          ????private?String?name;
          ????private?int?age;

          ????@Override
          ????public?String?toString()?{
          ????????return?"User{"?+
          ????????????????"name='"?+?name?+?'\''?+
          ????????????????",?age="?+?age?+
          ????????????????'
          }';
          ????}

          ????public?String?getName()?{
          ????????return?name;
          ????}

          ????public?void?setName(String?name)?{
          ????????this.name?=?name;
          ????}

          ????public?int?getAge()?{
          ????????return?age;
          ????}

          ????public?void?setAge(int?age)?{
          ????????this.age?=?age;
          ????}

          ????public?User()?{
          ????}

          ????public?User(String?name,?int?age)?{
          ????????this.name?=?name;
          ????????this.age?=?age;
          ????}
          }

          ReadTest類:

          package?com.nice0e3;

          import?java.io.*;

          public?class?ReadTest?{
          ????public?static?void?main(String[]?args)?throws?IOException,?ClassNotFoundException?{
          ????????User?user?=?new?User();
          ????????user.setName("nice0e3");
          ????????user.setAge(20);
          ????????ObjectOutputStream?oos?=?new?ObjectOutputStream(new?FileOutputStream("1.txt"));
          ????????oos.writeObject(user);
          ????????ObjectInputStream?ois?=?new?ObjectInputStream(new?FileInputStream("1.txt"));
          ????????Object?o?=?ois.readObject();
          ????}
          }

          然后將斷點落在ObjectInputStream.readObject方法中,進行執(zhí)行測試類代碼動態(tài)跟蹤。

          這里對enableOverride進行了一個判斷,不為flase的話就會去返回readObjectOverride方法,而在構造方法中就定義該值為flase。

          下面就直接執(zhí)行到了這步

          調用了readObject0方法,選擇跟進查看一下內部的實現(xiàn)。

          在這里會去獲取序列化信息第一個字節(jié),如果為TC_RESET就會調用bin.readByte()handleReset();方法。

          查看TC_RESET內容。

          而該值轉換Byte后,為121,我們序列化數(shù)據(jù)的第一個字節(jié)為151,這里就跳過不執(zhí)行了。

          接下來代碼中定義了一個switch去做一個判斷,TC_OBJECT的值轉換后剛剛好為115。那么就會執(zhí)行到這一步。

          在這里面會調用readOrdinaryObject方法,進行跟進。

          在該方法中還會去調用readClassDesc方法,繼續(xù)跟進。

          看到這里發(fā)現(xiàn)就很有意思了,獲取我們序列化數(shù)據(jù)的第二個字節(jié),然后又進行一次switch,這次走到了readNonProxyDesc方法中,跟進!

          在這又調用了resolveClass方法然后傳入readDesc參數(shù)。還是跟進方法。

          這里返回了

          Class.forName(name,?false,?latestUserDefinedLoader());

          latestUserDefinedLoader()方法返回的是sun.misc.VM.latestUserDefinedLoader()說明指定了該加載器。

          返回到readOrdinaryObject方法中繼續(xù)做分析。

          直接定位到這一步,該方法對反序列化的操作進行實現(xiàn)。

          這里的slotDesc.hasReadObjectMethod()獲取的是readObjectMethod這個屬性,如果反序列化的類沒有重寫readobject(),那么readObjectMethod這個屬性就是空,如果這個類重寫了readobject(),那么就會進入到if之中的

          slotDesc.invokeReadObject(obj,?this);


          如果readobject()方法被重寫則是走到這一步


          3、Shiro resolveClass方法分析

          在shiro里面resolveClass方法被進行了重寫,導致大部分利用鏈都使用不了,查看一下該方法實現(xiàn)。

          這里去調用了ClassUtils.forName方法進行跟蹤。

          這里是調用了THREAD_CL_ACCESSOR.loadClass,查看一下THREAD_CL_ACCESSOR是什么。

          跟進查看一下該類。

          這里調用getClassLoader方法獲取類加載器,而在這里獲取到的是ParallelWebappClassLoader,那么下面調用的肯定也就是ParallelWebappClassLoader.loadClass

          上面內容中的一些補充:

          TC_NULL描述符表示空對象引用

          TC_REFERENCE描述符表示引用已寫入流的對象

          TC_PROXYCLASSDESC是新的代理類描述符

          TC_CLASSDESC是新的類描述符

          參考文章

          https://blog.csdn.net/niexinming/article/details/106665753

          https:
          //www.anquanke.com/post/id/192619#h2-2


          4、 結尾

          其實在前面的一些cc鏈的調試鋪墊下,再去調試其他的一些漏洞,都會比較熟練。本文也是為了下文去做了一個較好的鋪墊。




          粉絲福利:Java從入門到入土學習路線圖

          ???

          ?長按上方微信二維碼?2 秒


          感謝點贊支持下哈?

          瀏覽 81
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  99热激情 | 一级成人亚欧精品 | 国产99自拍 | 免费黄色a片子 | 成全在线观看高清的 |