ORM Injection
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Bu yazıda Django ORM'nin nasıl savunmasız hale getirilebileceği, örneğin aşağıdaki gibi bir kod kullanılarak açıklanmaktadır:
Tüm request.data'nın (bu bir json olacak) doğrudan veritabanından nesneleri filtrelemek için geçirildiğine dikkat edin. Bir saldırgan, beklenenden daha fazla veri sızdırmak için beklenmedik filtreler gönderebilir.
Örnekler:
Giriş: Basit bir girişte, içindeki kayıtlı kullanıcıların şifrelerini sızdırmaya çalışın.
Şifreyi brute-force ile kırmak, sızdırılana kadar mümkündür.
İlişkisel filtreleme: İşlemde kullanılacağı bile beklenmeyen sütunlardan bilgi sızdırmak için ilişkileri geçmek mümkündür. Örneğin, bu ilişkilerle bir kullanıcı tarafından oluşturulan makaleleri sızdırmak mümkünse: Article(created_by
) -[1..1]-> Author (user
) -[1..1]-> User(password
).
Tüm makale oluşturmuş kullanıcıların şifrelerini bulmak mümkündür.
Çoktan çoğa ilişkisel filtreleme: Önceki örnekte, makale oluşturmamış kullanıcıların şifrelerini bulamadık. Ancak, diğer ilişkileri takip ederek bu mümkündür. Örneğin: Article(created_by
) -[1..1]-> Author(departments
) -[0..*]-> Department(employees
) -[0..*]-> Author(user
) -[1..1]-> User(password
).
Bu durumda, makaleler oluşturan kullanıcıların departmanlarındaki tüm kullanıcıları bulabiliriz ve ardından şifrelerini sızdırabiliriz (önceki json'da yalnızca kullanıcı adlarını sızdırıyoruz ama daha sonra şifreleri sızdırmak mümkün).
Kullanıcılarla Django Grup ve İzinleri çoktan çoğa ilişkilerini kötüye kullanma: Ayrıca, AbstractUser modeli Django'da kullanıcıları oluşturmak için kullanılır ve varsayılan olarak bu modelin İzin ve Grup tablolarıyla bazı çoktan çoğa ilişkileri vardır. Bu, temelde aynı grupta bulunan veya aynı izni paylaşan bir kullanıcıdan diğer kullanıcılara erişmenin varsayılan yoludur.
Filtre kısıtlamalarını atlama: Aynı blog yazısı, articles = Article.objects.filter(is_secret=False, **request.data)
gibi bazı filtrelerin kullanımını atlamayı önerdi. is_secret=True olan makaleleri dökme olanağı vardır çünkü bir ilişkiden Article tablosuna geri dönebiliriz ve gizli makaleleri gizli olmayan makalelerden sızdırabiliriz çünkü sonuçlar birleştirilmiştir ve is_secret alanı gizli olmayan makalede kontrol edilirken veri gizli makaleden sızdırılmaktadır.
İlişkileri kötüye kullanarak, gösterilen verileri korumak için tasarlanmış filtreleri bile atlatmak mümkündür.
Hata/Zaman tabanlı ReDoS ile: Önceki örneklerde, filtrelemenin çalışıp çalışmadığına göre farklı yanıtlar alınması bekleniyordu ve bunun bir oracle olarak kullanılması amaçlanıyordu. Ancak, veritabanında bazı işlemler yapıldığında yanıtın her zaman aynı olması mümkün olabilir. Bu senaryoda, yeni bir oracle elde etmek için veritabanı hatası oluşturmak mümkün olabilir.
SQLite: Varsayılan olarak bir regexp operatörü yoktur (üçüncü taraf bir uzantının yüklenmesi gerekir)
PostgreSQL: Varsayılan bir regex zaman aşımı yoktur ve geri izlemeye daha az eğilimlidir
MariaDB: Bir regex zaman aşımı yoktur
Aşağıdakiler bu yazıdan çıkarılan ipuçlarıdır.
Tam bulma kontrolü:
Tüm javascript gövdesinin sorgular gerçekleştirmek için prisma'ya geçirildiği görülebilir.
Orijinal yazıdaki örnekte, bu, birisi tarafından oluşturulan tüm gönderileri kontrol eder (her gönderi birisi tarafından oluşturulur) ve ayrıca o kişinin kullanıcı bilgilerini (kullanıcı adı, şifre...) döndürür.
Aşağıdaki, bir şifreye sahip olan birinin oluşturduğu tüm gönderileri seçer ve şifreyi döndürecektir:
Tam where koşulu kontrolü:
Saldırının where
koşulunu kontrol edebileceği bu duruma bir göz atalım:
Kullanıcıların şifrelerini doğrudan şu şekilde filtrelemek mümkündür:
startsWith
gibi işlemler kullanarak bilgi sızdırmak mümkündür.
Çoktan çoğa ilişkisel filtreleme ile filtrelemeyi atlama:
Category
-[*..*]-> Article
arasındaki çoktan çoğa ilişkileri geri döndürerek yayımlanmamış makaleleri sızdırmak mümkündür:
Aynı zamanda bazı döngüsel çoktan çoğa ilişkileri kötüye kullanarak tüm kullanıcıları sızdırmak da mümkündür:
Hata/Zamanlı sorgular: Orijinal yazıda, zaman tabanlı bir yük ile bilgi sızdırmak için optimal yükü bulmak amacıyla gerçekleştirilen çok kapsamlı bir test setini okuyabilirsiniz. Bu şudur:
Where the {CONTAINS_LIST}
is a list with 1000 strings to make sure the yanıtın doğru leak bulunduğunda geciktiğinden emin olmak için.
These tricks where found in this post.
Ransack 4.0.0.0'ın artık aranabilir nitelikler ve ilişkiler için açık bir izin listesi kullanımını zorunlu kıldığını unutmayın.
Vulnerable example:
Not edin ki sorgu, saldırgan tarafından gönderilen parametreler ile tanımlanacaktır. Örneğin, sıfırlama token'ını brute-force yapmak mümkün oldu:
Brute-forcing ve potansiyel ilişkiler ile bir veritabanından daha fazla veri sızdırmak mümkündü.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)