1. はじめに 周知のとおり、ディープラーニングはコンピュータービジョン、自然言語処理、人工知能などの分野で大きな進歩を遂げており、セキュリティ分野でも登場し、実用化に向けて動き始めています。この記事で行った実験は、主にテキスト分類法とディープラーニングを使用してXSS攻撃を検出します。私は初心者なので、アルゴリズム自体を明確に理解していないのは避けられません。そのため、この記事では、シンプルで一般的な方法でアルゴリズムを紹介し、誤解を招かないようにあまり詳細を説明しません。 2. データセット セキュリティ分野の公開データセットは非常に少ないです。この記事で提供される実験データは、xssed からクロールされた 40,000 以上のブラック サンプル (ポジティブ サンプル) と、約 200,000 の通常の http get リクエスト レコード (ネガティブ サンプル) の 2 つの部分で構成されています。データのセキュリティを確保するために、URL 内のホスト、パス、その他の情報は削除され、ペイロード部分のみが保持されます。 上記データは URL エンコードされ、CSV 形式で保存されています。元データの一部は URL エンコードされているため、使用するには 2 回 URL デコードする必要があります。 良い例: - topic=http://gmwgroup.harvard.edu/techniques/ index .php?topic=<script>alert(document.cookie)</script>
- siteID= ';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">' ><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
- js='"
否定的な例: - _=1498584888937/&リスト=FU1804、FU0、FU1707、FU1708、FU1709、FU1710、FU1711、FU1712
- hid=sgpy-windows-generic-device-id&v=8.4.0.1062&brand=1&platform=6&ifbak=0&ifmobile=0&ifauto=1&type=1&filename=sgim_privilege.zip
- iid=11491672248&device_id=34942737887&ac=wifi&channel=huawei&aid=13&app_name=news_article&version_code=621&version_name=6.2.1&device_platform=android&ssmix=a&device_type=FDR-A03L&device_brand=HUAWEI&language=zh&os_api=22&os_version=5.1.1&uuid=860947033207318&openudid=fc19d05187ebeb0&manifest_version_code=621&resolution=1200*1848&dpi=240&update_version_code=6214&_rticket=1498580286466
3. 分詞 テキスト分類を使用する方法には、当然ながらテキストをセグメント化する方法が含まれます。上記の肯定的な例を観察して、人々がどのように XSS を識別するかを確認してください。パラメータには、実行可能な完全な HTML タグと DOM メソッドが含まれています。したがって、サポートされる単語分割の原則は次のとおりです。 一重引用符と二重引用符で囲まれた内容は「xss」です http/https リンク <script> タグ <>はじめに<h1 パラメータ名トピック= 関数本体アラート( 文字と数字で構成された単語 さらに、単語の分割数を減らすために、数字とハイパーリンクを正規化し、数字を「0」に、ハイパーリンクを http://u に置き換える必要があります。 実装されたコードは次のとおりです。 - def GeneSeg(ペイロード):
- ペイロード =ペイロード.lower ()
- ペイロード = unquote(unquote(ペイロード))
- ペイロード,num=re.subn(r '\d+' , "0" ,ペイロード)
- ペイロード、num=re.subn(r '(http|https)://[a-zA-Z0-9\.@&/#!#\?]+' 、 "http://u" 、ペイロード)
- r = '' '
- (?x)[\w\.]+?\(
- |\)
- | "\w+?"
- | '\w+?'
- |http://\w
- |</\w+>
- |<\w+>
- |<\w+
- |\w+=
- |>
- |[\w\.]+
- '' '
- nltk.regexp_tokenize(payload,r)を返す
単語分割後の正例: - [ 'topic=' , 'http://u' , '<script>' , 'alert(' , 'document.cookie' , ')' , '</script>' ]
- ')' 、 '>' 、 '> ' 、 '>' 、 ' <script>' 、 'alert(' 、 'string.fromcharcode(' 、 '0' 、 ' 0 ' 、 ' 0 ' 、 ' 0 ' 、 ' ) ' 、 ' alert (' 、 ' string.fromcharcode(' 、 '0' 、 '0' 、 '0' 、 '0' 、 ')' 、 ')' 、 ' alert (' 、 ' string.fromcharcode(' 、 '0' 、 '0' 、 '0' 、 ')' 、 ')' 、 ' alert (' 、 'string.fromcharcode(' 、 ' 0 ' 、 ' 0 ' 、 ' 0 ' 、 ' ) ' 、 ' )' 、 '> ' 、 '</script>' 、 '>' 、 '>' 、 '<script>' 、 'alert(' , 'string.fromcharcode(' , '0' , '0' , '0' , ')' , ')' , '</script>' ]
- ]
単語分割後の負の例: - [ '_=' 、 '0' 、 'list=' 、 'fu0' 、 'fu0' 、 'fu0' 、 'fu0' 、 'fu0' 、 'fu0' 、 'fu0' 、 'fu0' 、 'fu0' ]
- [ 'hid=' 、 'sgpy' 、 'windows' 、 'generic' 、 'device' 、 'id' 、 'v=' 、 '0.0.0.0' 、 'brand=' 、 '0' 、 'platform=' 、 '0' 、 'ifbak=' 、 '0' 、 'ifmobile=' 、 '0' 、 'ifauto=' 、 '0' 、 'type=' 、 '0' 、 'filename=' 、 'sgim_privilege.zip' ]
- 、 ' device_type = ' 、 ' fdr ' 、 ' a0l ' 、 ' device_brand = ' 、 ' huawei ' 、 ' language = ' 、 ' zh ' 、 ' os_api = ' 、 ' 0 ' 、 ' os_version = ' 、 ' 0.0.0 ' 、 'uuid=' 、 '0' 、 'openudid=' 、 'fc0d0ebeb0' 、 'manifest_version_code=' 、 '0' 、 'resolution=' 、 '0' 、 '0' 、 'dpi=' 、 '0' 、 'update_version_code=' 、 '0' 、 '_rticket=' 、 '0' ]
4. 埋め込み単語ベクトル セグメント化されたテキストを機械学習の問題に変換するにはどうすればよいでしょうか。最初のステップは、これらの単語を数学化する方法を見つけることです。最も一般的な方法はワンホットエンコーディングで、語彙を非常に長いベクトルとして表し、1つの次元のみが1の値を持ち、他の次元は0になります。たとえば、「<script>」は[0,0,0,1,0,0,0,0…….]と表されます。この方法の重要な問題は、テキストを構成するベクトルが非常にまばらで、単語が互いに独立しているため、機械学習が単語の意味を理解できないことです。埋め込み単語ベクトルは、テキストを学習し、単語を空間に埋め込むことで、意味が似ている単語間の距離を空間内で近づけることで、単語の意味情報を単語ベクトルで表します。空間ベクトルは、「マイク」や「マイク」などの同義語を表現でき、「猫」、「犬」、「魚」などの単語も空間内で一緒にクラスター化されます。 ここでは、マシンが <script> や alert() などの HTML 言語を理解できるように、埋め込み単語ベクトル モデルを使用して XSS のセマンティック モデルを構築する必要があります。ポジティブサンプルで最も頻繁に出現する 3000 語が選択され、語彙を形成します。その他の単語は「UKN」としてマークされ、gensim モジュールの word2vec クラスを使用してモデル化されます。単語空間の次元は 128 次元です。 コアコード: - def build_dataset(データ、単語):
- カウント= [[ "UNK" , -1]]
- counter=カウンター(単語)
- count .extend(counter.most_common(vocabulary_size-1))
- 語彙=[c[0] cの場合 カウント]
- データセット=[]
- データ内のデータの場合:
- d_set=[]
- データ内の単語:
- 語彙内の単語:
- d_set.append(単語)
- それ以外:
- d_set.append( "UNK" )
- カウント[0][1]+=1
- data_set.append(d_set)
- データセットを返す
- data_set = build_dataset(データ、単語)
- モデル=Word2Vec(データセット、サイズ=埋め込みサイズ、ウィンドウ=スキップウィンドウ、負の数=サンプル数、反復数=反復数)
- 埋め込み=モデル.wv
5. データ前処理 適切な単語ベクトル モデルを構築することで、空間ベクトルを使用してテキストを表すことができます。前のプロセスを組み合わせると、完全なプロセスは次のようになります。 最後に、すべてのデータはランダムに 70% のトレーニング データと 30% のテスト データに分割され、次の 3 つのニューラル ネットワークのトレーニングとテストに使用されます。コード例: - sklearn.model_selectionからtrain_test_split をインポートします
-
- トレーニングデータ、テストデータ、トレーニングラベル、テストラベル = トレーニングテスト分割 (データ、ラベル、テストサイズ = 0.3)
6. 多層パーセプトロン 多層パーセプトロン (MLP) は、入力層、出力層、および複数の隠れ層で構成されます。 Keras は、バックエンドとして Tensorflow を使用して、多層パーセプトロンを簡単に実装できます。アルゴリズム全体の精度は 99.9%、再現率は 97.5% です。コアコードは次のとおりです。 モデルのトレーニング: - deftrain(train_generator、train_size、input_num、dims_num):
- print( "トレインジョブを開始します!" )
- 開始 =時間.時間()
- 入力=InputLayer(入力シェイプ=(入力番号、寸法番号)、バッチサイズ=バッチサイズ)
- レイヤー1 = Dense(100、アクティベーション = "relu" )
- レイヤー2 = Dense(20, アクティベーション = "relu" )
- フラット化 = フラット化()
- layer3 = Dense(2, activation = "softmax" , name = "Output" )
- オプティマイザー=Adam()
- モデル=シーケンシャル()
- モデルを追加します(入力)
- モデルを追加(レイヤー1)
- model.add(ドロップアウト(0.5))
- モデルを追加(レイヤー2)
- model.add(ドロップアウト(0.5))
- モデル。追加(平坦化)
- モデルを追加(レイヤー3)
- 呼び出し = TensorBoard(log_dir = log_dir、write_grads = True 、histogram_freq = 1)
- model.compile(optimizer,loss= "categorical_crossentropy" ,metrics=[ "accuracy" ])
- model.fit_generator(train_generator、steps_per_epoch=train_size//batch_size、epochs=epochs_num、callbacks=[call])
テスト: - deftest(model_dir、test_generator、test_size、input_num、dims_num、batch_size):
- モデル = load_model(model_dir)
- ラベル_pre=[]
- ラベル_true=[]
- batch_num=テストサイズ//batch_size+1
- ステップ=0
- バッチの場合、test_generatorのラベル:
- len(labels)==batch_sizeの場合:
- labels_pre.extend(model.predict_on_batch(バッチ))
- それ以外:
- バッチ = np.concatenate((バッチ、np.zeros((バッチサイズ-長さ(ラベル)、入力数、ディメンション数))))
- labels_pre.extend(model.predict_on_batch(バッチ)[0:len(ラベル)])
- labels_true.extend(ラベル)
- ステップ+=1
- print( "%d/%dbatch" %(steps,batch_num))
- labels_pre = np.array(labels_pre).round()
- def to_y(ラベル):
- y=[]
- i が範囲(len(ラベル))内にある場合:
- ラベル[i][0]==1の場合:
- y.追加(0)
- それ以外:
- y.append(1)
- yを返す
- y_true = to_y(ラベルが真)
- y_pre=to_y(ラベルのpre)
- 精度= precision_score(y_true,y_pre)
- リコール = リコールスコア(y_true,y_pre)
- print( "精度スコアは: " , precision )
- print( "リコールスコアは:" ,recall)
7. リカレントニューラルネットワーク リカレント ニューラル ネットワークは、シーケンス内のコンテキスト知識を理解できる時間再帰ニューラル ネットワークです。このネットワークも Keras を使用して構築されています。最終モデルの精度は 99.5%、再現率は 98.7% です。コアコード: モデルのトレーニング: - 定義トレイン(トレインジェネレータ、トレインサイズ、入力数、ディメンション数):
- print( "トレインジョブを開始します!" )
- 開始 =時間.時間()
- 入力=InputLayer(入力シェイプ=(入力番号、寸法番号)、バッチサイズ=バッチサイズ)
- レイヤー1=LSTM(128)
- 出力= Dense(2, アクティベーション = "softmax" 、名前= "出力" )
- オプティマイザー=Adam()
- モデル=シーケンシャル()
- モデルを追加します(入力)
- モデルを追加(レイヤー1)
- model.add(ドロップアウト(0.5))
- model.add (出力)
- 呼び出し = TensorBoard(log_dir = log_dir、write_grads = True 、histogram_freq = 1)
- model.compile(optimizer,loss= "categorical_crossentropy" ,metrics=[ "accuracy" ])
- model.fit_generator(train_generator、steps_per_epoch=train_size//batch_size、epochs=epochs_num、callbacks=[call])
tensorboard を使用してネットワークを視覚化します。 8. 畳み込みニューラルネットワーク MLP ネットワークと比較すると、畳み込みニューラル ネットワーク (CNN) は、トレーニングが必要なパラメータの数と計算量を削減します。同時に、分析のための深い特徴を洗練することができます。ここでは、Google VGG に似た 1 次元畳み込みニューラル ネットワークが使用されています。これには、4 つの畳み込み層、2 つの最大プーリング層、および 1 つの完全接続層が含まれます。最終的な精度は 99.5%、再現率は 98.3% です。コア コードは次のとおりです。 - deftrain(train_generator、train_size、input_num、dims_num):
- print( "トレインジョブを開始します!" )
- 開始 =時間.時間()
- 入力=InputLayer(入力シェイプ=(入力番号、寸法番号)、バッチサイズ=バッチサイズ)
- レイヤー1 = Conv1D(64,3,アクティベーション = "relu" )
- レイヤー2 = Conv1D(64,3,アクティベーション = "relu" )
- レイヤー3 = Conv1D(128,3,アクティベーション = "relu" )
- レイヤー4 = Conv1D(128,3,アクティベーション = "relu" )
- レイヤー5 = 高密度 (128、アクティベーション = "relu" )
- 出力= Dense(2, アクティベーション = "softmax" 、名前= "出力" )
- オプティマイザー=Adam()
- モデル=シーケンシャル()
- モデルを追加します(入力)
- モデルを追加(レイヤー1)
- モデルを追加(レイヤー2)
- model.add (MaxPool1D(pool_size=2))model.add ( Dropout(0.5))
- モデルを追加(レイヤー3)
- モデル追加(レイヤー4)
- モデルを追加します(MaxPool1D(pool_size=2))
- model.add(ドロップアウト(0.5))
- モデルを追加します(Flatten())
- モデルを追加(レイヤー5)
- model.add(ドロップアウト(0.5))
- model.add (出力)
- 呼び出し = TensorBoard(log_dir = log_dir、write_grads = True 、histogram_freq = 1)
- model.compile(optimizer,loss= "categorical_crossentropy" ,metrics=[ "accuracy" ])
- model.fit_generator(train_generator、steps_per_epoch=train_size//batch_size、epochs=epochs_num、callbacks=[call])
IX. 結論 この記事では、埋め込み単語ベクトルを使用して XSS セマンティック認識モデルを構築する方法を紹介し、MLP、リカレント ニューラル ネットワーク、畳み込みニューラル ネットワークの 3 つのアルゴリズムを使用して XSS 攻撃を検出します。3 つのアルゴリズムはすべて良好な結果を達成しています。 |