ロード・トゥ・ザ・ホワイトハッカー

ホワイトハッカーはじめました

SQLインジェクションの検出(エントロピー編)

ログ情報の数値化

こちらの書籍の7章にSQLインジェクションの検出方法が記載されている。

GitHub - oreilly-japan/ml-security-jp: 『セキュリティエンジニアのための機械学習』のリポジトリ

 

使用されているデータセットがこちらのHTTPリクエストのログ。

github.com

データの概要としては、

  • 通常データ:19,304件
  • 異常データ:11,763件

異常データの内訳は、

となっている。

ある程度、WEBアプリケーションの脆弱性に対する攻撃知識があれば、特定の文字列によって推測できるものもある。例えば、SQLインジェクションであれば、シングルクォーテーションの記号などが該当する。

書籍の中では、そのようにドメイン知識に基づいて特徴量を追加することと、単純に文字列を数値化する方法として、エントロピーを算出していた。

それ以外に、ドメイン知識に基づかない方法としてN-gramが紹介されていた。

エントロピーについて

シャノンのエントロピーを使って数値化します。公式は以下、というところでいきなり躓きます。

上記の式を分解していく。

この値は、情報量と確率(P)をかけたものの総和。

情報量は以下の公式で算出される。

確率(P)の算出方法について。

例えば、AAABCDEFGH、という8種類の文字からなる10桁の文字列があると仮定する。

1文字づつに区切って出現回数を算出すると以下になる。

A:3回

B~H:1回

 

これを文字数の10で割ると、文字の出現率、という確率(P)にできる。

A:0.3

B~H:0.1

 

情報量は、

A:1.73(-log₂0.3)

B~H:3.32(-log₂0.1)

となる。

 

エントロピーは、

A(0.3x1.73)+B(0.1x3.32)+C(0.1x3.32)+D(0.1x3.32)+E(0.1x3.32)+F(0.1x3.32)+G(0.1x3.32)+H(0.1x3.32)

=2.834

と計算される。

 

この計算を用いて、HTTPログのクエリ文字のエントロピーを算出して、文字列を数値化して、機械学習に使います。

 

以下がそのPythonのコード。

import numpy as np
import pandas as pd

# HTTPクエリストリングのエントロピーの計算
def H_entropy(x):
    prob = [ float(x.count(c)) / len(x) for c in dict.fromkeys(list(x)) ] 
    H = - sum([ p * np.log2(p) for p in prob ]) 
    return H

以下のサイトでは、説明付きで別のコードが紹介されています。

www.physics.okayama-u.ac.jp

 

実際にSQLインジェクションのデータと、通常のデータとではエントロピーの分布が異なる。

SQLインジェクションのデータの方がエントロピーが大きくなってたが、その理由がイマイチ良く分からない。

まとめ

特徴量エンジニアリングの一つとして、ログファイルの文字列からエントロピーを算出して数値化できる。