Hibernate1 是触发 getter 方法,除了 TemplatesImpl 实例化恶意类字节码,还可以通过 JdbcRowSetImpl 触发恶意 JNDI 查询,Hibernate2 就是这种方式
JAVA环境
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)
依赖版本
- Hibernate Core 依赖版本:3-5
检查依赖配置
确认项目中是否正确引入了
- Hibernate Core
的依赖。如果使用的是 Maven,可以在 pom.xml 文件中添加以下依赖:
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.10.Final</version>
</dependency>
资源下载
前置知识
JdbcRowSetImpl
com.sun.rowset.JdbcRowSetImpl 本质上是 Java 标准库中的一个类,用于基于 JDBC 的数据库交互,其设计允许通过配置数据源(如 JNDI URI)来访问远程资源
connect
在 com.sun.rowset.JdbcRowSetImpl 中有一个关键方法叫做connect()
- 当数据库连接不为空时,直接返回数据库连接
- 当数据库连接为空,并且
dataSource不为空继续往下走getDataSourceName()获取的是dataSource属性dataSource的设计初衷是用来指定数据库的数据源名称,通常是一个合法的 JNDI 数据源名称,用于连接数据库dataSource在 JdbcRowSetImpl 中的主要作用是配置数据源,通过 JNDI 查找数据库连接配置
- 获取 JNDI 的上下文对象
- 通过 JNDI 的上下文对象查找配置项
- JNDI 通过lookup来获取 JNDI 对象的配置项
- 如果
this.getDataSourceName()是一个恶意构造的ldap://ip:port/EvilClass,就会导致lookup过来的其实是一个恶意类,从而导致恶意代码执行
private Connection connect() throws SQLException {
if (this.conn != null) {
return this.conn;
} else if (this.getDataSourceName() != null) {
try {
InitialContext var1 = new InitialContext();
DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
return this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();
} catch (NamingException var3) {
throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
}
} else {
return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;
}
}
如果这个 dataSource 参数是我们可控的,那么我们直接通过调用 connect() 就能达到加载恶意代码的效果
那么哪些地方会触发这个connect()方法呢?通过IDEA可以看到有三处调用

:Hibernate2&spm=1001.2101.3001.5002&articleId=147236456&d=1&t=3&u=9c85841706a4431cb50eed782fc5ec81)
1378

被折叠的 条评论
为什么被折叠?



