Qual è la migliore contromisura della forza bruta distribuita?


151

Innanzitutto, un piccolo retroscena: non è un segreto che sto implementando un sistema auth + auth per CodeIgniter, e finora sto vincendo (per così dire). Ma ho incontrato una sfida piuttosto banale (una delle quali la maggior parte delle librerie di autenticazione manca del tutto, ma insisto per gestirla correttamente): come gestire in modo intelligente attacchi su larga scala, distribuiti, con nome utente variabile e forza bruta .

Conosco tutti i soliti trucchi:

  1. Limitare il numero di tentativi falliti per IP / host e negare l'accesso ai trasgressori (ad es. Fail2Ban) - che non funziona più da quando le botnet sono diventate più intelligenti
  2. Combinando quanto sopra con una lista nera di IP / host "cattivi" noti (ad esempio DenyHosts) - che si basa sul fatto che le botnet cadano per il n. 1, che sempre più non fanno
  3. Whitelist IP / host combinate con l'autenticazione tradizionale (purtroppo inutile con utenti IP dinamici e l'elevata abbandono della maggior parte dei siti Web)
  4. Impostare un limite a livello di sito sul numero di tentativi falliti entro un periodo di N minuti / ora e limitare (sospendere) tutti i tentativi di accesso successivi per un numero di minuti / ore (con il problema che DoS ti attacca diventa un gioco da ragazzi botnet)
  5. Firme digitali obbligatorie (certificati a chiave pubblica) o token hardware RSA per tutti gli utenti senza opzione login / password (senza dubbio una soluzione solida, ma pratica solo per servizi chiusi e dedicati)
  6. Forzate schemi di password ultra-forti (ad esempio> 25 caratteri senza senso con simboli - ancora una volta, troppo poco pratico per gli utenti occasionali)
  7. E, infine, CAPTCHAs (che potrebbe funzionare nella maggior parte dei casi, ma sono fastidiosi per gli utenti e praticamente inutili contro un aggressore determinato e pieno di risorse )

Ora, queste sono solo idee teoricamente realizzabili. Ci sono molte idee sulla spazzatura che spalancano il sito (ad es. Per insignificanti attacchi DoS). Quello che voglio è qualcosa di meglio. E meglio, intendo:

  • Deve essere sicuro (+) contro DoS e attacchi di forza bruta e non introdurre nuove vulnerabilità che potrebbero consentire a un bot leggermente più subdolo di continuare a operare sotto il radar

  • Deve essere automatizzato. Se richiede un operatore umano per verificare ogni accesso o monitorare attività sospette, non funzionerà in uno scenario del mondo reale

  • Deve essere fattibile per l'uso corrente del web (es. Alto churn, alto volume e registrazione aperta che può essere eseguita da non programmatori)

  • Non può ostacolare l'esperienza dell'utente al punto in cui gli utenti occasionali saranno infastiditi o frustrati (e potenzialmente abbandoneranno il sito)

  • Non può coinvolgere i cuccioli, a meno che non siano cuccioli veramente sicuri

(+) Per "sicuro" intendo almeno sicuro quanto la capacità di un utente paranoico di mantenere segreta la sua password

Quindi, ascoltiamolo! Come lo faresti ? Conosci una best practice che non ho menzionato (oh, per favore, dì che lo fai)? Ammetto di avere un'idea mia (che combina idee da 3 e 4), ma lascerò che i veri esperti parlino prima di mettermi in imbarazzo ;-)

Risposte:


68

Va bene, abbastanza stallo; ecco cosa ho escogitato finora

(scusa, post lungo avanti. Sii coraggioso, amico, il viaggio ne varrà la pena)

Combinando i metodi 3 e 4 dal post originale in una specie di whitelist 'fuzzy' o dinamica, e quindi - ed ecco il trucco - non bloccare gli IP non autorizzati, limitandoli all'inferno e viceversa .

Nota che questa misura ha il solo scopo di contrastare questo specifico tipo di attacco. In pratica, ovviamente, funzionerebbe in combinazione con altri approcci di best practice per l'authoring: limitazione del nome utente fisso, limitazione per-IP, politica di password complessa con codice, accesso con cookie non limitato, hashing di tutti gli equivalenti di password prima di salvarli, mai usando domande di sicurezza, ecc.

Ipotesi sullo scenario di attacco

Se un utente malintenzionato prende di mira nomi utente variabili, la limitazione del nostro nome utente non viene attivata. Se l'attaccante sta utilizzando una botnet o ha accesso a un ampio intervallo IP, la nostra limitazione IP è impotente. Se l'attaccante ha pre-cancellato il nostro elenco di utenti (di solito possibile sui servizi Web a registrazione aperta), non possiamo rilevare un attacco in corso in base al numero di errori "utente non trovato". E se imponiamo una limitazione restrittiva a livello di sistema (tutti i nomi utente, tutti gli IP), tale attacco farà il nostro intero sito per la durata dell'attacco più il periodo di limitazione.

Quindi dobbiamo fare qualcos'altro.

La prima parte della contromisura: whitelisting

Ciò di cui possiamo essere abbastanza sicuri è che l'attaccante non è in grado di rilevare e falsificare dinamicamente gli indirizzi IP di diverse migliaia di nostri utenti (+). Il che rende whitelisting possibile la . In altre parole: per ogni utente, memorizziamo un elenco degli IP (con hash) da cui l'utente ha effettuato (di recente) l'accesso.

