简单介绍
大家都知道JDK高版本后,限制远程Reference加载的属性是trustURLCodebase
但它其实没有看上去那么简单,具体限制分为两部分
系统属性
第一个是可以用System.setProperty改的系统属性**com.sun.jndi.ldap.object.trustURLCodebase
**
其带来的限制较前,而且会在目标控制台弹出警告
什么是系统属性?
使用System.setProperty
分别设置com.sun.jndi.ldap.object.trustURLCodebase
/com.sun.naming.internal.VersionHelper12
两个系统属性为ture
然而com.sun.naming.internal.VersionHelper12
类实例属性仍然为false
系统属性是特殊的全局变量,和具体的类属性无关,也只能通过System.set/get…..的方式来设置/获取
类私有属性
另一个是**com.sun.naming.internal.VersionHelper12
中的trustURLCodebase
**
由private static final
修饰,String类型,初始化为**com.sun.jndi.ldap.object.trustURLCodebase
**,Spring和Tomcat下,其类初始化发生在Web应用启动之时
最终影响loadClass是否生效,拦截到了也不会警告,只是默默地不从远程codebase加载类
操纵之术
系统属性
有很多反序列化链都可以修改,具体可见:
BCS2022-探索JNDI攻击 by浅蓝
然而单单改系统属性是不够的,除非是Web应用初始化阶段就改掉
所以继续来看类私有属性
类私有属性
VersionHelper12
里也没有setter,这个肯定只能反射改了
考虑以下两个问题
static final修改
针对这种情况,需要先去掉final修饰符
一种适用于 JDK8Java8 至 JDK17Java17 的反射修改 static final 属性的方法
https://blog.csdn.net/wu_weijie/article/details/129251045
获取实例对象
因为加载类的时候要用到,大概率是单例,打个断点,看看加载类的时候是从哪里拿到这个对象的
发现了如下方法调用
VersionHelper.getVersionHelper()
最终payload
由于要反射修改,所以只能在RCE(而且是动态代码执行上下文)条件下实现
适用于LDAP,Java 8 ~ Java11
1 | System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true"); |
应用场景#非常无用
纯鸡肋: 在JDK高版本,利用具有动态代码执行上下文的反序列化漏洞,使得JNDI注入漏洞可以远程类加载
- 本文链接:https://whocansee.github.io/2024/03/19/%E6%B5%85%E8%B0%88trustURLCodebase%E9%99%90%E5%88%B6%E7%9A%84%E8%A7%A3%E9%99%A4/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。