Java代码审计之SQL注入——Hibernate框架

admin 2021年5月6日18:29:25评论102 views字数 5348阅读17分49秒阅读模式

Hibernate简介

   Hibernate是一个开源的对象关系映射(ORM:Object Relation Mapping)框架,对JDBC进行了非常轻量级的对象封装,采用映射元数据(配置文件)来描述对象-关系的映射细节,是一个全自动的orm框架。hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

Hibernate简单架构

  1. 创建持久化类
  2. 创建对象-关系映射文件
  3. 创建Hibernate配置文件
  4. 通过Hibernate API编写访问数据库的代码

    Java代码审计之SQL注入——Hibernate框架

定位框架

  直接查看相关的依赖即可:

xml
<!-- 添加Hibernate依赖 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.10.Final</version>
</dependency>

  或者是相关的配置文件 hibernate.cfg.xmlhibernate.properties*.hbm.xml

  例如hibernate.cfg.xml:

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 1. 配置数据库信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">ceshi</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 2. 其他配置 -->
<!-- 显示生成的SQL语句 -->
<property name="hibernate.show_sql">true</property>
<property name="format_sql">true</property><!-- 会格式化输出sql语句 -->
<!-- 3. 导入映射文件 -->
<mapping resource="/com/tk/sqlinject/hibernate/User.hbm.xml" />
</session-factory>
</hibernate-configuration>

  除了上述方式外,还可以通过hibernate相关的注解来定位,例如

@Column
@Transient
@Table
.....

Hibernate框架下SQL注入漏洞产生场景

  Hibernate查询方式主要有get/load主键查询,对象导航查询、HQL查询、Criteria查询、SQLQuery本地SQL查询。审计的方法主要是搜索createQuery()、createSQLQuery、criteria、createNativeQuery(),查看与其相关的上下文,检查是否存在拼接sql

HQL查询

  HQL:hibernate query language,即hibernate提供的面向对象的查询语言。查询的是对象以及对象的属性(区分大小写)。HQL查询并不直接发送给数据库,而是由hibernate引擎对查询进行解析并解释,根据对象-关系映射文件中的映射信息,将其转换为SQL。

  跟所有SQL注入的成因一样,使用拼接HQL语句的写法可能会导致SQL注入:

java
Query<User> query = session.createQuery("from User where name='"+queryString+"'");//hql拼接

  但是HQL注入存在一定的局限性,不能像常规SQL注入一样利用。 其没有联合,没有可用的元数据表等。Hibernate查询语言没有那些在后台数据库中可能存在的功能特性。

  举几个例子:

  • 不支持*

java
Query<User> query = session.createQuery("select *from User");

Java代码审计之SQL注入——Hibernate框架
* 不支持Union
java
Query<User> query = session.createQuery("from User Union select 1,2,3,4,5");

Java代码审计之SQL注入——Hibernate框架
* 不支持跨库查表,系统表也不行(未映射的表不可查询)

java
Query<User> query = session.createQuery("from hibernate.user4");

Java代码审计之SQL注入——Hibernate框架
  查询mysql的系统表information_schema同样会返回表not mapped:

java
Query<User> query = session.createQuery("from information_schema.tables");

Java代码审计之SQL注入——Hibernate框架
* 表名、列名大小写敏感
  例如映射配置文件中将User Bean映射如下:

xml
<hibernate-mapping>
<class name="com.tk.sqlinject.hibernate.User" table="USER">
<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>
......
</hibernate-mapping>

  那么如果我们并没有考虑大小写,直接查询user的话是会产生not mapped报错的:

java
Query<User> query = session.createQuery("from user");

Java代码审计之SQL注入——Hibernate框架
  HQL无法直接执行原生SQL,及写文件,执行命令等操作。除了利用万能密码、知道表名列名的情况下进行盲注外,暂时没想到比较好的方法来进行漏洞利用。但是成因跟判断方式跟SQL注入类似,所以也归在一起,审计时候可以注意。

Criterion查询

  Hibernate支持Criteria查询(Criteria Query),该查询方式把查询条件封装为一个Criteria对象。在实际应用中,通过构建一个org.hibernate.Criteria实例,然后把具体的查询条件通过Criteria的add()方法加入到Criteria实例中。这样,可以在不使用SQL甚至HQL的情况下进行数据查询。

  Hibernate提供了相当多的内置criterion类型(Restrictions子类),例如in、like、eq(相当于where条件查询)等,需要额外注意的是Restrictions.sqlRestriction(SQL限定的查询)

