HQL注入(Hibernate框架)
Hibernate是一种ORM框架,它是支持使用原生SQL或HQL语言(Hibernate框架自己的语言)进行SQL操作的
通常使用Hibernate框架都是使用HQL语言方式进行查询
1、原生SQL语句
|
|
2、HQL语句
将数据库tables映射为相关的类,通过此类进行数据查询,使用的是HQL自己的语言
|
|
1、Hibernate框架首先会去解析createQuery()函数中语句是否符合HQL语法,不符合则会HQL语法错误
2、符合HQL语法后,HQL框架会将语句解析成对应数据库的原生SQL语句
3、最后将原生SQL语句去数据库中进行查询获取结果,此时原生SQL语句如果不正确则会导致数据库层面的报错(不同数据库则是不同的报错了)
|
|
简单HQL层面注入
union查询在5.6.15版本之前不支持
|
|
6.x版本开始支持union查询,但是也只能利用HQL语法
|
|
不能使用单行注释#
或+--+
|
|
不支持*
查询
|
|
怎么查询:
1、如果有报错信息的话,那就根据报错回显去看表名、列名,根据表名进行盲注或报错注入查询数据。或者根据回显去猜测可能存在的表名和列名,然后进行查询数据
2、如果没有报错信息的话
使用and或or进行列名的枚举
|
|
使用子查询进行表名枚举
|
|
HQL
注入的常见类型可以总结为两种:布尔盲注和报错注入。
HQL注入需要两次or
逃逸HQL层面注入
低于5.x版本逃逸
1、在5.6.15之前,WHERE子句中是可以使用用户自定义函数的,这就说明数据库本身的函数也是可以使用的
|
|
2、在5.6.15版本之前,存在着对单引号转义的差异导致的逃逸问题
在HQL语言,字符串和常规SQL语句一样都是使用单引号包裹
|
|
引擎是不会对字符串里面的内容进行解析的
当在字符串中加入一个转译字符
|
|
HQL引擎是不识别转译字符\
的,它会将tony\
作为一个字符串,原封不动的转为mysql语句
此处就导致了一个差异,mysql是识别转译字符的,所以爆了语法错误
然后利用这个差异,构造一个HQL以为是字符串,但转为mysql变成语句的POC即可
|
|
拼接HQL语句,此时mysql\''and+1=2+union+select+user(),version()#
是一整个字符串,所以引擎不去解析
|
|
转为sql语句,这样就在低于5.x的版本实现用union进行注入
高于6.x 版本逃逸
1、从6.0.1.Final版本开始,测试发现转译符\
失效
所以无法用\来逃逸
2、在6.x版本中发现新增了一个sql()函数,在5.x版本是不支持的
意思就是可以执行SQL语句,主要是两种方式
|
|
1、第一种是将函数里面的字符串直接拼接SQL语句中,然后去执行
2、第二种就是将后面参数预编译替换占位符?
,然后再拼接到SQL语句中执行
|
|
通用版本逃逸
有一个函数在5.x和6.x都能使用,那就是JPQL语言的function()
函数
在Hibernate框架中是同时支持JPQL语言和HQL语言的
function()
函数是用来调用自定义函数或数据库自带函数的,和某些动态函数调用差不多吧
|
|
它首先将第一参数作为函数名,随后拼接一个括号,后面的参数则是括号里的内容
而function()
函数的利用和sql()
函数一样,是直接拼接在解析后的SQL语句中的,而且第一参数的内容没有任何限制
这样就可以构造一个可利用POC了
|
|