Pertanto, il nostro schema di whitelisting funzionerà come una "porta d'ingresso" bloccata, in cui un utente deve essere connesso da uno dei suoi "buoni" IP riconosciuti per accedere a tutti. Un attacco di forza bruta su questa "porta d'ingresso" sarebbe praticamente impossibile (+).

(+) a meno che l'attaccante "possieda" il server, tutte le caselle dei nostri utenti o la connessione stessa - e in quei casi, non abbiamo più un problema di "autenticazione", abbiamo un vero pull-the in franchising -inserire la situazione FUBAR

La seconda parte della contromisura: limitazione a livello di sistema di IP non riconosciuti

Al fine di far funzionare una whitelist per un servizio Web a registrazione aperta, in cui gli utenti cambiano computer frequentemente e / o si connettono da indirizzi IP dinamici, è necessario mantenere una "porta di accesso" aperta agli utenti che si connettono da IP non riconosciuti. Il trucco è progettare quella porta in modo che le botnet rimangano bloccate e che gli utenti legittimi vengano infastiditi il meno possibile .

Nel mio schema, ciò si ottiene impostando un numero massimo molto restrittivo di tentativi di accesso non riusciti da parte di IP non approvati su, per esempio, un periodo di 3 ore (potrebbe essere più saggio utilizzare un periodo più breve o più lungo a seconda del tipo di servizio), e rendere globale tale restrizione , vale a dire. per tutti gli account utente.

Anche una forza bruta lenta (1-2 minuti tra i tentativi) verrebbe rilevata e contrastata rapidamente ed efficacemente usando questo metodo. Certo, davvero lento forza bruta potrebbe ancora rimanere inosservata, ma velocità troppo lente vanificano lo scopo stesso dell'attacco di forza bruta.

Ciò che spero di ottenere con questo meccanismo di limitazione è che se viene raggiunto il limite massimo, la nostra "porta per gatti" sbatte per un po ', ma la nostra porta d'ingresso rimane aperta agli utenti legittimi che si collegano con i soliti mezzi:

  • O connettendosi da uno dei loro IP riconosciuti
  • O utilizzando un cookie di accesso persistente (da qualsiasi luogo)

Gli unici utenti legittimi che sarebbero interessati durante un attacco, ad es. mentre era attiva la limitazione - sarebbero utenti senza cookie di accesso persistenti che effettuavano l'accesso da una posizione sconosciuta o con un IP dinamico. Tali utenti non sarebbero in grado di accedere fino a quando il throttling non si esaurisce (il che potrebbe richiedere del tempo, se l'attaccante ha mantenuto la sua botnet in esecuzione nonostante il throttling).

Per consentire a questo piccolo sottoinsieme di utenti di spremere attraverso la porta per gatti altrimenti sigillata, anche se i robot lo stavano ancora martellando, avrei impiegato un modulo di accesso di "backup" con un CAPTCHA. In modo che, quando visualizzi il messaggio "Siamo spiacenti, ma non puoi accedere da questo indirizzo IP al momento", includi un link che dice " accesso sicuro al backup - SOLO UMANI ( robot: non mentire ) ". Scherzo a parte, quando fanno clic su quel link, danno loro un modulo di accesso autenticato da reCAPTCHA che elude la limitazione a livello di sito. In questo modo, SE sono umani E conoscono il login + password corretti (e sono in grado di leggere i CAPTCHA), non potranno mai negato il servizio, anche se si stanno connettendo da un host sconosciuto e non stanno usando il cookie di accesso automatico.

Oh, e solo per chiarire: dal momento che considero i CAPTCHA generalmente malvagi, l'opzione di accesso 'backup' appare solo quando la limitazione era attiva .

Non si può negare che un attacco prolungato del genere costituirebbe comunque una forma di attacco DoS, ma con il sistema descritto in atto, influenzerebbe solo quello che sospetto sia un piccolo sottoinsieme di utenti, vale a dire le persone che non usano il cookie "ricordami" E accede mentre si sta verificando un attacco E non accede da nessuno dei loro IP abituali E che non sono in grado di leggere i CAPTCHA. Solo coloro che possono dire di no a TUTTI questi criteri - in particolare i robot e le persone disabili davvero sfortunate - saranno respinti durante un attacco bot.

EDIT: In realtà, ho pensato a un modo per consentire anche agli utenti sfidati di CAPTCHA di passare durante un 'blocco': invece di, o come supplemento al login CAPTCHA di backup, fornire all'utente un'opzione per avere un uso singolo , codice di blocco specifico dell'utente inviato alla sua e-mail, che può quindi utilizzare per ignorare la limitazione. Questo sicuramente supera la mia soglia del "fastidio", ma dato che è usato solo come ultima risorsa per un piccolo sottoinsieme di utenti e dato che batte ancora per essere bloccato fuori dal tuo account, sarebbe accettabile.

(Si noti inoltre che nulla di tutto ciò accade se l'attacco è meno sofisticato della cattiva versione distribuita che ho descritto qui. Se l'attacco proviene da pochi IP o colpisce solo pochi nomi utente, sarà contrastato molto prima e senza conseguenze a livello di sito)


Quindi, questa è la contromisura che implementerò nella mia libreria di autenticazione, una volta che sono convinto che sia corretto e che non ci sia una soluzione molto più semplice che mi è sfuggita. Il fatto è che ci sono così tanti modi sottili di fare cose sbagliate in termini di sicurezza, e non sto esagerando nel fare false assunzioni o logiche irrimediabilmente imperfette. Quindi, per favore, qualsiasi feedback, critica e miglioramento, sottigliezze ecc. Sono molto apprezzati.


