Rilevamento automatico di perdite di credenziali e server segreti

1

Sono disponibili framework o applicazioni per il rilevamento automatico delle credenziali o dei segreti trapelati?

Finora, ho trovato una serie di articoli accademici su documenti su il oggetto ma senza applicazioni o framework specifici. Ho anche trovato lo strumento Scumblr di Netflix, che corrisponde al criterio: ricerca automatica dei siti di social media, possibile caso d'uso essere per aggiungere regex per e-mail o possibili stringhe API.

    
posta Peter Souter 15.09.2016 - 17:15
fonte

1 risposta

1

Questa non sarà una risposta completa, poiché una risposta completa non è possibile: una credenziale può essere qualsiasi cosa che si può voler trasformare in una credenziale. Ma supponendo che le credenziali siano ragionevoli possiamo discutere su due cose:

  1. Il primo articolo che menzioni fa semplicemente uno schema in cui un accesso non autorizzato provoca un allarme (codice di errore nella carta) che disabilita la chiave. In termini di implementazione questo non è molto diverso da: "dopo tre accessi non riusciti la password è bloccata" .

    La novità della carta è solo che fanno un keychame completo (con analisi formale dello schema).

  2. Il secondo documento parla di qualcosa di completamente diverso. È solo un'enumerazione di come i sistemi che pubblicano i dati dell'utente sul web (ad esempio github o bitbucket, ma potrebbe anche essere Facebook) cercano di scoprire che all'interno dei dati pubblicati ci sono stringhe che sembrano credenziali da qualche altra parte. Questo è molto simile a ciò che scumblr può essere configurato per fare. La loro lista di tecniche include punti piuttosto semplici:

    1. ricerca per parole chiave (ad esempio BEGIN RSA PRIVATE KEY )
    2. pattern match (ad esempio ricerca per stringhe con codifica Base64)
    3. euristica (pattern match ma usando context)
    4. ricerca del codice sorgente (pattern match ma usando ipotesi basate sul tipo di codice sorgente che sta cercando)

    Queste cose funzionano, ricordo di aver ricevuto un'email da BitBucket quando una volta ho inviato la mia chiave API AWS a un repository. Ma per quanto riguarda la loro implementazione come strumento specifico, credo che siano solo script che vengono invocati come git hooks. Guarda questa immagine sul giornale:

    Il"modulo di rilevamento chiavi" viene chiamato tra un commit utente e il commit effettivo nel repository pubblico.

    Github e BitBucket hanno certamente un database di pattern che possono essere credenziali. E inoltre hanno sicuramente un paio di algoritmi euristici. I punti 1 (ricerca per parole chiave) e 2 (corrispondenza modello) sono semplici da implementare con grep, i punti 3 (euristica) e 4 (ricerca sorgente) richiedono una buona quantità di dati preesistenti che avrebbero solo luoghi come Github e BitBucket.

    Si noti infine che persino il documento sostiene che l'euristica e la ricerca sorgente producono sia falsi negativi che falsi positivi. Quindi non c'è una soluzione magica qui.

Se avessi avuto bisogno di qualcosa per verificare che gli utenti sul mio sito web pubblicassero le loro credenziali in qualche posto per caso, proverei ad usare i punti 1 (keyword match) e 2 (pattern matching) e poi semplicemente costruire un algoritmo euristico che non dipende su così tanto su dati preesistenti. Il modo migliore sarebbe provare la complessità di Kolmogorov (vedi questa vecchia domanda sulla complessità delle stringhe da ulteriori informazioni ).

L'assunto è che le credenziali complesse avranno un sacco di entropia per byte poiché dovrebbero essere difficili da usare come forza bruta. Questa è una cattiva ipotesi in alcuni casi: ad esempio le stringhe con codifica base64 hanno una complessità ridotta rispetto alla loro lunghezza. Dovremo catturare le stringhe base64 nella fase di corrispondenza del modello (fase 2).

Ecco una cosa banale (usa zlib per approssimare l'algoritmo euristico di complessità di Kolmogorov, che non è particolarmente vicino) usando l'assunto sopra:

#!/usr/bin/env python3

from io import BytesIO
import zipfile

strings = [ b'password password password password'
          , b'correct horse batter staple'
          , b'HdtfhhaissdogkanfhhwnaHDnbahdnSGENdkfQWee=='
          , b'hZjJIdkXndjaodk='
          , b'\x89\x12\x03\x561w\x10'
          ]
for s in strings:
    fp = BytesIO()
    zf = zipfile.ZipFile(fp, 'w', zipfile.ZIP_DEFLATED)
    zf.writestr('f', s)
    zf.close()
    print('%50s' % s, float(len(fp.getvalue())) / float(len(s)) )

E il suo output:

        b'password password password password' 3.257142857142857
                b'correct horse batter staple' 4.777777777777778
b'HdtfhhaissdogkanfhhwnaHDnbahdnSGENdkfQWee==' 3.3255813953488373
                           b'hZjJIdkXndjaodk=' 7.375
                        b'\x89\x12\x03V1w\x10' 15.571428571428571

Come previsto, funziona bene per separare stringhe semplici da stringhe che sono insiemi di byte più o meno casuali. Tuttavia, funziona male sulle stringhe base64 e persino su alcune frasi d'accesso.

    
risposta data 17.09.2016 - 02:47
fonte

Leggi altre domande sui tag