Java RMI反序列化/JEP290相關

RMI

遠程過程調用 (Remote Procedure Call)是一種服務器-客戶端模式,
Java的RMI(Remote Method Invocation)是一種RPC實現。
其基本思想是程序員可以像本地那樣,與遠程對象進行交互。

步驟:

1、創建一個接口IRemoteService,繼承自java.rmi.Remote;
2、S端創建一個類IRemoteServiceImpl,實現該接口,並且繼承自java.rmi.server.UnicastRemoteObject;
3、S端在某端口(1099)註冊該Naming服務,並將新建的對象(Skeleton)與該服務綁定;
4、C端通過網絡連接(lookup)到該服務,得到C端的對象(Stub)通過網絡調用服務端對象(Skeleton)的方法。

RMI安全問題

RMI基於Java的序列化/反序列化實現,使其成爲反序列漏洞利用的一個攻擊面。

原理

攻擊者輸入惡意序列化對象,使得RMI服務端反序列化攻擊者指定的對象;
如果攻擊者指定的對象實現了自定義的readObject()方法,則在反序列化過程中可以藉此實現一些副作用(比如執行任意代碼)。

利用條件

RMI服務端classloader可以找到(存在於classpath中)一個或多個類,能在反序列化過程中實現攻擊者的意圖。通常把能實現這個的類叫做gadget,或者當通過多個類組合起來實現的叫做gadget chain

Ysoserial

是一個預裝了多個gadgets的反序列化漏洞利用工具。

JEP 290

這篇文章A First Look Into Java’s New Serialization Filtering
對JEP 290做了解讀。
認爲

在Java反序列化漏洞廣受詬病的背景下,Oracle拿出了出了它自己的起碼之力:JEP 290,提供了一種反序列化過濾的機制。這個機制確實是在朝正確的方向上走。但它不能完全解決問題,也不適合企業生產環境。

因爲這種黑名單/白名單的過濾機制只有配置得當,纔能有效過濾掉惡意的反序列化攻擊。

JEP 290引入了三種過濾機制:

一、進程級過濾器(Process-wide Filter),也叫全局過濾器(Global Filter)

這種過濾方式的工作方式是:
啓動Java應用時添加命令行參數(後面有例子)

-Djdk.serialFilter=<白名單類1>;<白名單類2>;!<黑名單類>

或者設置Java系統屬性(Java 6,7,8)
$JAVA_HOME/jre/lib/security/java.security(官方的是錯的)
或者啓動Java應用時設置

-Djava.security.properties=<黑白名單配置文件名>

基於白名單的進程級過濾器雖然是有效的,但是由於是白名單,程序員得找出某應用所有需要被反序列化調用的類,所以一般較難實現。不需要程序員手動修改應用程序級別的代碼,因爲這個機制已經內置在加入JEP 290的JDK代碼(java.io.ObjectInputStream)中。
PS:對於RMI反序列化,如果加入了全局過濾器,當然沒有辦法繞過這個全局過濾器。

二、自定義過濾器(Custom filters)

可以覆蓋進程級過濾器!
當程序員很明確知道他想要反序列化的類是在哪個具體的包下,或者具體的類。需要程序員手動修改應用程序級別的代碼。
通過代碼:

ObjectInputFilter filesOnlyFilter = ObjectInputFilter.Config.createFilter("de.mogwailabs.Example;!*");

表示只接受
de.mogwailabs.Example
這個包下的類,其他的類都會被拒絕。
PS: 對於RMI反序列化,我們不關心這個,因爲我們無法修改服務端代碼。

三、內置過濾器(Built-in Filters)

//TODO

關於java.security文件

這個文件在jre目錄下,
Java 6、7、8的是在這個目錄下:

$JAVA_HOME/jre/lib/security/java.security

看一下不同的JDK有沒有JEP 290有什麼區別:
在這裏插入圖片描述
具體看一下這個有JEP 290的jdk1.8.0_112的java.security文件有什麼東西。
首先有全局過濾器,即

jdk.serialFilter

這個值,不過需要程序員自行配置。
在這裏插入圖片描述