1
Forse potresti generare una password "speciale" per ogni utente che potrebbe utilizzare se in modalità di blocco (e si stanno connettendo da un nuovo IP, ecc.), Quella password speciale è sufficientemente complicata da non poter essere forzata?
Douglas Leeder,

1
Potrebbe funzionare, ma solo se gli utenti ricordano quelle password anche se non le hanno mai usate prima (questi tipi di attacchi non sono comuni, e nessun botmaster degno del suo sale si preoccuperebbe di mantenerne uno in esecuzione a lungo dopo essere stato limitato). Il rischio è troppo grande che semplicemente non potevano ricordare.
Jens Roland,

1
Tuttavia, un metodo che potrebbe sicuramente funzionare è quello di fornire un link "inviami un codice di blocco" a quegli utenti, consentendo loro di ricevere un'e-mail contenente un token monouso specifico dell'utente che consentirebbe loro di accedere, ignorando il strozzamento.
Jens Roland,

1
@Abtin: buona idea, tranne che sarebbe "entrare nella corsa agli armamenti" - cioè. avviare un "chi può superare in astuzia chi" con le persone che creano elenchi di password per gli attacchi del dizionario. Penso che un modo migliore sarebbe quello di applicare una solida politica di password in modo che non ci siano password deboli
Jens Roland,

1
@OrestisP .: Ti manca il punto dell'attacco distribuito - il numero di tentativi non validi da ciascun IP è minimo, quindi il blocco per IP non può funzionare. Inoltre, la domanda descrive specificamente un attacco automatizzato di forza bruta, quindi 1) l'attaccante non è umano, ma piuttosto una botnet di macchine zombi (che non possono usare il login captcha); e 2) la natura della forza bruta dell'attacco richiede un numero molto elevato di tentativi di accesso per garantire il successo, il che significa che non è possibile coltivare il captcha in un negozio di sudore (anche se possibile se l'attaccante è ben finanziato e determinato abbastanza).
Jens Roland,

17

Alcuni semplici passaggi:

Aggiungi alla lista nera alcuni nomi utente comuni e usali come honeypot. Amministratore, ospite, ecc ... Non permettere a nessuno di creare account con questi nomi, quindi se qualcuno prova ad accedervi sai che è qualcuno che fa qualcosa che non dovrebbe.

Assicurati che chiunque abbia un vero potere sul sito abbia una password sicura. Richiedi agli amministratori / moderatori di disporre di password più lunghe con un mix di lettere, numeri e simboli. Rifiuta password banalmente semplici da utenti regolari con una spiegazione.

Una delle cose più semplici che puoi fare è dire alle persone quando qualcuno ha tentato di accedere al proprio account e dare loro un link per segnalare l'incidente se non fosse loro. Un semplice messaggio quando accedono come "Qualcuno ha provato ad accedere al tuo account alle 4:20 di mercoledì blah blah. Fai clic qui se non eri tu." Ti consente di mantenere alcune statistiche sugli attacchi. Puoi intensificare il monitoraggio e le misure di sicurezza se noti che c'è un improvviso aumento degli accessi fraudolenti.


Bei pensieri. Stavo sicuramente pianificando di implementare una politica di password automatica che varia in modo dinamico con il livello di privilegio dell'utente. L'idea honeypot potrebbe funzionare per alcuni tipi di attacco, ma se l'attacco è distribuito, bloccare gli IP che cadono per esso non sarà efficace.
Jens Roland,

Rispetto all '"Ultimo tentativo di accesso", questa è una buona strategia per gli utenti esperti (che scommetto è perché SO lo fa), ma ha due punti deboli: (a) non affronta il problema dell'intrusione, riferisce solo che potrebbe essere successo, e (b), la maggior parte degli utenti non ricorda / cura
Jens Roland,

1
Sì, l'honeypot e il reporting degli utenti riguardano maggiormente la raccolta di informazioni. Possono fornire alcune metriche preziose per farti sapere se / quando si sta verificando un attacco di forza bruta lenta.
patros,

2
Per l'honeypot, trattare un nome utente inesistente come sospetto sarebbe meglio che semplicemente usare un elenco fisso di nomi utente noti-cattivi? Vorresti evitare di bloccare gli utenti che hanno sbagliato a digitare il loro nome utente e non hanno notato l'errore di battitura mentre tentavano di ripetere la password più volte, ma penso ancora che ci siano modi in cui potrebbe essere prezioso. Potresti persino evitare alcuni "falsi positivi" costruendo un grande filtro bloom o una struttura di dati simile con varianti di nomi utente, nomi, cognomi, nomi e-mail validi quando vengono aggiunti gli utenti.
R .. GitHub smette di aiutare ICE il

11

Se capisco correttamente il MO degli attacchi di forza bruta, uno o più nomi utente vengono provati continuamente.

Ci sono due suggerimenti che non credo di aver ancora visto qui:

  • Ho sempre pensato che la pratica standard fosse quella di avere un breve ritardo (circa un secondo) dopo ogni accesso errato per ogni utente. Questo dissuade la forza bruta, ma non so per quanto tempo un ritardo di un secondo manterrebbe a bada un attacco da dizionario. (dizionario di 10.000 parole == 10.000 secondi == circa 3 ore. Hmm. Non abbastanza buono.)
  • invece di un rallentamento a livello di sito, perché non una limitazione del nome utente. L'acceleratore diventa sempre più duro con ogni tentativo sbagliato (fino a un limite, immagino che il vero utente possa ancora accedere)

