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)
In questo post viene spiegato come sia possibile rendere vulnerabile un Django ORM utilizzando ad esempio un codice come:
Nota come tutti i request.data (che sarà un json) siano direttamente passati a filtrare oggetti dal database. Un attaccante potrebbe inviare filtri inaspettati per cercare di leakare più dati del previsto.
Esempi:
Login: In un semplice login prova a leakare le password degli utenti registrati al suo interno.
È possibile forzare la password fino a quando non viene leakata.
Filtraggio relazionale: È possibile attraversare le relazioni per leakare informazioni da colonne che non ci si aspettava nemmeno fossero utilizzate nell'operazione. Ad esempio, se è possibile leakare articoli creati da un utente con queste relazioni: Article(created_by
) -[1..1]-> Author (user
) -[1..1]-> User(password
).
È possibile trovare la password di tutti gli utenti che hanno creato un articolo
Filtraggio relazionale molti-a-molti: Nell'esempio precedente non siamo riusciti a trovare le password degli utenti che non hanno creato un articolo. Tuttavia, seguendo altre relazioni, questo è possibile. Ad esempio: Article(created_by
) -[1..1]-> Author(departments
) -[0..*]-> Department(employees
) -[0..*]-> Author(user
) -[1..1]-> User(password
).
In questo caso possiamo trovare tutti gli utenti nei dipartimenti degli utenti che hanno creato articoli e poi leakare le loro password (nel json precedente stiamo solo leakando i nomi utente ma poi è possibile leakare le password).
Abusare delle relazioni many-to-many di Django Group e Permission con gli utenti: Inoltre, il modello AbstractUser è utilizzato per generare utenti in Django e per impostazione predefinita questo modello ha alcune relazioni many-to-many con le tabelle Permission e Group. Che fondamentalmente è un modo predefinito per accedere ad altri utenti da un utente se si trovano nel stesso gruppo o condividono la stessa autorizzazione.
Bypassare le restrizioni del filtro: Lo stesso post del blog ha proposto di bypassare l'uso di alcuni filtri come articles = Article.objects.filter(is_secret=False, **request.data)
. È possibile estrarre articoli che hanno is_secret=True perché possiamo tornare indietro da una relazione alla tabella Article e leakare articoli segreti da articoli non segreti poiché i risultati sono uniti e il campo is_secret viene controllato nell'articolo non segreto mentre i dati vengono leakati dall'articolo segreto.
Abusando delle relazioni è possibile bypassare anche i filtri destinati a proteggere i dati mostrati.
Error/Time based via ReDoS: Negli esempi precedenti ci si aspettava di avere risposte diverse se il filtraggio funzionava o meno per usarlo come oracolo. Ma potrebbe essere possibile che venga eseguita un'azione nel database e la risposta sia sempre la stessa. In questo scenario potrebbe essere possibile provocare un errore nel database per ottenere un nuovo oracolo.
Dallo stesso post riguardo a questo vettore:
SQLite: Non ha un operatore regexp per impostazione predefinita (richiede il caricamento di un'estensione di terze parti)
PostgreSQL: Non ha un timeout regex predefinito ed è meno soggetto a backtracking
MariaDB: Non ha un timeout regex
I seguenti sono trucchi estratti da questo post.
Controllo completo della ricerca:
È possibile vedere che l'intero corpo javascript viene passato a prisma per eseguire query.
Nell'esempio del post originale, questo controllerebbe tutti i post creati da qualcuno (ogni post è creato da qualcuno) restituendo anche le informazioni dell'utente di quel qualcuno (nome utente, password...)
Controllo completo della clausola where:
Diamo un'occhiata a questo dove l'attacco può controllare la clausola where
:
È possibile filtrare direttamente la password degli utenti come:
Utilizzando operazioni come startsWith
è possibile leakare informazioni.
Bypass del filtraggio relazionale molti-a-molti:
È possibile leak articoli non pubblicati tornando alle relazioni molti-a-molti tra Category
-[*..*]-> Article
:
È anche possibile leak tutti gli utenti abusando di alcune relazioni many-to-many a loop back:
Error/Timed queries: Nel post originale puoi leggere un insieme molto esteso di test eseguiti per trovare il payload ottimale per leakare informazioni con un payload basato sul tempo. Questo è:
Dove {CONTAINS_LIST}
è un elenco con 1000 stringhe per assicurarsi che la risposta sia ritardata quando viene trovata la corretta leak.
Questi trucchi sono stati trovati in questo post.
Nota che Ransack 4.0.0.0 ora impone l'uso di un elenco di autorizzazione esplicito per gli attributi e le associazioni ricercabili.
Esempio vulnerabile:
Nota come la query sarà definita dai parametri inviati dall'attaccante. È stato possibile, ad esempio, forzare il token di reset con:
Forzando e potenzialmente relazioni, è stato possibile leakare più dati da un database.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)