セキュリティ分野における DPI の活用事例

こんにちは。セキュリティ技術グループの@knqyf263です。
早いもので、新卒として入社してからもうすぐ一年が経とうとしています。

今回の記事はネットワークトラフィックからアプリケーションの種類を判定して社内通信の監視などに役立てよう!というものになります。

アプリケーション層の解析(L7解析)は一般的な話なので、セキュリティ関係者じゃなくても役に立つかと思います。

 

例えば、以下の画像の様な情報を取得できるようになります。

※本記事で利用する画像では、時刻や IPアドレス等をダミーのものに変更してあります。

セキュリティ技術グループの紹介

本題に入る前に簡単にセキュリティ技術グループについて紹介します(読み飛ばしてもOKです)。
自分は去年まで学生だったのですが、各社が何をやっているか知るのは難しいなと感じたので、少しでも役に立てば良いなと思って書くことにしました。

セキュリティ技術グループでは大きく分けて2つの業務を行っています。

 

1つ目は、脆弱性診断です。リリースされる前のWebサービスやスマートフォンアプリなどを診断し、脆弱性が見つかった場合は報告して修正してもらいます。他にも、サーバやネットワーク機器の脆弱性の確認も行っています。自動診断ツールも使いますが、見つからない脆弱性も多いので基本的には手動で実施します。手動診断に便利なプロキシツールなども内製しています。

2つ目は、社内セキュリティの強化です。IPA から報告書が出ていましたが、最近では内部不正によるインシデントが増えています。意図的ではなくても年金機構の流出事件のようにマルウェアの感染による情報流出の可能性もあります。標的型攻撃は手口が巧妙なため、社内に既にマルウェアが侵入しているぐらいの考えで対策をする必要があるかと思います。そのため、セキュリティ部では組織内部からの情報流出を防ぐために様々な取り組みを行っています。

今回はその中でも、ログ監視について紹介させていただきます。

ログ監視

最近では ElasticSearch + Fluentd + Kibana という構成でログを監視している企業が多いかと思いますが、セキュリティ技術グループでも同じ構成でログを収集しています。

他にも便利なツールなどを色々検証しており、今回はその中で nDPI について後ほど紹介します。

ログの種類は様々で、一部を挙げると以下の様なものがあります。

・Active Directory
・ファイルサーバ
・本番サーバへの踏み台サーバ
・Github Enterprise
・NetFlow
・Firewall, DNS, DHCP, VPN, etc…

他にも、会社独自のアプリケーションのログなどを収集して監視を行っています。

では実際に上記のうち、NetFlow を利用した社内通信のポート・ホストスキャン監視の一例を紹介します。
まず、社内の執務室におけるコアスイッチでミラーリングして NetFlow を取得します。
これらの NetFlow を fluentd に渡したあと、
Norikra で集計します。
以下の SQL は Norikra で宛先ポートを集計する例です(実際は会社の環境用にカスタマイズされています)。

SELECT
    ipv4_src_addr,
    COUNT(distinct l4_dst_port) AS uniq_dport
  FROM ext.win:time_batch(1 min)
  WHERE ipv4_src_addr LIKE '192.0.2.%'
  GROUP BY ipv4_src_addr
  HAVING COUNT (distinct l4_dst_port)

ソースIPアドレスごとに集計しているので、各社員のPCが1分間で通信した宛先ポート番号のユニーク数が計算されるようになっています。

そしてこれらの値が閾値を超えると Slack やメールで通知されるようになっています。

1分で241個のユニークなポート番号と通信するのは通常の用途ではなかなか考えにくいため、検知された IPアドレスについて Kibana のグラフを見てみます。

横軸が時間で縦軸が通信したポートのユニーク数です。
09:00~09:30の間に急激にポート数が増加していることが分かります。

では09:00~09:30に絞って実際に NetFlow のデータを見てみます。

確かに様々な IPアドレス・ポート番号と短期間に大量に通信をしているようです。
不審な通信であることまでは分かるのですが、ここから先の調査は難しいです。

なぜなら NetFlow ではヘッダなどの情報のみなので、実際にどのようなアプリケーションによる通信か分からないためです。

全パケットのペイロードも保存しておけば後で解析可能ですが、通信量が多い環境では現実的ではありません。

今までは、DNS のログなどと突き合わせたり、リアルタイムにパケットキャプチャしたりして何とか推測していました。

しかし頑張って調査した結果、「Skype なので問題ありませんでした。」ということも少なくありません。

また、社内から社外に対して VPN を張っていたり、SSH したりするのは好ましくないため(社外から社内へ到達できてしまう可能性がある)、なるべく検知したいと考えています。

これらに関しても上記同様、ヘッダ情報のみでは正確な検知は難しいです。

例えば22番ポートなら SSH、といったルールを書いておいても10022番ポートに変えて SSH されたら検知できません。

他にも、社内禁止ソフトの利用や踏み台サーバを経由しない DB への接続など、検知したい項目は多数ありますが、パケットのヘッダ情報からでは検知が難しいです。

DPI の導入検討

そこで、DPI(Deep Packet Inspection) 機器の利用を検討しました。