Modifica : in risposta ai commenti sull'acceleratore di un nome utente: si tratta di un acceleratore specifico per il nome utente, indipendentemente dalla fonte dell'attacco.

Se il nome utente è limitato, verrà catturato anche un attacco coordinato del nome utente (multi IP, singola ipotesi per IP, stesso nome utente). I singoli nomi utente sono protetti dall'acceleratore, anche se gli attaccanti sono liberi di provare un altro utente / passaggio durante il timeout.

Dal punto di vista degli aggressori, durante il timeout potresti essere in grado di fare una prima ipotesi su 100 password e scoprire rapidamente una password errata per account. Potresti essere in grado di fare solo ipotesi di 50 secondi per lo stesso periodo di tempo.

Dal punto di vista dell'account utente, è necessario lo stesso numero medio di ipotesi per violare la password, anche se provengono da più origini.

Per gli aggressori, nella migliore delle ipotesi, sarà lo stesso sforzo di spezzare 100 account come farebbe con 1 account, ma poiché non si sta limitando la limitazione su un sito, è possibile accelerare abbastanza rapidamente.

Ulteriori perfezionamenti:

  • rileva IP che stanno indovinando più account - 408 Timeout richiesta
  • rileva IP che stanno indovinando lo stesso account - 408 Timeout richiesta dopo un numero elevato (diciamo 100) di ipotesi.

Idee dell'interfaccia utente (potrebbe non essere adatto in questo contesto), che può anche perfezionare quanto sopra:

  • se hai il controllo dell'impostazione della password, quindi mostrare all'utente quanto è forte la sua password li incoraggia a sceglierne una migliore.
  • se hai il controllo della pagina di accesso , dopo un piccolo (diciamo 10) numero di ipotesi di un singolo nome utente, offri un CAPTCHA.

Una limitazione del nome utente più una limitazione IP va bene contro gli attacchi a nome fisso o IP fisso e rendono impossibili gli attacchi tradizionali ai dizionari. Ma se l'attaccante cambia costantemente i nomi utente, passerà senza attivare la limitazione del nome utente. Questo è ciò che voglio contrastare
Jens Roland il

2
Grazie per la modifica, James. Ora stiamo parlando. Adoro l'idea del 408. Tuttavia, anche con una limitazione del nome utente rigorosa, una botnet che attacca più utenti funzionerebbe comunque. E controllare le prime 5000 password con un solo utente è MENO probabile che riesca a controllare LE prime 1 password su 5000 utenti
Jens Roland,

Niente come il paradosso del compleanno. In un gruppo numeroso, molti useranno password non sicure e uno probabilmente ne utilizzerà una popolare. Ci sarà anche un buon numero di persone come me che non saranno catturate da un simile attacco.
David Thornley,

2
In realtà, potrei dover ricontrollare la matematica sulla mia precedente dichiarazione. Dopo aver escluso le prime N password più comuni, la probabilità che l'utente abbia la password # (N + 1) può aumentare abbastanza per compensare la differenza. Anche se la curva è probabilmente abbastanza ripida per non essere così
Jens Roland il

9

Esistono tre fattori di autenticazione:

  1. Un utente conosce qualcosa (ovvero una password)
  2. Un utente ha qualcosa (cioè un portachiavi)
  3. Un utente è qualcosa (ad es. Scansione della retina)

Di solito, i siti Web applicano solo la politica n. 1. Anche la maggior parte delle banche applica solo la politica 1. Si basano invece su un approccio "sa qualcos'altro" all'autenticazione a due fattori. (IE: un utente conosce la propria password e il nome da nubile della madre.) Se sei in grado, un modo per aggiungere un secondo fattore di autenticazione non è troppo difficile.

Se è possibile generare circa 256 caratteri di casualità, è possibile strutturarlo in una tabella 16 × 16 e quindi chiedere all'utente di fornire il valore nella tabella della cella A-14, ad esempio. Quando un utente si iscrive o modifica la propria password, assegnare loro la tabella e dire loro di stamparla e salvarla.

La difficoltà con questo approccio è che quando un utente dimentica la sua password, come vuole, non puoi semplicemente offrire lo standard "rispondi a questa domanda e inserisci una nuova password", poiché è vulnerabile anche alla forza bruta. Inoltre, non è possibile ripristinarlo e inviarne uno nuovo via e-mail, poiché anche la loro e-mail potrebbe essere compromessa. (Vedi: Makeuseof.com e il loro dominio rubato.)

Un'altra idea (che coinvolge i cuccioli), è ciò che BOA chiama SiteKey (credo che abbiano il marchio). In breve, l'utente deve caricare un'immagine quando si registra e, quando tenta di accedere, chiede di scegliere la propria immagine tra 8 o 15 (o più) casuali. Quindi, se un utente carica una foto del suo gattino, solo teoricamente sa esattamente quale immagine è la sua di tutti gli altri gattini (o fiori o altro). L'unica vera vunerabilità di questo approccio è l'attacco man-in-the-middle.

Un'altra idea (anche se non gattini), è quella di tenere traccia degli IP con cui gli utenti accedono al sistema e richiedono loro di eseguire un'ulteriore autenticazione (captcha, scegliere un gattino, scegliere una chiave da questa tabella) quando effettuano l'accesso da un indirizzo che non hanno prima. Inoltre, simile a GMail, consente all'utente di visualizzare da dove ha effettuato l'accesso di recente.

Modifica, nuova idea:

