In questo articolo vorrei dimostrare quanto sia facile ottenere informazioni riservate da un’applicazione web che… beh, non presta molta attenzione alla sicurezza. Quello con cui lavorerò è un’applicazione Java di esempio che ho creato in Spring Boot a scopo dimostrativo. Ma gli attacchi eseguiti sono validi per qualsiasi altro linguaggio di programmazione o framework. Alcune vulnerabilità e problemi di sicurezza che verranno dimostrati includono:
- SQL Injection
- Esposizione ai dati sensibili
- Registrazione insufficiente
- Autenticazione interrotta
La configurazione
Lavoreremo con un’applicazione web fittizia che consente di accedere come utente che fa parte di un gruppo. In base al ruolo dell’utente, può visualizzare i dati di base o riservati. In questo caso, vedrai un elenco di dipendenti in un’azienda, il loro stato, ecc.
Puoi trovare le fonti di questa applicazione nel mio Github: https://github.com/rapasoft/hackme.
Attacco #1: Man in the middle attack
Immagina di essere seduto in un ristorante e vorresti controllare qualcosa nell’applicazione sopra. Ti connetti al Wi-Fi del ristorante, apri la pagina di accesso, inserisci le credenziali e ottieni le informazioni che desideri (ad esempio l’elenco di dipendenti specifici). Quello che non si potrebbe ora, è che le credenziali sono state compromesse. Esaminiamo attentamente la pagina di accesso:
Questa applicazione non utilizza SSL/TLS (ad esempio nessuna connessione https://
). Ciò significa che tutte le informazioni inviate possono essere visualizzate come testo normale da chiunque abbia accesso alla comunicazione tra il client e il server.
Questo è esattamente ciò che sta accadendo nel cosiddetto attacco Man in the middle. Più specificamente, in questo caso ARP spoofing è stato utilizzato come un modo per avvelenare tutta la rete in modo che attaccante è a conoscenza di tutto ciò che accade e può annusare su tutti i pacchetti. Non ho intenzione di entrare nei dettagli su come funziona lo spoofing ARP, ma lo dimostrerò in questo video:
potrebbe essere necessario aprire questo video di Youtube in una nuova finestra e schermo intero per vedere più dettagli
Quello che potete vedere qui sopra, è che ho iniziato Ettercap, che è una suite completa per gli attacchi MITM, ed eseguito ARP spoofing nella mia rete locale. Nel frattempo, quando l’utente (me via iPad) inserisce le credenziali, sono visibili sia in Ettercap che in Wireshark (strumento per l’analisi del traffico di rete).
Attacco #2: SQL Injection
Continuando il nostro ruolo di attaccante di questa applicazione, ora abbiamo le credenziali per l’utente hgraves
con password P4SSW0RD
. Si può vedere che non solo questa applicazione non utilizza TLS, ha una politica di password molto debole che consente agli utenti di scegliere password davvero terribili.
Accediamo utilizzando le credenziali sopra e possiamo vedere un campo di input con l’opzione per cercare l’elenco delle persone. Quando si preme Search
otterremo l’elenco completo delle persone. Se mettiamo ” Fra ” per esempio otterremo risultati filtrati in base alla ricerca. E se ci mettessimo un personaggio illegale? È ovvio che c’è un database dietro questa applicazione, quindi proviamo il carattere '
:
Non solo ha fallito, ma possiamo vedere che la richiesta POST
ha fallito con un messaggio di errore molto specifico che espone la struttura dell’intera istruzione SQL. Possiamo vedere che WHERE P.NAME LIKE '%'%'
è usato alla fine.
Hacker esperto non ha bisogno di più. La regolazione della stringa di ricerca può dopo pochi tentativi produrre questi risultati:
L’iniezione in questo caso ha creato unione per selezionare l’istruzione che recupera nomi utente e password insieme al loro ruolo. Non solo questo ha avuto successo, siamo riusciti a visualizzarlo nell’applicazione client originale.
Ora abbiamo le credenziali di tutti gli utenti e i loro ruoli (visualizzati dal numero intero nella colonna “Età”). Se hframe
ha il ruolo 1, rgraves
deve quindi essere un utente più importante con il ruolo 3.
Attacco #3: Attaccare password debolmente hash
Abbiamo imparato nel primo attacco, che probabilmente non c’è alcuna politica di password impostata per questa applicazione. Questo ci darebbe la speranza che rgraves
non presti troppa attenzione alla sicurezza.
Il modo più semplice per crack hash di password che utilizza algoritmo di hash insufficiente (come MD5 in questo caso) è quello di eseguire dizionario o rainbow table attack. Ci sono molte possibilità, ma la più semplice è quella di utilizzare i servizi Internet che hanno già un ampio database di combinazioni da password a hash:
Il primo è
hframe
, il secondo èrgraves
.smorgan
sembra utilizzare password più forti di altre, dal momento che non è nel dizionario.
Puoi vedere che la password per rgraves
è swordfish, il che significa che ora non è importante scegliere la password non del dizionario ;). Ora, nulla ci impedisce di accedere come utente e scoprire la sezione “admin” e le informazioni riservate:
Non leggere questo se sei tedesco 🙂
Come risolvere questo problema?
Si potrebbe dire che tutto questo potrebbe essere facilmente prevenuto. Si potrebbe dire che questi erano errori rookie. Bene, questo potrebbe essere vero, ma ciò che è anche vero è che il progetto Open Web Application Security elenca Injection come vulnerabilità #1 nelle applicazioni Web (ed è stato così per diversi anni).
Quindi, se ti sei trovato a chiederti come prevenire tutto questo, ricapitoliamo:
- Usa sempre SSL / TLS quando invii qualcosa al server. Non deve essere credenziali, è attualmente considerato come buona pratica in generale. Anche se non hai alcun input sulla tua pagina! Il modo più semplice è fornire certificati tramite servizi come Let’s Encrypt.
- Ricorda che i certificati autofirmati potrebbero mitigare il problema dell’esposizione dei dati, ma non impediscono all’attaccante MITM di falsificare l’intero sito con il proprio certificato autofirmato del tutto.
- Quando si ha a che fare con le query SQL, si evitano sempre i parametri ottenuti dal client. Il modo più semplice per farlo è usare le funzionalità del tuo framework, ad esempio in primavera puoi usare NamedParameterJdbcTemplate che è buono anche per la leggibilità.
- Essere paranoico. Convalidare qualsiasi input dell’utente. Ancora una volta nel mondo Java/Spring è possibile aggiungere regole di convalida utilizzando
JSR-380
implementazione di convalida bean come Hibernate validator e annotare i parametri, ad esempio@Pattern(regexp = "*") String name
impedirebbe l’inserimento di'
. - Registra qualsiasi tentativo di passare input non valido nell’applicazione. Inoltre, in caso di errore non esporre alcuna informazione specifica per l’implementazione al client.
- Migliora la tua autenticazione.
- Se possibile utilizzare almeno l’autenticazione a 2 fattori.
- Non implementare algoritmi di archiviazione password o crittografia personalizzati. È estremamente difficile da fare da solo e sicuramente fallirai. Ci sono soluzioni collaudate come BCrypt.
- Leggi e segnalibro OWASP TOP 10. Inizia con lì e poi passare attraverso la loro lista di best practice.