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)
W tym poście wyjaśniono, jak można uczynić Django ORM podatnym, używając na przykład kodu takiego jak:
Zauważ, jak wszystkie request.data (które będą w formacie json) są bezpośrednio przekazywane do filtrów obiektów z bazy danych. Atakujący mógłby wysłać nieoczekiwane filtry, aby wyciekło więcej danych, niż się spodziewano.
Przykłady:
Logowanie: W prostym logowaniu spróbuj wyciekować hasła użytkowników zarejestrowanych w systemie.
Możliwe jest przeprowadzenie ataku brute-force na hasło, aż zostanie ujawnione.
Filtracja relacyjna: Możliwe jest przeszukiwanie relacji w celu ujawnienia informacji z kolumn, które nie były nawet oczekiwane w operacji. Na przykład, jeśli możliwe jest ujawnienie artykułów stworzonych przez użytkownika z tymi relacjami: Article(created_by
) -[1..1]-> Author (user
) -[1..1]-> User(password
).
Możliwe jest znalezienie hasła wszystkich użytkowników, którzy stworzyli artykuł
Filtrowanie relacji wiele-do-wielu: W poprzednim przykładzie nie mogliśmy znaleźć haseł użytkowników, którzy nie stworzyli artykułu. Jednakże, podążając za innymi relacjami, jest to możliwe. Na przykład: Article(created_by
) -[1..1]-> Author(departments
) -[0..*]-> Department(employees
) -[0..*]-> Author(user
) -[1..1]-> User(password
).
W tym przypadku możemy znaleźć wszystkich użytkowników w działach użytkowników, którzy stworzyli artykuły, a następnie wyciekować ich hasła (w poprzednim jsonie wyciekamy tylko nazwy użytkowników, ale później możliwe jest wycieknięcie haseł).
Wykorzystywanie relacji wiele-do-wielu między grupami a uprawnieniami w Django: Co więcej, model AbstractUser jest używany do generowania użytkowników w Django i domyślnie model ten ma pewne relacje wiele-do-wielu z tabelami Permission i Group. Co zasadniczo jest domyślnym sposobem dostępu do innych użytkowników z jednego użytkownika, jeśli są w tej samej grupie lub dzielą te same uprawnienia.
Obejście ograniczeń filtrów: Ten sam post na blogu zaproponował obejście użycia niektórych filtrów, takich jak articles = Article.objects.filter(is_secret=False, **request.data)
. Możliwe jest zrzucenie artykułów, które mają is_secret=True, ponieważ możemy wrócić z relacji do tabeli Article i wyciekować sekretnych artykułów z niesekretnych artykułów, ponieważ wyniki są łączone, a pole is_secret jest sprawdzane w niesekretnym artykule, podczas gdy dane są wyciekane z sekretnym artykułem.
Wykorzystując relacje, możliwe jest ominięcie nawet filtrów mających na celu ochronę wyświetlanych danych.
Błąd/Czas oparty na ReDoS: W poprzednich przykładach oczekiwano różnych odpowiedzi, jeśli filtracja działała lub nie, aby użyć tego jako oracle. Ale może się zdarzyć, że jakaś akcja jest wykonywana w bazie danych i odpowiedź jest zawsze taka sama. W tym scenariuszu możliwe byłoby wywołanie błędu w bazie danych, aby uzyskać nowy oracle.
From te same post regarding this vector:
SQLite: Domyślnie nie ma operatora regexp (wymaga załadowania rozszerzenia firm trzecich)
PostgreSQL: Nie ma domyślnego limitu czasu regex i jest mniej podatny na backtracking
MariaDB: Nie ma limitu czasu regex
The following are tricks extracted from this post.
Full find control:
It's possible to see that the whole javascript body is passed to prisma to perform queries.
In the example from the original post, this would check all the posts createdBy someone (each post is created by someone) returning also the user info of that someone (username, password...)
Pełna kontrola nad klauzulą where:
Przyjrzyjmy się temu, gdzie atak może kontrolować klauzulę where
:
Możliwe jest bezpośrednie filtrowanie haseł użytkowników, jak:
Używając operacji takich jak startsWith
, możliwe jest wycieknięcie informacji.
Obchodzenie filtrowania w relacjach wiele-do-wielu:
Możliwe jest wycieknięcie nieopublikowanych artykułów poprzez powracanie do relacji wiele-do-wielu między Category
-[*..*]-> Article
:
Możliwe jest również wycieknięcie wszystkich użytkowników, nadużywając niektórych relacji wiele-do-wielu z pętlą:
Błędy/Zapytania czasowe: W oryginalnym poście można przeczytać bardzo obszerny zestaw testów przeprowadzonych w celu znalezienia optymalnego ładunku do wycieku informacji za pomocą ładunku opartego na czasie. To jest:
Gdzie {CONTAINS_LIST}
to lista z 1000 ciągami, aby upewnić się, że odpowiedź jest opóźniona, gdy zostanie znaleziony poprawny leak.
Te sztuczki zostały znalezione w tym poście.
Zauważ, że Ransack 4.0.0.0 teraz wymusza użycie jawnej listy dozwolonych atrybutów i powiązań do przeszukiwania.
Przykład podatny:
Zauważ, jak zapytanie będzie definiowane przez parametry wysyłane przez atakującego. Możliwe było na przykład przeprowadzenie brute-force na tokenie resetującym za pomocą:
By brute-forcing i potencjalnie relacjami możliwe było wycieknięcie większej ilości danych z bazy danych.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)