java
Restrictions.sqlRestriction(sql,value,type)
1.是String类型,是SQL语句的条件部分,
2.参数是参数值,
3.参数是类型.

  同样的,若第一个参数使用拼接的方式进行交互的话,会存在SQL注入风险的。举个例子:

java
List<User> resSql = criteria.add(Restrictions.sqlRestriction("id="+query)).list();
for (User user:resSql) {
System.out.println(user.toString());
}

  query是我们用户输入,可以在log打印对应的sql语句,可以看到,倘若我们输入恶意的sql注入payload的话,是可以成功执行的:

Java代码审计之SQL注入——Hibernate框架

SQLQuery本地SQL查询

  Hibernate对原生SQL查询的支持和控制是通过SQLQuery接口实现的,这种方式弥补了HQL、Criterion查询的不足,其直接使用sql语句进行查询,在操作和使用上往往更加的自由和灵活,如果使用得当,数据库操作的效率还会得到不同程度的提升。一般复杂的sql都会用到它。

  同样的,只要存在sql拼接,就会存在注入问题:

java
SQLQuery<User> sqlQuery = session.createSQLQuery("select * from User where Name='"+query+"'").addEntity(User.class);

  同时因为其直接操作sql,与常见的SQL注入无异,没有特殊的限制。

  PS:新版本hibernate已经弃用createSQLQuery(),可使用createNativeQuery()代替。

  综上,其实Hibernate框架下的注入挖掘主要还是查看拼接。

Hibernate框架下SQL注入漏洞修复

  主要方式是名称绑定,位置绑定(参数化查询)。下面是具体实例:

HQL查询

  • 名称绑定:

java
List<User> res =(List<User>)session.createQuery("select u from User u where name like :name").setParameter("name", "%"+sqlString).list();

  • 位置绑定:

java
Query<User> query = session.createQuery("from User where Name=?");
//HQL是从0开始的
query.setParameter(0, "tkswifty");

  Hibernate 4.1之后对于HQL中查询参数的占位符做了改进:

java
Query<User> query = session.createQuery("from User where Name=?0");
query.setString(0,name);

Criterion查询

  对于Restrictions.sqlRestriction的情况,应该使用预编译的方式进行SQL查询:

java
List<User> resSql = criteria.add(Restrictions.sqlRestriction("name=?",query,StandardBasicTypes.STRING)).list();

  同时,在mybatis中提到的例如in、like等查询方式,Criterion查询可以很好的解决预编译的问题:

  • Like

java
Criteria criteria = session.createCriteria(User.class);
List<User> resLike = criteria.add(Restrictions.like("name", "%test")).list();

  打印log看出交互过程,可以看到熟悉的占位符?:

Java代码审计之SQL注入——Hibernate框架
* in

java
Criteria criteria = session.createCriteria(User.class);
List<User> resIn = criteria.add(Restrictions.in("name", new String[] {"test"})).list();

Java代码审计之SQL注入——Hibernate框架

SQLQuery本地SQL查询

  使用占位符预编译方式:

java
SQLQuery<User> sqlQuery = session.createSQLQuery("select * from User where Name=?0").addEntity(User.class);
sqlQuery.setParameter(0, query);

  打印log看出交互过程,可以看到熟悉的占位符?:

Java代码审计之SQL注入——Hibernate框架

其他

  虽然参数化查询是防止SQL注入最便捷有效的一种方式,但是其无法应用于所有场景。当使用执行前不可被占位符?替代的不可信数据来动态构建SQL语句时,必须要对不可信数据进行校验,举个例子:

java
Code oe = new OracleCodec();
String safeExpr = ESAPI.encoder().encodeForSQL(oe, exprString);

  同样的,类似过滤器filter同样的也安全防护措施审计中不可缺少的一环。

相关推荐: 月饼计划之XSS

计划制定 2020年9月的某一天,天朗气清,惠风和畅。我默默打开日历,打算看下今日运势,宜划水、聊天、睡觉。与我努力奋斗积极向上的性格不合。正在我沉思之时,突然收到一条消息:中秋来临,各大SRC送月饼了!还有一张一积分换月饼的截图。 SRC?中秋?月饼?送?本…

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年5月6日18:29:25
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Java代码审计之SQL注入——Hibernate框架http://cn-sec.com/archives/246339.html