
以前記事の 1つで書いたOVAL言語とSCAPスキャナーの概念を研究する過程で、かなり深刻な問題、つまりOVAL言語でコンテンツを作成するための便利なツールの不足に遭遇しました。 いいえ、絶対に何もないと言っているのではありません。 公式ウェブサイトには、 ユーティリティの小さなセットが提示されています。 それらのほとんどは有料ですが、残りは非常に便利なソリューションではなく、 XML-Notepadに最もよく似ています 。 その結果、Pythonを言語として使用して、自分で作業するために必要な小さなツールを作成することにしました。
この選択は、Python言語が「迅速な開発言語」であるという評判と、サードパーティライブラリの豊富なパレットの存在によるものです。 言語のドキュメントを用意して、 MITREのアイデアを現実に再現しようとしました。 私自身の究極の目標は、OVAL言語のオブジェクトの実装と、それらのストレージとインデックス作成のためのシステムを設定することです。
主な問題は、収集した情報の保存方法の選択でした。 最初の(そして失敗した)ソリューションはSQLite 3でした。 私はこの悲しい経験を特に長引きしませんが、実践が示しているように、リレーショナルデータベースに予測不可能なツリーを格納することは私にとって非常に難しい作業です。 したがって、私はNoSQLデータベースに注目しました。 データベースの排他的使用に制限することを計画していたので、私の選択はZoDBに落ちました。 もちろん、この決定も急いでいた。 しかし、 MongoDBのリメイクはすでに手遅れでした。 したがって、さらに計算するために、 PersistentMapping()は実際には通常のdict()であることに注意したいと思います。 データベースによるハッシュマップの認識の不確実性を考慮して、私はハッシュマップと同じクラスのキーを使用しました。 PersistentList()はlist()と同等です。 この置換は、そのような構造をZoDBに保存するために必要です。 これは、データベースの内部ロジックが原因です。 データベースにクラスを保存するには、クラスがpersistent.Persistentクラスの子孫である必要があります。
さらに、変数、メソッド、クラスの非定型的な命名、および可能な「斜視」については、事前にご容赦ください。私は魔術師ではありません。ただ学習しています。 そして、喜んで、知識のある同僚からの修正やコメントを受け付けます。
不必要に大きなコードを引用しないように、すぐにソースcode.google.comへのリンクを提供します。
一般に、OVAL言語の構造を分析するとき、その主な機能は拡張性であることに注意しました。 独自の構造を入力する必要がある場合は、名前空間を定義するXSDに記述してください。 ほとんどの構造は典型的なデータセットを表しているため、各言語オブジェクト専用のクラスを作成することにしました。 この実装の主な目標は、データベースに便利に保存される情報のコンテナを作成することです。 したがって、 OBJECT要素はベースオブジェクトとして機能します。
#ユニバーサルオーバルオブジェクト
クラス oval_object (永続的。 永続的 ) :
def __init__ ( self ) :
自己 。 id = str ( )
自己 。 タグ = "オブジェクト"
自己 。 名前空間 = str ( )
自己 。 楕円 = str ( )
自己 。 バージョン = 0
自己 。 vHash = 0
自己 。 非推奨 = False
自己 。 変数 = PersistentList ( )
自己 。 notes = PersistentList ( )
自己 。 コメント = str ( )
自己 。 署名 = str ( )
def assign_id ( self 、UniqId ) :
自己 。 id = "oval:" + self oval + ":obj:" + str ( UniqId )
def hash ( self ) :
summ_hash = 0
summ_hash + = hash ( self。tag )
summ_hash + = hash ( self。namespace )
summ_hash + = hash ( self。comment )
var for selfの場合 。 変数 :
isinstance ( var、variable )の場合 :
summ_hash + = var。 ハッシュミー ( )
その他 :
例外を発生させます ( 「オブジェクト変数のエラー入力パラメーター」 )
summ_hashを返す
def hashme ( self ) :
自己 。 vHash = self ハッシュ ( )
自己を 返す 。 vHash
def clearme ( self ) :
ハッシュマップ= PersistentMapping ( )
var for selfの場合 。 変数 :
var。 クリアーム ( )
var_hash = var。 ハッシュミー ( )
var_hash がハッシュマップにない 場合 。 キー ( ) :
ハッシュマップ[ var_hash ] = なし
その他 :
自己 。 変数 削除 ( var )
このクラスは、 OVALのすべての基本要素のベースです。 Definition 、 Test 、 State、およびOval_variableは、このクラスの子孫になります。 要素を比較する可能性を実現するために、 hash()メソッド(すべてに共通)およびhashme() (子孫により再定義)が作成されました。
変数名からわかるように、すべての基本構造は静的に定義されています。 構造がわからない可能性のある子孫は動的です。 そのような「子孫」を実装するために、 Variableクラスを作成し、多くの点でElementTreeの Elementイデオロギーを繰り返しました。
クラス変数( persistent。Persistent ) :
def __init__ ( self 、tag = str ( ) 、body = str ( ) 、attributes = None 、variables = None ) :
属性でない 場合 :
自己 。 属性 = PersistentMapping ( )
変数でない場合:
自己 。 変数 = PersistentList ( )
isinstance で はない属性( attributes、PersistentMapping )の場合 :
属性= PersistentMapping (属性)
isinstance で はない変数( variables、PersistentList )の場合 :
変数= PersistentList (変数)
自己 。 タグ =タグ
自己 。 body = body
属性の場合 :
自己 。 属性 =属性
変数の場合:
自己 。 変数 =変数
自己 。 vHash = 0
def clearme ( self ) :
ハッシュマップ= PersistentMapping ( )
var for selfの場合 。 変数 :
var。 クリアーム ( )
var_hash = var。 ハッシュミー ( )
var_hash がハッシュマップにない 場合 。 キー ( ) :
ハッシュマップ[ var_hash ] = なし
その他 :
自己 。 変数 削除 ( var )
def hashme ( self ) :
summ_hash = 0
summ_hash + = hash ( self。tag )
summ_hash + = hash ( self。body )
自己の 場合 。 属性 :
selfの属性用 。 属性 。 キー ( ) :
summ_hash + = hash (属性) + hash ( self。attributes [属性] )
自己の 場合 。 変数 :
var for selfの場合 。 変数 :
isinstance ( var、variable )の場合 :
if var ! = 自己 :
summ_hash + = var。 ハッシュミー ( )
その他 :
例外を発生させます ( 「変数の入力パラメータにエラーがあります。自己追加しますか?」
自己 。 vHash = summ_hash
自己を 返す 。 vHash
OBJECTと同様に、ハッシュ計算機能が必要でした。 クラスの構造は、XML形式のデータベースの将来のアンロードを簡素化するために、 ElementTree.Elementに最大限に適合されます。
一般に、塗りつぶしに便利なオブジェクトのセットを取得しました。 ただし、それらを埋めるだけでは十分ではありません。独自のオブジェクトを作成する場合、新しいDefinitionsを埋めて保存するためのレギュレーター(この場合はMITER )の要件を満たす必要があります。 したがって、定義バージョンの変更を索引付けおよび制御するシステムが必要でした。 これを行うために、 oval_suite()クラスが作成されました。 メソッドの基本セット( put 、 get 、 delete 、 search 、 import_xml 、 export_xml )を実装します。これにより、コンテンツの処理が容易になり、上記の問題に悩まされることがなくなります。
oval_suite()の作成中に発生した特定の問題の1つは、大量のデータ(約100MB)を一度にXML形式にエクスポートしようとしたときにメモリが不足することでした。 したがって、この関数を実装するには、最終ファイルを段階的に作成し、 StackOverflowから借用した要素削除関数ElementTree.Elementを使用する必要がありました。
def _garbager ( self 、root ) :
リスト 内の要素( root )の場合 :
self ._garbager (要素)
根 クリア ( )
デルルート
一般に、PythonでOVALを操作するためのツールの概要があります。これは、セキュリティコンテンツを構築および作成するときに役立ちます。 このモジュールにより、セキュリティコンテンツをアセンブルし、バージョン管理と識別子の一意性を備えたデータベースに「パック」できます。
ご清聴ありがとうございました! 誰かがOVALのテーマに興味を持ち、これらの開発が彼に役立つことを願っています。