
Db データベース評価ツール
DbDat は、データベースのセキュリティを評価するために多数のチェックを実行します。実行されるチェックのカテゴリは、構成、権限、ユーザー、および情報です。チェックは、クエリを実行するか、データベース構成ファイルを読み取ることによって実行されます。このツールの目的は、即時の対応が必要な問題を強調し、適切性を確認すべき構成設定を特定することです。このツールは、アプリケーションの SQL インジェクションの脆弱性を特定するためのものではありません。そのための優れたツールは既に存在します (例: https://github.com/sqlmapproject)。また、このツールは、対象データベースのバージョンに影響を与える可能性のある CVE を特定しようとはしません (将来行う可能性はありますが、おそらく)。むしろ、このツールは、脆弱な構成やアクセス制御による SQL インジェクション攻撃の成功の潜在的な影響をよりよく理解するのに役立ちます。チェックの大部分は、CIS (https://cisecurity.org) のデータベース向けセキュリティベンチマークに基づいています。CIS に感謝します!ベンチマーク文書はこちらにあります: https://benchmarks.cisecurity.org/downloads/browse/index.cfm?category=benchmarks.servers.database
対象データベースのベンチマーク文書をダウンロードすることを強くお勧めします。実行されるチェックに関する追加情報が含まれているからです。
最後に、DbDat は、新しいプラグインやチェックを簡単に作成できるようにするためのフレームワークを意図しています。セキュリティコミュニティ、あるいはデータベース管理者コミュニティからの貢献が、このツールを素晴らしいものにするでしょう。現在のチェックのセットは決して完全ではなく、確かにやるべきことはまだたくさんあります。ぜひ貢献してください!
新しいデータベースチェックの開発
プルリクエストは大歓迎です! チェックはプラグインフォルダ内でデータベースタイプ (例: MySQL、Oracle、MS SQL など) ごとに整理されています。各チェックは単一の Python ファイルであり、ファイル名の先頭に check_ がなければなりません。各ファイルには do_check メソッドを持つクラスが含まれています。このメソッドがチェックの主要なロジックです。すぐに始めるには、既存のチェックファイルをコピーして修正してください。ただし、詳細については、以下の「プラグインの開発」セクションを参照してください。
etc/dbdat.conf ファイルに接続プロファイルエントリを追加します。python dbdat.py -p <プロファイル名>cd して python -m SimpleHTTPServer 9000 を実行します (または好みのポート番号を選択してください)。次にブラウザを開き、http://localhost:9000 に移動します。追加のコマンドライン引数のリストを表示するには、python dbdat.py -h を実行します。
レポートは結果をレベル別に整理します。レベルは RED、YELLOW、ORANGE、GRAY、GREEN です。
現時点では、DbDat は Debian Linux、CentOS Linux、Windows 7 (Python 2.7) でテストされています。
実行: pip install MySQL-python
または Debian では、実行: apt-get install python-mysqldb
実行: pip install psycopg2
実行: pip install cx_Oracle
注: これを機能させるには、Oracle クライアントライブラリをインストールする必要があります。
実行: pip install pymssql
実行: pip install ibm_db または easy_install ibm_db
注: DbDat を実行するユーザーが DB2 CLP コマンド (例: db2 や db2level) を実行する権限を持っていることを確認する必要があります。
実行: pip install pymongo
MongoDB YAML 構成ファイルをサポートするには、実行: pip install pyyaml
実行: pip install couchdb
plugins フォルダ内にはデータベースの種類ごとにフォルダがあり、各フォルダにはチェックファイルが含まれています。これは非常にシンプルな構造ですが、プラグインフォルダを参照して慣れることもできます。https://github.com/foospidy/DbDat/tree/master/plugins
データベースフォルダには以下が含まれます:
__init.py - init ファイルには各チェックファイルのインポート文が含まれています。check_ ファイル - これらは実際にデータベースチェックを実行するファイルです。ファイルとその中で定義されたクラスは同じ名前を持つ必要があります。helper.py - 共通関数を含むファイル。チェックファイルは helper.py をインポートして共通関数を利用できます。新しいチェックファイルを追加する場合、対応するプラグインディレクトリの __init__.py ファイルにインポート文を追加する必要があります。チェックのコードパターンはかなり一貫しています。既存のファイルをレビューして、それらがどのように構成されているかを把握してください。sql タイプと configuration_file タイプのチェックの違いに注意してください。
定義可能なチェックには異なる「タイプ」があります。チェックタイプは TYPE 変数によって決定され、sql、configuration_file、nosql、clp のいずれかになります。以下は、さまざまなチェックタイプのシナリオに対する実装例です。
sql チェックの場合、do_check メソッドのシグネチャは do_check(self, *results) である必要があります。
https://github.com/foospidy/DbDat/blob/master/plugins/mysql/check_user_empty_password.py
この例では、呼び出し元の親クラスから appuser 変数が必要です。appuser は sql 文に動的に追加する必要があるため、self.SQL 変数は __init__ メソッド内で設定されています。また、この do_check メソッドは sql を実行するために DB カーソル (接続) も必要とするため、self.dbcurs = parent.dbcurs で __init__ メソッド内に設定されています。
https://github.com/foospidy/DbDat/blob/master/plugins/mysql/check_privilege_user_grants.py
configuration_file チェックの場合、do_check メソッドのシグネチャは do_check(self, configuration_file) である必要があります。
https://github.com/foospidy/DbDat/blob/master/plugins/mysql/check_configuration_general_log.py
この例では、PostgreSQL 構成ファイルにはセクション (例: [section_name]) がないため、PostgreSQL フォルダ内のヘルパーモジュールにこれを処理する関数があります。helper.py で定義されている get_config_value 関数を参照してください。
その他の構成ファイル形式については、独自の解析ロジックを定義する必要があります。
nosql チェックの場合、do_check メソッドのシグネチャは do_check(self) である必要があります。
NoSQL クエリは do_check メソッド内で実行する必要があるため、クラスの __init__ メソッドは self.db = parent.db を実装する必要があります。self.db 変数は、do_check メソッド内で NoSQL クエリを実行するために使用できます。
https://github.com/foospidy/DbDat/blob/master/plugins/mongodb/check_information_banner.py
clp チェックの場合、do_check メソッドのシグネチャは do_check(self, *results) である必要があります。clp チェックは、IBM DB2 データベースで db2 コマンドラインプロセッサを実行してデータベースに関する情報を取得するために必要です。ただし、このタイプのチェックは任意のコマンドラインコマンドを実行するためにも使用できます。すべてのコマンドライン出力は、do_check メソッドに渡される results 変数から解析できます。さらに、CMD クラスメソッドを定義する必要があります。この変数は、コマンドと関連する引数のリストです。
https://github.com/foospidy/DbDat/blob/master/plugins/db2/check_privilege_group_entitlements.py
すべてのチェックには、CATEGORY 変数を使用してカテゴリを指定する必要があります。カテゴリはチェックを整理する方法です。可能なカテゴリは、Information、Configuration、Privilege、User です。チェックのコンテキストに最も関連するカテゴリを指定してください。
これは、チェックファイルが従うべきパターンの大まかな例です:
# (OPTIONAL): インポート文を追加し、このチェックをサポートするために必要なモジュールを含めます
import helper
# (REQUIRED): クラスを定義します。クラスはそのファイル名と同じ名前でなければなりません。
class check_configuration_evaluate_something():
# (REQUIRED): ドキュメントを追加します。このチェックに関する情報を提供します。レポートに表示されます。
"""
check_configuration_evaluate_something:
説明文をここに書きます!
"""
# (OPTIONAL): 参照を追加します。コード内のコメントのみです。参照を追加することは他の人に役立ちます。
# 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
# (REQUIRED): 標準的な変数セットを追加します
TITLE = 'Client Password'
CATEGORY = 'Configuration'
TYPE = 'configuration_file'
SQL = None
verbose = False
skip = False
result = {}
# (OPTIONAL): このチェックに固有のカスタム変数を追加します
custom_var = 'custom_val'
# (REQUIRED): do_check メソッドを定義します。これが実際のチェックロジックであり、メインプログラムから呼び出されます。
def do_check(self, *results):
# (REQUIRED): チェックロジックをここに記述します。self.result['level'] と self.result['output'] の値を必ず設定してください。
# SQL 変数の結果は次のように処理できます:
for rows in results:
for row in rows:
# (REQUIRED):
# 必ず return の前に self.result['level'] と self.result['output'] 変数を設定してください。
if row[0] == 'bad':
self.result['level'] = 'RED'
self.result['output'] = 'Result is %s' % (row[0])
elif row[0] == 'needs review':
self.result['level'] = 'YELLOW'
self.result['output'] = 'Result is %s' % (row[0])
else:
self.result['level'] = 'GREEN'
self.result['output'] = 'Result is %s' % (row[0])
# 必ず self.result を返します
return self.result
# (REQUIRED): 最低でも __init__ メソッドは実行中のチェックを表示する必要があります。
def __init__(self, parent):
print('Performing check: ' + self.TITLE)
# 呼び出し元の親クラスから値を取得します
self.verbose = parent.verbose