Un altro modo per convalidare i tentativi di accesso è verificare se l'utente proviene o meno dalla tua pagina di accesso. Non puoi controllare i referrer, poiché possono essere facilmente falsificati. Ciò di cui hai bisogno è impostare una chiave in _SESSION var quando l'utente visualizza la pagina di accesso, quindi verificare che la chiave esista quando invia le proprie informazioni di accesso. Se il bot non si invia dalla pagina di accesso, non sarà in grado di accedere. Puoi anche facilitare ciò coinvolgendo javascript nel processo, sia utilizzandolo per impostare un cookie, sia aggiungendo alcune informazioni al modulo dopo che è stato caricato. In alternativa, puoi dividere il modulo in due invii diversi (ovvero, l'utente inserisce il suo nome utente, invia, quindi su una nuova pagina inserisce la password e invia di nuovo).

La chiave, in questo caso, è l'aspetto più importante. Un metodo comune per generarli è una combinazione dei dati dell'utente, del loro IP e del momento in cui sono stati inviati.


Sono sicuro che c'è di più, ma se l'idea di SiteKey è esattamente ciò che hai menzionato, un utente malintenzionato non deve essere un MITM, può semplicemente eseguire due o tre tentativi di accesso per quell'utente e scegliere l'immagine che si ripete tra quelli casuali. Anche se il set di 8-15 immagini è statico per l'utente X,
Jens Roland il

(continua) probabilmente non sarebbe troppo difficile scegliere quello corretto, dal momento che le persone tendono a scegliere tipi prevedibili di immagini (anche immagini dai loro album di Flickr!)
Jens Roland,

2
Sì, ho pensato al punto che hai sollevato la scorsa notte dopo essere tornato a casa. Penso che il modo per risolverlo sia: quando un utente accede e fornisce una password corretta, visualizza la sua immagine e un numero di altri casuali. Quando non forniscono la password corretta, mostra un numero di casuali
davethegr8,

1
images + 1, che può includere o meno la propria immagine. Inoltre, ho avuto un'altra idea, vedere la modifica nel post. Ma sì, queste idee sono un po 'difficili / complicate.
davethegr8,

1
Quel "potrebbe" funzionare, ma vedo un paio di problemi. Cosa succede se il proprietario della foto rimuove l'immagine? Come puoi essere sicuro che le immagini restituite non saranno offensive per il tuo utente? Come fa un utente a ricordare dove ha fatto clic? (Sembra difficile dimenticare)
davethegr8

7

In precedenza avevo risposto a una domanda molto simile su Come posso limitare i tentativi di accesso dell'utente in PHP . Ribadirò qui la soluzione proposta in quanto credo che molti di voi troveranno utile e informativo vedere un codice reale. Tieni presente che l'utilizzo di un CAPTCHA potrebbe non essere la soluzione migliore a causa degli algoritmi sempre più precisi utilizzati oggi nei buster CAPTCHA:

Non puoi semplicemente prevenire gli attacchi DoS concatenando la limitazione su un singolo IP o nome utente. Cavolo, non puoi nemmeno davvero prevenire tentativi di accesso rapido usando questo metodo.

Perché? Perché l'attacco può estendersi su più IP e account utente al fine di aggirare i tuoi tentativi di limitazione.

Ho visto postato altrove che idealmente dovresti tenere traccia di tutti i tentativi di accesso falliti sul sito e associarli a un timestamp, forse:

CREATE TABLE failed_logins(
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(16) NOT NULL,
    ip_address INT(11) UNSIGNED NOT NULL,
    attempted DATETIME NOT NULL
) engine=InnoDB charset=UTF8;

Decidi alcuni ritardi in base al numero complessivo di accessi non riusciti in un determinato periodo di tempo. Dovresti basarlo su dati statistici estratti dalla tua failed_loginstabella poiché cambieranno nel tempo in base al numero di utenti e al numero di utenti che possono ricordare (e digitare) la loro password.


10 failed attempts = 1 second
20 failed attempts = 2 seconds
30 failed attempts = reCaptcha

Esegui una query sulla tabella ad ogni tentativo di accesso non riuscito per trovare il numero di accessi non riusciti per un determinato periodo di tempo, ad esempio 15 minuti:


SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute);

Se il numero di tentativi nel corso di un determinato periodo di tempo supera il limite, imporre la limitazione o forzare tutti gli utenti a utilizzare un captcha (ovvero reCaptcha) fino a quando il numero di tentativi falliti in un determinato periodo di tempo è inferiore alla soglia.

// array of throttling
$throttle = array(10 => 1, 20 => 2, 30 => 'recaptcha');

// assume query result of $sql is stored in $row
$sql = 'SELECT MAX(attempted) AS attempted FROM failed_logins';
$latest_attempt = (int) date('U', strtotime($row['attempted']));
// get the number of failed attempts
$sql = 'SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute)';
// assume the number of failed attempts was stored in $failed_attempts
krsort($throttle);
foreach ($throttle as $attempts => $delay) {
    if ($failed_attempts > $attempts) {
        // we need to throttle based on delay
        if (is_numeric($delay)) {
            $remaining_delay = time() - $latest_attempt - $delay;
            // output remaining delay
            echo 'You must wait ' . $remaining_delay . ' seconds before your next login attempt';
        } else {
            // code to display recaptcha on login form goes here
        }
        break;
    }
}

