Smartbi_JNDI
Smartbi——高版本JNDI注入。
前情提要:
Smartbi存在未授权访问后台接口漏洞,结合 DB2 JDBC 利用方式,可导致 JNDI 注入漏洞。
漏洞分析:
首先从参数接收点入手。在RMIServlet中doGet
和doPost
用于参数接收
doGet
:通过参数jsonCallback来接收className
doPost
通过解析RMI信息来获取className、methodName、params。这三个变量在之前的分析文章也经常出现。实际就是要执行的类名、方法名、加参数。
processExecute
方法的作用是解析request
中的相关信息,并利用反射机制调用指定类的指定方法,并将params
转化为对应类型的参数传入到该方法中去执行。最终,将方法执行的结果以字符串形式返回,并赋给resultStr
变量。
testConnection
从数据库连接池中获取了一个数据库连接对象
getConnection
中有很多连接方法。重点关注这个JNDI连接方式。首先从上面接收的url
后截取JNDI后面的字符串进行lookup
,其中lookup
的参数可控,这也是本次漏洞的触发点。
高版本JNDI介绍:
低版本的JNDI注入是可以加载远程恶意类的。但是在高版本官方对远程加载类进行了限制。目前高版本JDK的防护方式主要是针对加载远程的ObjectFactory
的加载做限制,只有开启了某些属性后才会通过指定的远程地址获取ObjectFactory
的Class并实例化,进而通过ObjectFactory#getObjectInstance
来获取返回的真实对象。
但是在加载远程地址获取ObjectFactory
前,首先在本地ClassPath
下加载指定的ObjectFactory
,本地加载ObjectFactory
失败后才会加载远程地址的ObjectFactory
,所以一个主要的绕过思路就是加载本地ClassPath下的ObjectFactory
。
我们需要找到一个javax.naming.spi.ObjectFactory
接口的实现类,在这个实现类的getObjectInstance
可以实现一些恶意操作。但是在JDK提供的原生实现类里其实并没有操作空间。所以下面我们主要的思路就是在一些常用的框架或者组件中寻找可利用的ObjectFactory实现类。
而Smartbi自带的jdk版本是8.0.202.3
,正是修复JNDI过后的高版本jdk。
绕过思路:
Tomcat下的绕过比较精彩的并不是EL表达式利用,而是通过BeanFactory#getObjectInstance
将这个漏洞的利用面从仅仅只能从ObjectFactory
实现类的getObjectInstance
方法利用扩展为一次可以调用”任意”类的”任意”方法的机会,但是对调用的类和方法以及参数有些限制。
- 该类必须包含public无参构造方法
- 调用的方法必须是public方法
- 调用的方法只有一个参数并且参数类型为String类型
所以下面我们只要找到某个类的某个方法既满足了上面的条件又实现我们想要的功能。
javax.el.ELProcessor#eval
执行命令,但是ELProcessor
是在Tomcat8才引入的。groovy.lang.GroovyShell#evaluate(java.lang.String)
通过Groovy执行命令。com.thoughtworks.xstream.XStream().fromXML(String)
通过调用XStream
转换XML时的反序列化漏洞导致的RCE,这里之所以选择XStream
是因为Xstream的反序列化漏洞和影响版本比较多。JSON的转换的漏洞相对来说通用性不高。org.yaml.snakeyaml.Yaml#load(java.lang.String)
加载Yaml时的反序列化漏洞,在SpringBoot中经常会使用snakeyaml
来进行yml配置文件的解析。org.mvel2.MVEL#eval(String)
执行命令,这里浅蓝
师傅文章中提到的是MVEL
类是private所以要找上层调用,我在2.0.17
中测试Mvel
是存在public无参构造方法的,高版本确实换成了private构造方法。所以只能找那里调用了Mvel#eval
方法,而org.mvel2.sh.ShellSession#exec
调用了Mvel#eval
,因此可以通过ShellSession#exec
来间接完成调用。com.sun.glass.utils.NativeLibLoader#loadLibrary(String)
加载DLL,前提是我们已经将构造好的DLL上传至目标上,所以局限性比较大。
服务端代码:
1 |
|
漏洞复现:
1 |
|