DPI ではIPパケットのデータ部分(ペイロード)の情報を検査し、アプリケーションの判別などが可能になっています。

次世代ファイアウォールと呼ばれる WAF などは DPI 機能を有しており、ペイロードに応じてフィルタ処理を決めることが可能です。

参考:DPIとは

ですが、DPI 機器はかなり高価なものが多いです。

どの程度有用なものかも不明なため、きちんとテストして導入となるとかなりの工数がかかることが予想されます。

また、近年では1つのログからインシデントを特定するのは困難なため、相関分析や横断分析など複数のログを組み合わせて検知するという試みが行われるようになっています。

セキュリティ技術グループでも複数のログを横断的に分析することでインシデント特定に役立てています。

他のログと同様に Elasticsearch に入れることを考えると、単に DPI 機器を購入すれば解決するわけでもなさそうです。

nDPI とは

もう少し気軽に DPI のセキュリティ分野における有用性を確かめたかったので、以前個人的に利用したことのあった nDPI を試してみることにしました。

ということで前置きが長くなりましたが、今回は nDPI の紹介となります。

nDPI はLGPLv3ライセンスで提供されている、オープンソース のDPI用ライブラリになります。

アプリケーション層の解析をしてくれるのですが、nDPI のWebページを見ると非常に多くのプロトコルに対応していることが分かります。

nDPI を用いることでアプリケーションが判別できれば、アラート調査の際にとても役立ちそうです。

nDPI の特徴としては、アプリケーションの判定がポート番号に依存しない点が挙げられます。

上記で述べたようにSSHは22番ポート、のようなルールで判定しているとポート番号が変わった際に正しく判定できなくなってしまいます。

しかし nDPI ではペイロードを見て判定するため、ポート番号が変わっても(10022番とか)正しく判定することができます。

nProbe が便利

nDPI を利用した製品に nProbe というソフトウェアがあります。

nProbe は NetFlow のプローブとして動作可能なため、NetFlow と同時にアプリケーション層の情報を収集できます。
また、Gbit のトラフィックでも問題なく解析できたり、
Splunk にエクスポートする機能があったり、多数の機能を備えているそうです。

nProbe はライセンスの購入が必要ですが、デモ版があり25000フローまでは試しに収集することが可能です。

詳細:http://www.ntop.org/wp-content/uploads/2013/03/nProbe_UserGuide.pdf

インストールも簡単で、ntop のリポジトリを追加して yum でインストールするだけです。

参考:http://packages.ntop.org/centos/

Elasticsearch へエクスポートするプラグインがあったので、そちらを試してみました。
localhost に Elasticsearch がある想定で以下のようなコマンドを打ちます。
エクスポートするカラムは自由に指定できます。

$ sudo nprobe --json-labels --elastic "nprobe;nprobe;http://127.0.0.1:9200/_bulk" -i eth0 -T "%IPV4_SRC_ADDR %L4_SRC_PORT %IPV4_DST_ADDR %L4_DST_PORT %PROTOCOL %IN_BYTES %OUT_BYTES %FIRST_SWITCHED %LAST_SWITCHED %HTTSITE %HTTP_RET_CODE %IN_PKTS %OUT_PKTS %IP_PROTOCOL_VERSION %APPLICATION_ID %L7_PROTO_NAME %ICMP_TYPE"

Kibana で見てみると以下のようにL7_PROTO_NAMEやHTTP_SITEなどが追加されていることが確認できました!

アラート対応の際にどのようなプロトコルか(上記だと HTTP)分かれば調査の時間が短縮できます。

一度 Elasticsearch に入れてしまえば集計して可視化したり統計を取ったりできるので、セキュリティ以外でも活用できると思います。

ネットワーク関係者など、社内ネットワークを流れるトラフィックのアプリケーションの統計が知りたい!と思っている方がいましたら nProbe の導入を検討してみると良いかと思います。

ndff の紹介

上記で nProbe の有用性について紹介してきましたが、セキュリティ技術グループでは nProbe はまだ利用していません。

理由としてはいくつかあるのですが、nProbe ほど多機能が必要ではなかったという点と、簡単に検証してから導入したかったという点などが挙げられます(デモ版の25000フローでは判断が難しかった)。

社内通信の監視においては、HTTP のステータスコードなどは不要で、アプリケーションの判定さえできればとりあえずは十分に思えました。

今後他に欲しい機能があれば nProbe を購入してプラグインを利用するかもしれませんが、まずはアプリケーション判定が有用か試したい、と考えました。

少機能であれば nDPI のライブラリを使って自分で作成できそうだったので、ndff というソフトウェアを作ってみました。

ndff は nDPI の有用性を確かめるために作ったもので、現在社内でテスト運用しています。
自分が1人で作ったものなので一切動作保証は出来ないですが、一応リポジトリは以下になります。

https://github.com/knqyf263/ndff

簡単に説明すると、pcap やインタフェースからパケットを取得してアプリケーションを nDPI で判定し、NetFlow 風にフローをまとめて fluentd に JSON か MessagePack で送るものになります。