L'uso di reCaptcha a una certa soglia assicurerebbe che un attacco da più fronti sarebbe ridotto al minimo e che gli utenti normali del sito non subirebbero un ritardo significativo per tentativi di accesso legittimi non riusciti. Non posso garantire la prevenzione, poiché è già stato ampliato il fatto che i CAPTCHA possono essere eliminati. Esistono soluzioni alternative, forse una variante di "Name this animal", che potrebbe funzionare abbastanza bene come sostituto.


6

Devo chiederti se hai fatto un'analisi costi-benefici di questo problema; sembra che tu stia cercando di proteggerti da un utente malintenzionato che ha una presenza Web sufficiente per indovinare un numero di password, inviando forse 3-5 richieste per IP (dal momento che hai bloccato la limitazione dell'IP). Quanto (approssimativamente) costerebbe quel tipo di attacco? È più costoso del valore degli account che stai cercando di proteggere? Quante gigantesche botnet vogliono ciò che hai?

La risposta potrebbe essere no - ma se lo è, spero che tu stia ricevendo aiuto da un professionista della sicurezza di qualche tipo; le capacità di programmazione (e il punteggio StackOverflow) non sono strettamente correlati al know-how di sicurezza.


(Intendi dire se la risposta è "no", ovvero che la spesa di un attacco botnet NON è troppo elevata rispetto ai conti)
Jens Roland,

Ma comunque, fai emergere un punto importante. Per i miei usi, non mi aspetto che nessun operatore botnet se ne occupi minimamente, ma sto rilasciando il codice sorgente per chiunque desideri una sicurezza decente per la sua app Web e non posso sapere cosa potrebbero provare gli altri proteggere, o chi sono i loro nemici
Jens Roland,

Non tutelerà i segreti nazionali a prescindere da cosa (i sistemi ufficiali necessitano di una certificazione speciale e sono abbastanza sicuro che nulla di qualificato su PHP possa qualificare), ma tutte le applicazioni web richiedono un'autorizzazione sicura, quindi se lo sto rilasciando, sarei incredibilmente irresponsabile a non usare le migliori pratiche dove posso
Jens Roland,

1
Quindi la mia risposta breve è: lo sto costruendo perché il 99,9% dei siti Web e delle app là fuori ha una sicurezza spaventosa (anche nei grandi campionati: AOL, Twitter, Myspace sono stati tutti compromessi prima), e nella maggior parte dei casi perché sono utilizzando scadenti librerie di autenticazione.
Jens Roland,

Inoltre, leggi l'articolo "To Catch A Predator" di Niels Provos et al. dal procedimento USENIX del 2008 (link: usenix.org/events/sec08/tech/small.html ) È un colpo d'occhio: 2 mesi, un honeypot: 368.000 attacchi da quasi 30.000 IP distinti, provenienti da oltre 5.600 botnet!
Jens Roland,

5

