前言
ApacheLog4j2是一款优秀的Java日志框架,最近爆出了一个jndi注入的漏洞,影响面非常广,各大厂商都被波及。Log4j2作为日志记录的第三方库,被广泛得到使用,这次主要分享一下,最近的一些调试记录。
JNDI简介
JNDI全称为JavaNamingandDirectoryInterface,即Java名称与目录接口。本质上就是一个接口,ND代表的Naming和Directory,分别代表NamingService(名称服务)和DirectoryService(目录服务)。参考JNDI注入漏洞的前世今生
名称服务就是通过名称查找实际对象的服务,例如:通过域名寻找ip地址即DNS服务、文件系统、以及LDAP(LightweightDirectoryAccessProtocol)即轻量级目录访问协议都是名称服务,不同的是LDAP(RFC(RFC))是一个协议,是和HTTP一样是通用的,而不止局限于JAVA.目录服务是名称服务的一种拓展,除了名称服务中已有的名称到对象的关联信息外,还允许对象拥有属性(attributes)信息。由此,我们不仅可以根据名称去查找(lookup)对象(并获取其对应属性),还可以根据属性值去搜索(search)对象。目录服务也是一种特殊的名称服务,关键区别是在目录服务中通常使用搜索(search)操作去定位对象,而不是简单的根据名称查找(lookup)去定位。
JNDI架构上主要包含两个部分,即Java的应用层接口和SPI,SPI全称为ServiceProviderInterface,即服务供应接口,主要作用是为底层的具体目录服务提供统一接口,从而实现目录服务的可插拔式安装,如下图所示:
如上JNDI为不同的目录服务提供统一的操作接口
JDK中包含了下述内置的目录服务:
RMI:JavaRemoteMethodInvocation,Java远程方法调用;
LDAP:轻量级目录访问协议;
CORBA:CommonObjectRequestBrokerArchitecture,通用对象请求代理架构,用于COS名称服务(CommonObjectServices);
RMI
RMI(RemoteMethodInvocation)即java的远程方法调用,JavaRMI是专为Java环境设计的远程方法调用机制,远程服务器实现具体的Java方法并提供接口,客户端本地仅需根据接口类的定义,提供相应的参数即可调用远程方法并获取执行结果,即JAVA的RPC机制。关于RMI需要注意以下两点:
RMI的传输是基于反序列化的。
对于任何一个以对象为参数的RMI接口,你都可以发一个自己构建的对象,迫使服务器端将这个对象按任何一个存在于服务端classpath(不在classpath的情况,可以看后面RMI动态加载类相关部分)中的可序列化类来反序列化恢复对象。
更多可以参考: