
Db Strumento di valutazione del database
Strumento di valutazione del database Db
DbDat esegue numerosi controlli su un database per valutarne la sicurezza. Le categorie di controllo sono: configurazione, privilegi, utenti e informazioni. I controlli vengono eseguiti lanciando query o leggendo i file di configurazione del database. L'obiettivo di questo strumento è evidenziare i problemi che richiedono attenzione immediata e identificare le impostazioni di configurazione che dovrebbero essere riviste per verificarne l'appropriatezza. Questo strumento non serve per identificare vulnerabilità di SQL Injection in un'applicazione; esistono già buoni strumenti per questo (ad esempio https://github.com/sqlmapproject). Inoltre, questo strumento non tenta di determinare quali CVE possano riguardare la versione del database target (ma potrebbe farlo in futuro – forse). Piuttosto, questo strumento può aiutarti a comprendere meglio l'impatto potenziale di un attacco SQL Injection riuscito a causa di una configurazione debole o di controlli di accesso inadeguati. La maggior parte dei controlli proviene dai CIS Security Benchmarks per database (https://cisecurity.org), quindi grazie al CIS! I documenti di benchmark sono disponibili qui: https://benchmarks.cisecurity.org/downloads/browse/index.cfm?category=benchmarks.servers.database
Raccomando vivamente di scaricare il documento di benchmark per il tuo database target, poiché contiene informazioni aggiuntive sui controlli eseguiti.
Infine, DbDat è pensato come un framework per facilitare la creazione di nuovi plugin e controlli. I contributi dalla comunità della sicurezza, o anche dagli amministratori di database, sono ciò che renderà questo strumento eccezionale. L'attuale insieme di controlli non è assolutamente completo, sicuramente c'è ancora molto da fare. Per favore, contribuisci!
Sviluppare nuovi controlli per il database
Le pull request sono molto benvenute! I controlli sono organizzati per tipo di database (es. MySQL, Oracle, MS SQL, ecc.) nella cartella plugins. Ogni controllo è un singolo file Python il cui nome deve iniziare con check_. Ogni file contiene una classe con un metodo do_check. Questo metodo è la logica principale per i controlli. Il modo più rapido per iniziare è copiare un file di controllo esistente e modificarlo. Tuttavia, per maggiori dettagli consultare la sezione "Sviluppare plugin" più avanti.
etc/dbdat.conf per ogni database che desideri valutare.python dbdat.py -p <nome_profilo>python -m SimpleHTTPServer 9000 (o scegli un numero di porta a tua preferenza). Quindi apri il browser e naviga su http://localhost:9000.Per vedere un elenco di argomenti aggiuntivi da riga di comando, esegui python dbdat.py -h
Il report organizza i risultati in livelli: RED, YELLOW, ORANGE, GRAY e GREEN.
Finora DbDat è stato testato su Debian Linux, CentOS Linux e Windows 7 con Python 2.7.
Esegui: pip install MySQL-python
Oppure su Debian, esegui: apt-get install python-mysqldb
Esegui: pip install psycopg2
Esegui: pip install cx_Oracle
Nota: dovrai installare le librerie client Oracle per farlo funzionare.
Esegui: pip install pymssql
Esegui: pip install ibm_db o easy_install ibm_db
Nota: assicurati che l'utente che esegue DbDat abbia accesso per eseguire i comandi CLP di DB2 (es. db2 e db2level).
Esegui: pip install pymongo
Per supportare i file di configurazione YAML di MongoDB, esegui: pip install pyyaml
Esegui: pip install couchdb
All'interno della cartella plugins c'è una cartella per ogni tipo di database, e ogni cartella contiene i file di controllo. Questa è una struttura molto semplice, ma puoi anche esplorare la cartella plugins per familiarizzare https://github.com/foospidy/DbDat/tree/master/plugins
Le cartelle dei database conterranno:
__init.py – Il file init contiene un'istruzione import per ogni file di controllo.check_ – Sono i file che eseguono effettivamente i controlli sul database. Il file e la classe definita al suo interno dovrebbero avere lo stesso nome.helper.py – Un file contenente funzioni comuni. I file di controllo possono importare helper.py per sfruttare funzioni comuni.Quando si aggiunge un nuovo file di controllo, è necessario aggiungere un'istruzione import nel corrispondente file __init__.py della directory del plugin. Il modello di codice per i controlli è abbastanza coerente. Rivedi i file esistenti per farti un'idea della loro struttura. Nota la differenza tra controlli di tipo sql e configuration_file.
Esistono diversi "tipi" di controlli che possono essere definiti. Il tipo di controllo è determinato dalla variabile TYPE e può essere sql, configuration_file, nosql o clp. Di seguito sono riportati esempi di implementazione per i diversi scenari di tipo di controllo.
Per i controlli sql, la firma del metodo do_check deve essere: do_check(self, *results)
https://github.com/foospidy/DbDat/blob/master/plugins/mysql/check_user_empty_password.py
In questo esempio abbiamo bisogno della variabile appuser dalla classe genitore chiamante. L'utente app deve essere aggiunto dinamicamente all'istruzione sql, quindi la variabile self.SQL viene impostata nel metodo __init__. Inoltre, poiché questo metodo do_check deve eseguire l'sql, abbiamo bisogno anche del cursore DB (connessione), che viene impostato nel metodo __init__ con self.dbcurs = parent.dbcurs.
https://github.com/foospidy/DbDat/blob/master/plugins/mysql/check_privilege_user_grants.py
Per i controlli configuration_file, la firma del metodo do_check deve essere: do_check(self, configuration_file)
https://github.com/foospidy/DbDat/blob/master/plugins/mysql/check_configuration_general_log.py
In questo esempio, il file di configurazione di PostgreSQL non ha sezioni (es. [nome_sezione]), quindi il modulo helper nella cartella PostgreSQL contiene una funzione che gestisce questa situazione. Vedi la funzione get_config_value definita in helper.py.
Per altri formati di file di configurazione dovrai definire la tua logica di parsing.
Per i controlli nosql, la firma del metodo do_check deve essere: do_check(self)
Le query NoSQL devono essere eseguite all'interno del metodo do_check, quindi il metodo __init__ della classe deve implementare self.db = parent.db. La variabile self.db può quindi essere utilizzata per eseguire query NoSQL all'interno del metodo do_check.
https://github.com/foospidy/DbDat/blob/master/plugins/mongodb/check_information_banner.py
Per i controlli clp, la firma del metodo do_check deve essere: do_check(self, *results). I controlli clp sono necessari per i database IBM DB2 in modo che il processore a riga di comando db2 possa essere eseguito per ottenere informazioni sul database. Tuttavia, questo tipo di controllo potrebbe essere utilizzato per eseguire qualsiasi comando arbitrario a riga di comando. Tutto l'output della riga di comando può essere analizzato dalla variabile results passata al metodo do_check. Inoltre, dovrai definire il metodo di classe CMD. Questa variabile è una lista del comando e degli argomenti correlati.
https://github.com/foospidy/DbDat/blob/master/plugins/db2/check_privilege_group_entitlements.py
Ogni controllo deve avere una categoria specificata utilizzando la variabile CATEGORY. La categoria è un modo per organizzare i controlli. Le categorie possibili sono: Information, Configuration, Privilege e User. Specifica la categoria più pertinente al contesto del controllo.
Questo è un esempio approssimativo che mostra il modello che un file di controllo dovrebbe seguire:
# (OPZIONALE): Aggiungi istruzioni import, includi i moduli necessari per supportare questo controllo
import helper
# (OBBLIGATORIO): Definisci la classe, la classe deve avere lo stesso nome del suo file.
class check_configuration_evaluate_something():
# (OBBLIGATORIO): Aggiungi documentazione, fornisci informazioni su questo controllo, verranno visualizzate nel report.
"""
check_configuration_evaluate_something:
Qualche descrizione va qui!
"""
# (OPZIONALE): Aggiungi riferimenti, sono solo commenti nel codice; aggiungere riferimenti è utile per gli altri.
# References:
# https://www.percona.com/blog/2012/12/28/auditing-login-attempts-in-mysql/
# https://dev.mysql.com/doc/refman/5.7/en/password-security-user.html
# (OBBLIGATORIO): Aggiungi il set standard di variabili
TITLE = 'Client Password'
CATEGORY = 'Configuration'
TYPE = 'configuration_file'
SQL = None
verbose = False
skip = False
result = {}
# (OPZIONALE): Aggiungi variabili personalizzate specifiche per questo controllo
custom_var = 'custom_val'
# (OBBLIGATORIO): Definisci il metodo do_check, è la logica effettiva del controllo e viene chiamato dal programma principale.
def do_check(self, *results):
# (OBBLIGATORIO): la logica del controllo va qui; assicurati di impostare i valori per self.result['level'] e self.result['output']
# I risultati della variabile SQL possono essere elaborati usando:
for rows in results:
for row in rows:
# (OBBLIGATORIO):
# Imposta sempre le variabili self.result['level'] e self.result['output'] prima di restituire.
if row[0] == 'bad':
self.result['level'] = 'RED'
self.result['output'] = 'Il risultato è %s' % (row[0])
elif row[0] == 'needs review':
self.result['level'] = 'YELLOW'
self.result['output'] = 'Il risultato è %s' % (row[0])
else:
self.result['level'] = 'GREEN'
self.result['output'] = 'Il risultato è %s' % (row[0])
# Restituisci sempre self.result
return self.result
# (OBBLIGATORIO): almeno il metodo __init__ dovrebbe stampare il controllo in esecuzione.
def __init__(self, parent):
print('Esecuzione del controllo: ' + self.TITLE)
# ottieni i valori dalla classe chiamante genitore
self.verbose = parent.verbose