Per riassumere lo schema di Jens in un diagramma / base di regole di pseudo stato:

  1. utente + password -> voce
  2. user +! password -> negato
  3. user + known_IP (utente) -> porta d'ingresso, // never throttle
  4. user + unknown_IP (utente) -> catflap
  5. (#denied> n) via catflaps (site) -> throttle catflaps (site) // slow the bots
  6. catflap + throttle + password + captcha -> entry // humans still welcome
  7. catflap + throttle + password +! captcha -> negato // a correct guess from a bot

osservazioni:

  • Non accelerare mai la porta d'ingresso. La polizia di stato elboniana ha il tuo computer a casa tua, ma non è in grado di interrogarti. La forza bruta è un approccio praticabile dal tuo computer.
  • Se si fornisce un "Hai dimenticato la password?" link, quindi il tuo account e-mail diventa parte della superficie di attacco.

Queste osservazioni riguardano un diverso tipo di attacco rispetto a quelli che stai cercando di contrastare.


Assolutamente l'account e-mail fa parte della superficie di attacco. Ho una serie di ipotesi di limite superiore sulla sicurezza che la mia strategia fornirà e il limite più basso è la sicurezza della posta elettronica dell'utente. Se un utente malintenzionato viola la posta elettronica di un utente, tutte le scommesse sono disattivate.
Jens Roland,

Inoltre, penso che il diagramma di transizione dello stato abbia bisogno di un paio di dettagli: # 3 e # 4 dovrebbero includere la password; # 1 e # 2 dovrebbero includere known_IP (utente) poiché un accesso ha sempre un IP noto o sconosciuto; e il n. 6 è 'entry nonostante throttle'
Jens Roland,

4

Sembra che tu stia cercando di difenderti dalla forza bruta distribuita lenta . Non puoi fare molto. Stiamo utilizzando una PKI e nessun accesso con password. Aiuta, ma se i tuoi clienti si imbattono nelle workstation di tanto in tanto, questo non è molto applicabile.


Forza bruta davvero veloce. Speravo di essere un po 'indulgente con la forza bruta dell'utente fisso (limitazione di soli 20 secondi), ma in un sito con 50k utenti, ciò avrebbe reso possibile la forza bruta veloce di un utente variabile (supponendo 20+ secondi per scorrere gli utenti). E quello, come si suol dire, farebbe schifo ...
Jens Roland,

Forza bruta veloce da un singolo host usa iptables o qualunque firewall tu usi.
Björn Raupach,

Mi riferivo alla forza bruta veloce distribuita. È raro ma potenzialmente molto cattivo
Jens Roland,

3

Disclaimer: lavoro per un'azienda a due fattori, ma non sono qui per collegarlo. Ecco alcune osservazioni

I cookie possono essere rubati con XSS e browser vulns. Gli utenti cambiano comunemente browser o cancellano i loro cookie.

Gli indirizzi IP di origine sono contemporaneamente dinamicamente variabili e spoofable.

Il captcha è utile, ma non autentica un essere umano specifico.

Più metodi possono essere combinati con successo, ma il buon gusto è sicuramente in ordine.

La complessità della password è buona, qualsiasi cosa basata su password dipende in modo critico dalle password con entropia sufficiente. IMHO, una password complessa scritta in un luogo fisico sicuro è meglio di una password debole in memoria. Le persone sanno come valutare la sicurezza dei documenti cartacei molto meglio di quanto sappiano capire l'entropia effettiva nel nome del loro cane quando vengono usati come password per tre diversi siti Web. Prendi in considerazione la possibilità di offrire agli utenti la possibilità di stampare una pagina grande o piccola piena di passcode monouso.

Le domande di sicurezza come "qual era la tua mascotte del liceo" sono per lo più un'altra forma di "qualcosa che conosci", la maggior parte di esse sono facilmente indovinabili o di dominio pubblico.

Come hai notato, rallentare i tentativi di accesso non riusciti è un compromesso tra la prevenzione degli attacchi di forza bruta e la facilità di fare un account. Criteri di blocco aggressivi possono riflettere una mancanza di fiducia nell'entropia delle password.

Personalmente non vedo il vantaggio di imporre la scadenza della password su un sito Web comunque. L'attaccante riceve la password una volta, può cambiarla e attenersi a tale politica il più facilmente possibile. Forse un vantaggio è che l'utente potrebbe notare prima se l'attaccante cambia la password dell'account. Ancora meglio sarebbe se l'utente fosse stato in qualche modo avvisato prima che l'attaccante ottenesse l'accesso. Messaggi come "N tentativi falliti dall'ultimo accesso" sono utili al riguardo.

La migliore sicurezza deriva da un secondo fattore di autenticazione che è fuori banda rispetto al primo. Come hai detto, i token hardware nel "qualcosa che hai" sono fantastici, ma molti (non tutti) hanno un vero overhead di amministrazione associato alla loro distribuzione. Non conosco soluzioni biometriche "qualcosa che sei" per i siti Web. Alcune soluzioni a due fattori funzionano con provider openid, alcune hanno SDK PHP / Perl / Python.


Tutti i punti eccellenti: non potrei essere più d'accordo. Il punto sull'insicurezza dei cookie è molto valido, ma senza un secondo fattore di token fisici o password monouso (distribuite su una linea sicura) non si può davvero proteggere da un endpoint vulnerabile. Se il box / browser dell'utente è compromesso, lo sono anche i suoi accessi.
Jens Roland,

1

La mia più alta raccomandazione è semplicemente assicurarsi di tenere gli utenti informati dei tentativi di accesso errati ai loro account - Gli utenti probabilmente prenderanno molto più seriamente la forza della loro password se vengono presentati con prove che qualcuno sta effettivamente cercando di entrare nel loro account .

In realtà ho trovato qualcuno che ha violato l'account myspace di mio fratello perché avevano cercato di accedere all'account Gmail che ho configurato per lui e hanno usato la funzione "Reimposta la mia password via email" ... che è andata nella mia casella di posta.


1
  1. Che ne dici di richiedere una password una tantum prima di inserire la loro normale password? Ciò renderebbe molto ovvio che qualcuno stava attaccando prima di avere molte opportunità di indovinare la password principale?

  2. Mantieni un conteggio / tasso globale di errori di accesso - questo è l'indicatore di un attacco - durante un attacco sii più severo sugli errori di accesso, ad es. Bando IP più rapidamente.


1) Come implementeresti una password monouso su una linea non sicura e non autenticata? In altre parole, quando l'utente imposta queste password singole? 2) Sì, questo è l'essenza di # 4 nella mia lista, il limite a livello di sito per tentativi falliti. Il rovescio della medaglia è l'opportunità DoS che si apre.
Jens Roland,

0

Non credo che ci sia una risposta perfetta, ma sarei propenso ad avvicinarlo sulla base del tentativo di confondere i robot se viene rilevato un attacco.

In cima alla mia mente:

Passa a una schermata di accesso alternativa. Ha più spazi vuoti per nome utente e password che appaiono davvero, ma solo uno di questi è nel posto giusto. I nomi dei campi sono RANDOM - una chiave di sessione viene inviata insieme alla schermata di accesso, il server può quindi scoprire quali campi sono cosa. Se ha esito positivo o negativo, viene quindi scartato in modo da non poter provare un attacco di riesecuzione: se si rifiuta la password, viene visualizzato un nuovo ID sessione.

Si presume che qualsiasi modulo inviato con dati in un campo errato provenga da un robot: il login non riesce, punto e quell'IP è limitato. Assicurati che i nomi dei campi casuali non corrispondano mai ai nomi dei campi legittimi, quindi qualcuno che utilizza qualcosa che ricorda le password non è fuorviante.

Quindi, che ne dici di un diverso tipo di captcha: hai una serie di domande che non causeranno problemi a un essere umano. Tuttavia, NON sono casuali. Quando l'attacco inizia, a tutti viene data la domanda n. 1. Dopo un'ora la domanda n. 1 viene scartata, per non essere più utilizzata e tutti ricevono la domanda n. 2 e così via.

L'attaccante non può sondare per scaricare il database da inserire nel proprio robot a causa della natura usa e getta delle domande. Deve inviare nuove istruzioni alla sua botnet entro un'ora per avere la possibilità di fare qualsiasi cosa.