另外有RMI相關的,有一個內置的黑名單:
在這裏插入圖片描述
Github有人寫了一個常用的黑名單,配置JEP 290機制使用:
以下有一些黑名單類集合(過濾掉ysoserial中的gadgets):
https://github.com/mogwailabs/deserialization-filter-blacklists/blob/master/blacklist-filter.properties
在這裏插入圖片描述
在以下JDK版本之上

  • Java 8 - 8u121
  • Java 7 - 7u131
  • Java 6 - 6u141

可以使用以下方式來進行進程級(Process-wide)的黑名單過濾,操作方法:

java -Djava.security.properties=blacklist-filter.properties -jar application.jar

後JEP 290時代

ATTACKING JAVA RMI SERVICES AFTER JEP 290
這篇文章其實人家也沒說繞過JEP 290的機制。人家標題說的就是XXX after jep 290,即"後JEP 290時代的Java RMI漏洞利用方式",從頭到尾沒說繞過的事,也在開篇承認了如果在JEP 290機制下使用了全局過濾,那還是沒問題的。
在這裏插入圖片描述
翻譯過來是:如果沒有配置全局過濾器,我們還是可以在應用程序級別下功夫利用反序列化漏洞的。

以最近的Dubbo反序列漏洞爲例,比如我們用CommonsCollections4這個gadget生成了payload,不管是使用JDK 112還是JDK 131啓動dubbo-samples-http,都可以被反序列化成功。原因在於JEP 290只是引入了一種機制,要麼使用進程級的過濾器,要麼各個應用自己加上自己應用級的過濾器。
而且對於JDK 112,即便加上了這個參數

-Djava.security.properties=/Users/caiqiqi/GitProjects/JavaSer/JEP290/blacklist-filter.properties

在這裏插入圖片描述
啓動後,依然可以被反序列化成功。
反序列化成功HTTP響應結果是:
在這裏插入圖片描述
而當使用帶JEP290的JDK 131啓動時,
在這裏插入圖片描述
未能命令執行。HTTP返回響應:
在這裏插入圖片描述
報錯信息是:

java.io.InvalidClassException: filter status: REJECTED

對比一下:
在這裏插入圖片描述
從打印出的調試信息也可以看出JEP 290修改了java.io.ObjectInputStream類,增加了過濾對待反序列化對象的類檢查的邏輯(推測的,待看具體代碼)。

RMI反序列化漏洞環境

環境來源:
https://github.com/mogwailabs/rmi-deserialization
環境包括服務端和客戶端。且兩端持有相同的接口:
IBSidesService.java

package de.mogwailabs.BSidesRMIService;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IBSidesService extends Remote {

   boolean register(String ticketID) throws RemoteException;
   void visitTalk(String talkname) throws RemoteException;
   void poke(Object attende) throws RemoteException;
}

在這裏插入圖片描述
爲了環境更加真實,這裏沒有將服務端和客戶端放到同一個節點上。服務端代碼BSidesMucRmiService放到ubuntu-server虛擬機裏:
使用maven編譯依賴並打包:

mvn clean compile assembly:single

成功打包成jar之後,會在默認端口1099啓動RMI服務:

java -jar ./target/BSidesRMIService-0.1-jar-with-dependencies.jar

在這裏插入圖片描述
使用nmap掃描1099端口,可以得到34725這個新的端口,然後第二次使用nmap掃描,可以獲取到遠程RMI服務的一些信息。
在這裏插入圖片描述
然後編譯客戶端。由於客戶端有ysoserial的payload,需要帶上ysoserial作爲classpath:

javac -cp /Users/caiqiqi/Downloads/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar *.java

在這裏插入圖片描述

漏洞利用:

java -cp .:/Users/caiqiqi/Downloads/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar de.mogwailabs.BSidesRMIService.AttackClient 127.0.0.1  1099 "touch /tmp/test_rmi"

JDK 1.8.0_112
在這裏插入圖片描述
可以成功
在這裏插入圖片描述
在這裏插入圖片描述

參考

發佈了592 篇原創文章 · 獲贊 97 · 訪問量 97萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章