SQL Injection su richiesta POST JSON

0

Ho un'applicazione Web vulnerabile alle iniezioni SQL. Sto usando BurpSuite per intercettare le richieste. Più specificamente, la seguente variabile di dati è vulnerabile. Ho aggiunto i miei dati agli aggregati e ai filtri:

data=[{
   "params": {
     "dsreq": "{
         \"version\":1,
         \"type\":\"SQL\",
         \"limit\":500, 
         \"aggregates\":[
             {\"expr\":\"user()\"}
         ],
         \"partitions\":[],
         \"filters\":[\" 1=1 --\"],
         \"having\":[],
         \"dataset_id\":3}"
         }
     }
   ]

Questo payload restituisce la seguente istruzione SQL:

SELECT 'portal' user() FROM active_tab tab_0 WHERE (TRUE) AND ((TA_0.grp_id) = 'sqlgrp1')

La chiave di aggregazione in JSON corrisponde alla sezione colonne dell'istruzione SQL e i filtri corrispondono alla condizione.

Questo recupera alcuni dati dal DB, ma restituisce solo i dati dal mio gruppo. Si noti come la clausola where includa "TRUE" (la mia istruzione 1 = 1), ma poi la parentesi dell'applicazione aggiunta attorno ad essa e un'istruzione AND aggiuntiva. Il mio obiettivo è quello di aggirare il problema in modo da poter ottenere dati da tutti i gruppi. L'ID del mio gruppo è sqlgrp1.

Come posso ingannare il filtro per interrompere l'esecuzione della clausola WHERE dopo la condizione TRUE o addirittura non eseguire la clausola WHERE? Dove viene aggiunta la condizione se la chiave dei filtri è vuota.

    
posta Hernan Duran 13.08.2018 - 17:20
fonte

3 risposte

3

Sto solo ripetendo ciò che @YourCommonSense ha detto in un commento, ma in ogni caso:

Non c'è nulla qui a suggerire che esiste una vulnerabilità SQLi. Ho costruito sistemi come questo che funzionano in modo molto simile: hanno un input JSON molto espressivo che consente al client di avere un controllo più preciso sulla query. Questo può essere vantaggioso perché dà al cliente più controllo senza dover regolare il server per ogni singolo caso d'uso. Questo sicuramente non significa che esiste una vulnerabilità SQLi. Ad esempio, nei miei sistemi ogni endpoint API (in questo caso dataset potrebbe essere l'equivalente) è esplicitamente legato a una tabella e condizioni aggiuntive specificate sul lato server che sono sempre aggiunte a la domanda. Eventuali filtri aggiuntivi passati dal client sono esplicitamente uniti con l'operatore AND mentre l'operatore OR non può essere utilizzato affatto. Inoltre, tutte le condizioni lato client sono esplicitamente in white list: al client è consentito filtrare solo tramite un elenco predefinito di colonne e specificare che l'operatore non è consentito: è possibile specificare solo il valore di ricerca (la colonna stessa determina esplicitamente quale operatore è usato nella query reale). Infine, tutto è incorporato in una query che utilizza query preparate per l'esecuzione effettiva. Tutto ciò rende quasi impossibile avere una vulnerabilità SQLi, pur consentendo al client un controllo più preciso sui risultati effettivi dell'API. Dico questo per non parlare del mio sistema, ma perché quello che ho creato sembra quasi esattamente quello che hai, e i risultati che mostri sono esattamente ciò che vedresti anche con il mio sistema. In particolare:

  1. Sembra che tu abbia concluso che la parte WHERE (true) di quella query è il risultato dell'iniezione 1=1 . Questo probabilmente non è il caso. Fare in modo che un parser riconosca la condizione 1=1 e tradurlo automaticamente in true sarebbe molto lavoro e non ha senso - qualcosa come 1=1 verrebbe visualizzato solo a causa di SQLi, quindi non posso immaginare che sarebbe il comportamento desiderato di qualsiasi sistema. La migliore ipotesi è che la parte (vera) venga aggiunta automaticamente alla query in tutti i casi per semplificare la creazione della query (non è necessario tenere traccia del fatto che tu abbia o meno già una condizione e quindi se tu o no tu devi mettere AND davanti alla condizione che stai aggiungendo) eb) MySQL lo ignorerà comunque quando costruisce il piano di query, quindi avrà un impatto quasi nullo sulle prestazioni.
  2. Il fatto che il tuo commento non sia stato mostrato nella query finale suggerisce che il sistema ha analizzato la tua condizione e l'ha completamente respinta. Di nuovo, la tua condizione viene ovviamente elaborata dal sistema e non viene semplicemente aggiunta direttamente alla fine (quindi perché il tuo commento non è nella query finale), e non ci sarebbe alcun motivo per un parser di riconoscere il tuo commento e rimuoverlo - quelli solo si presentano a causa delle vulnerabilità di SQLi, quindi qualsiasi sistema abbastanza intelligente da analizzare un commento e rimuoverlo dovrebbe (in teoria) essere abbastanza intelligente da riconoscere il pericolo di SQLi e rifiutare la richiesta tutti insieme.
  3. La condizione su grp_id esiste anche se non l'hai specificata. Questo è probabilmente un segnale che questo particolare endpoint dell'API (o dataset_id ?) Aggiunge automaticamente condizioni che non sarai in grado di rimuovere.
  4. Sembra guarda come se avessi ottenuto user() nella selezione, ma è difficile dire quale (se mai) è il significato di tale fatto.

Quindi direi che senza ulteriori dettagli non c'è molto da fare, ma da qui non sembra particolarmente vulnerabile.

    
risposta data 13.08.2018 - 18:13
fonte
0

Supponendo che il valore di filters sia direttamente giuntato nell'istruzione SQL dopo (TRUE - cioè prima della parentesi di chiusura ....

\"filters\":[\" 1=1 --\ ) UNION SELECT 'portal' user() FROM active_tab tab_0 WHERE ("],

Rivelerebbe tutti i gruppi. Se è stato giuntato da qualche altra parte, potrebbe essere necessario spostare le parentesi un po '. Ma l'assenza del valore nel tuo esempio JSON-in-JSON dal tuo SQL di esempio, e la mancanza di altri esempi ti pone molti dubbi su questo.

    
risposta data 13.08.2018 - 18:38
fonte
0

La richiesta dannosa deve essere impedita per raggiungere il livello di persistenza della tua applicazione web. È necessario applicare quanto segue per proteggere la propria applicazione da dati dannosi provenienti da fonti esterne.

  • Servizi igienici JSON a livello di controller.
  • Convalida dell'input per ciascun oggetto JSON.
  • Whitelist per i parametri sensibili (in particolare il filtro! non puoi fare 1 = 1 per raggiungere il livello di persistenza).

I 3 elencati sono solo la protezione minima che DEVE essere applicata a qualsiasi applicazione web. Prendete nota che non siete solo vulnerabili all'iniezione SQL, ma siete anche vulnerabili dallo scripting cross-site. Ti suggerisco di leggere il cheat di OWASP e la guida degli sviluppatori OWASP per fare la corretta codifica con la sicurezza in atto. Vedi sotto link.

link link

    
risposta data 14.08.2018 - 02:34
fonte

Leggi altre domande sui tag