nDPI が提供しているサンプルが良く出来ていたのでそれらをベースに、softflowd の NetFlow の実装を参考にして作りました。

社内通信は1Gbps程度ですが、以下のスペックのサーバ1台で問題なく動作しています。

OS:CentOS 6.7
CPU:Intel(R) Xeon(R) CPU  E5540  @ 2.53GHz
メモリ:8G
HDD:265GB

READMEに書いてありますが、簡単にインストール方法を説明します。
RPM を提供しているのでRedhat系のサーバなら簡単にインストールできると思います。

#必要なライブラリのインストール
$ sudo yum -y install libpcap msgpack json-c
#nDPIのインストール
$ sudo rpm -ivh
https://forensics.cert.org/centos/cert/6.5/x86_64/nDPI-1.7.1-1.el6.x86_64.rpm
#ndffのインストール
$ sudo rpm -ivh
https://github.com/knqyf263/ndff/releases/download/0.0.2/ndff-0.0.2-1.x86_64.rpm

パケットのミラーリングを受けているサーバなどで上記の様にインストールしてください。
ソースからビルドする場合は README を見てください。

オプションはいくつかあるのですが、基本的にキャプチャしたいインタフェース、送りたい fluentd のサーバのIPアドレス・ポート、あとはデータの形式(JSON か MessagePack)だけ指定しておけば良いです。

設定ファイルに書いて init スクリプトで起動すれば終了です。

$ sudo vim /etc/sysconfig/ndff
# Config file for ndff startup
# Options passed to the ndff program
OPTIONS="-i eth1,eth2 -s fluentd.server.local -p 24224 -t ndff.flow -m msgpack -q"

上記は eth1 と eth2 のインタフェースからパケットを取得し、fluentd.server.local に MessagePack形式でログを送信する例です。
ポート番号は24224番を指定し、fluentd のタグとしては ndff.flow を指定しています。

fluentd サーバ側では forward プラグインで待ち受けておけばよいです。
以下の例では受け取ったログを Elasticsearch に入れています。

<source>
  type forward
  port 24225
</source>
<match ndff.flow>
  type elasticsearch
  logstash_format true
  hosts localhost:9200
  type_name ndpi-log
</match>

では ndff を起動してみましょう。

$ sudo /etc/rc.d/init.d/ndffd start
Starting ndff:          [  OK  ]


$ sudo less /var/log/messages
…
Mar 16 17:56:46 capture-server ndff: [INFO] Capturing live traffic from device eth1…
Mar 16 17:56:46 capture-server ndff: [INFO] Capturing live traffic from device eth2…
Mar 16 17:56:46 capture-server ndff: [INFO] Running thread 1…
Mar 16 17:56:46 capture-server ndff: [INFO] Running thread 0...

上記のような syslog が出ていれば問題ないです。
正しくログが収集できていれば最初の画像のような情報が取得できているかと思います。

では実際にこれらの情報を用いてアラートについて調査をする場合を考えてみましょう。

アラート調査への活用

先程の不審な通信について調査することにします。
紹介する事例は実際にアラートが上がって調査した際の記録となります。
Kibana で表示すると以下の画像のように表示されました。

protocol_name を見ると BitTorrent となっています。
社内での P2P ソフトの利用は禁止されているので、より詳細な調査が必要ということが分かります。

nDPI-1.7.1-1.el6.x86_64.rpm でインストールした nDPI では bittorret_hash は取れませんが、最新版では取れるようになっています。そのため、ソースコードからビルドしたものを使えば上記の画像のようにハッシュが取れます。

「743bc6fad39e3a35460d31af5322c131dd196ac2」について調べると、Ubuntu 14.04 の ISO であることが分かりました。

悪用ではないものの、今後は使わないようにお願いしました。

続いて、別の日のポートスキャンのアラートについて調査してみます。

こちらは Skype と表示されており、問題ないように見えます。
実際、Skype のドメイン名にアクセスしていたりするため、Skype で間違いなさそうです(nDPI で SSL.Skype とか表示されたりします)。

SSH の場合も、ポートを変えても正しく認識されていることが分かります。
外部への SSH などでポートが変わっていても検知することが出来ます。

もちろん誤検知もあるため、プロトコル名から全てを判断するのは危険ですが、判断材料があることで調査しやすくなります。

実際、弊社では上記の仕組みをテスト運用してから検知できるインシデントの種類が増え、調査の時間も削減されました。

まとめ

今回は DPI によるアプリケーション判定の活用事例について説明しました。

本記事ではセキュリティの観点から有用性について書きましたが、社内を流れるトラフィックの種類が知りたい方(情シス関係者など)にも役立てていただけると思います。

精度に関してはたまに誤検知することはあるものの(Tor とかは誤検知されるので Issue あがってます)、判断材料の一つとしては有用であることが分かりました。

現在は ndff でテスト運用をしていますが、今後も DPI を利用し続けることになれば nProbe 等の導入なども検討しようと考えています。

もし他にも気軽に DPI を試してみたい方がいらっしゃいましたら nDPI を是非試してみてください!

最後までお読みいただきありがとうございました。