La schermata di accesso alternativa sembra confondere gli umani più delle macchine, francamente. Ovviamente stiamo assumendo che l'attaccante avrebbe verificato in anticipo le nostre misure di sicurezza. Avrebbe potuto facilmente modificare il suo raschietto per trovare i campi posizionati correttamente.
Jens Roland,

Le domande sul controllo umano sono state fatte in precedenza e non sono molto efficaci. Per un operatore di botnet umano rispondere a una domanda all'ora (dopo la quale la nuova risposta si propagherà ai robot) durante un attacco sarebbe abbastanza fattibile.
Jens Roland,

Ti manca il punto. L'attaccante non può controllare in anticipo perché mostra le difese extra solo quando si presenta un attacco.
Loren Pechtel,

Certo, l'umano poteva vedere quale fosse la domanda, ma doveva comunicarlo a tutti i suoi robot. Questo è un percorso di comunicazione che semplifica l'abbattimento della botnet.
Loren Pechtel,

Non credo di perdere il punto. Non voglio dire che in precedenza avrebbe eseguito un attacco per verificare le nostre misure di sicurezza, intendo che avrebbe letto questo thread e controllato il codice (aperto) per verificare la presenza di problemi :)
Jens Roland,

0

Poiché diverse persone hanno incluso CAPTCHA come meccanismo umano di fallback, sto aggiungendo una domanda StackOverflow precedente e un thread sull'efficacia di CAPTCHA.

ReCaptcha è stato crackato / hackerato / OCR / sconfitto / rotto?

L'uso di CAPTCHA non limita i miglioramenti della limitazione e di altri suggerimenti, ma penso che il numero di risposte che includono CAPTCHA come fallback dovrebbe considerare i metodi basati sull'uomo disponibili per le persone che cercano di violare la sicurezza.


0

Potresti anche limitare la potenza in base alla forza della password di un utente.

Quando un utente registra o modifica la propria password, si calcola un punteggio di sicurezza per la propria password, ad esempio tra 1 e 10.

Qualcosa come "password" segna un 1 mentre "c6eqapRepe7et * Awr @ ch" potrebbe segnare un 9 o 10 e più alto è il punteggio, più tempo impiega la limitazione per dare il calcio d'inizio.


2
Capisco l'idea, ma ciò perderebbe indirettamente informazioni sulla password, facendo sapere a un utente malintenzionato se vale la pena hackerare o meno una password. Può sembrare un po 'teorico, ma molti utenti riutilizzano le password, quindi se voglio entrare in Strong_Throttling_Website.com posso semplicemente attaccare account (privilegiati) a caso fino a quando non trovo un utente, "Freddy", che ha una password debole (es. throttling iniziale), quindi vai su Less_Secure_Website.edu e fai un semplice attacco con dizionario sull'account di Freddy lì. È un po 'coinvolto, ma certamente fattibile in pratica.
Jens Roland,

0

La prima risposta che di solito ho sentito quando ho posto questa domanda è cambiare le porte, ma dimenticatene e disabilita semplicemente IPv4. Se consenti solo ai client delle reti IPv6 non pregherai più per la semplice scansione della rete e gli aggressori ricorrono alle ricerche DNS. Non eseguire lo stesso indirizzo di Apache (AAAA) / Sendmail (MX-> AAAA) / cosa hai dato a tutti (AAAA). Assicurati che la tua zona non possa essere xferd, attendi che la tua zona sia scaricata da nessuno?

Se i bot rilevano che il tuo server configura nuovi nomi host, basta anteporre un po 'incomprensibile ai tuoi nomi host e cambiare il tuo indirizzo. Lasciare i vecchi nomi e persino impostare ** i nomi honeypot per il timeout della rete bot.

** Testa i tuoi record inversi (PTR) (sotto ip6.arpa.) Per vedere se possono essere usati per azzerare su / 4 che hanno record VS / 4 che non lo fanno. IE In genere ip6.arpa avrebbe ~ 32 "." S in un indirizzo ma provare con gli ultimi pochi mancanti potrebbe eludere i blocchi di rete che hanno record VS altri che non lo fanno. Se lo spingi oltre, diventa possibile saltare grandi parti dello spazio degli indirizzi.

Nel peggiore dei casi gli utenti dovranno configurare un tunnel IPv6, non è come se dovessero spingersi fino al VPN in una DMZ ... Anche se ci si chiede perché non sia la prima opzione.

Anche Kerberos è bello, ma LDHO IMHO soffia (Cosa c'è di tecnicamente sbagliato in NISPlus? Ho letto che Sun ha deciso che gli utenti volevano LDAP e per questo hanno lasciato cadere NIS +). Kerberos funziona bene senza LDAP o NIS, è sufficiente gestire gli utenti su un host in base all'host. L'uso di Kerberos ti dà una PKI facile da usare, se non automatizzata.


0

Un po 'tardi, ma stavo pensando, ipotizzando un caso difficile: l'attaccante usa molti IP casuali, nomi utente casuali e una password casuale selezionata da un elenco dei 10.000 più popolari.

Una cosa che potresti fare, specialmente se il sistema sembra essere sotto attacco in quanto ci sono molti tentativi di password sbagliati sul sistema e soprattutto se la password è a bassa entropia è di porre una domanda secondaria come quali sono i nomi dei tuoi genitori, per esempio . Se un utente malintenzionato colpisce un milione di account provando la password "password1", ci sono buone probabilità che ottengano molto, ma le loro probabilità di ottenere anche i nomi giusti ridurrebbero drasticamente i successi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.