SECURITY

脅威ハンティングにstats、eventstats、streamstatsコマンドを活用する方法

Splunkでサーチした経験があれば、少なくとも1回はstatsコマンドを使ったことがあるでしょう。結論から言うと、statsは、このブログシリーズのテーマである脅威ハンティングを行う上で欠かせない機能です。

Splunkドクターの画像

特定のデータセットを扱うときは、返されたフィールド値にstatsコマンドを使って計算することで、新たな情報を簡単に引き出すことができます。  ところで、ここで言う「stats」は次の3つのコマンドを指します。

多くのSplunkコマンドがそうであるように、これらは3つとも変換コマンド、つまり、取得した結果セットのデータに対して処理を実行するタイプのコマンドです。

では、statsについて詳しく見ていきましょう。

(この記事は「Splunkで脅威ハンティング」シリーズの一部であり、初稿はJohn Stonerが執筆しましたが、お客様に最大限の価値を提供できるよう、その内容を最近更新しました。)

脅威ハンティングでのstatsコマンドの使い方

statsコマンドは、基本的なSplunkコマンドです。フィールドに対してさまざまな統計関数を実行する機能を持ち、カウントや平均のようなシンプルな計算から、パーセンタイルや標準偏差のような高度な計算まで処理できます。 

statsコマンドでbyキーワードを使えば、1つのフィールドまたはフィールドのリストに基づいたグループごとに統計を計算できます。 

次の例は、ハンティングでstatsコマンドを使う基本的な方法を示しています。ここでは仮説として、特定のネットブロックで始まる送信元と宛先のペアの中で、接続数が最も多いペアを「怪しい」と考え、詳しく調査していきます。

sourcetype=fgt_traffic src=192.168.225.* NOT (dest=192.168.* OR dest=10.* OR dest=8.8.4.4 OR dest=8.8.8.8 OR dest=224.*)

| stats count by src dest

| where count > 1

| sort – count

statsコマンド

このサーチでは、まずファイアウォールデータから、送信元が192.168.225.0/24ネットブロックで、宛先が内部またはDNS以外のアドレスであるデータを抽出します。次にstatsコマンドとcount関数を使って、送信元/宛先ペアごとの接続数を集計します。続いて、その出力の中から、1回しか発生していないイベントを除外し、最後に結果を降順でソートします。

もう1つの例では、statsを使って値を合計する方法を示します。ここでは仮説として、ファイアウォールトラフィックの中で、外部ホストとの通信量が多い送信元を「怪しい」と考えます。通信量は、接続数ではなくバイト数を基準とします。statsコマンドでは、複数のフィールドの計算、名前変更、グループ分けをまとめて行うことができます。 

sourcetype=fgt_traffic src=192.168.225.* NOT (dest=192.168.* OR dest=10.* OR dest=8.8.4.4 OR dest=8.8.8.8 OR dest=224.*) 

| stats sum(bytes_in) as total_bytes_in sum(bytes_out) as total_bytes_out by src dest 

| table src dest total_bytes_in total_bytes_out 

| sort – total_bytes_out

statsを使って値を合計する方法

このサーチでは、前の例と同じデータセットを使用しますが、今回はstatsとsum関数を使って受信バイト数(bytes_inフィールド)と送信バイト数(bytes_outフィールド)をそれぞれ合計します。この出力結果を並べ替えるだけで、次のことがわかります。

  • 受信バイト数が特に多い送信元/宛先ペア 
  • 受信バイト数が特に少ない送信元/宛先ペア(こちらが「怪しい」という仮説も立てられるでしょう)

ちなみに、私が上記の結果セットを見たら、なぜ同じサブネット内の多くのホストが同じ宛先IPアドレスと通信し、しかも受信と送信のどちらのバイト数もすべて同じであるのかを不審に思うでしょう。とにかく重要なのは、statsにはさまざまな使い方があるということです。

eventstatsコマンド

基本を押さえたところで、その考え方に沿ってeventstatsを見ていきましょう。私はeventstatsを、結果セット内の「総計」を計算し、その後この総計を使用してデータセットをさらに観察する手法として使うのが好きです。

ここでは別の仮説として、ネットワーク外との通信で送信バイト数が多いシステムを「怪しい」と考え、該当するシステムを特定し、調査します。効果的にハンティングを行うために、次の2つの点に注目します。

  • 社内のシステムと通信するすべての外部ホスト 
  • 各ホストへの送信データ量

前述のサーチと同じ基本的なサーチ条件に、今回は送信バイト数(bytes_out)がゼロではないという条件を追加して、結果セットを絞り込みます。次に、eventstatsとsum関数を使って、送信元IPアドレスごとに送信バイト数の合計を計算し、結果のフィールド名をtotal_bytes_outに変更します。さらに、その出力をフィールド値として別のSplunkコマンドで処理します。

sourcetype=fgt_traffic src=192.168.225.* NOT (dest=192.168.* OR dest=10.* OR dest=8.8.4.4 OR dest=8.8.8.8 OR dest=224.*) bytes_out>0

| eventstats sum(bytes_out) AS total_bytes_out by src

| table src dest bytes_out total_bytes_out

| sort src – bytes_out

eventstatsコマンド

赤枠で囲んだ行内の送信元IPアドレスでは、各bytes_outの値の合計がtotal_bytes_outの値と等しいことがわかります。

さらに別の仮説を検証するため、トラフィックの60%以上が1つの宛先に向けられているシステムをeventstatsで調べます。特定のシステムがほぼ1つの外部ホストとしか通信していなければ、十分「怪しい」と考えられるため、詳しく調査する必要があります。

2つ前の例で、送信元/宛先IPアドレスのペアごとに送信バイト数の合計を計算し、通信量が多いペアを調べましたが、今回はさらに、送信元ごとの送信バイト数のうち、特定の宛先に送信されたバイト数の合計の割合(パーセント)を、eventstatsを使って調べます。

sourcetype=fgt_traffic src=192.168.225.* NOT (dest=192.168.* OR dest=10.* OR dest=8.8.4.4 OR dest=8.8.8.8 OR dest=224.*)

| eventstats sum(bytes_out) AS total_bytes_out by src

| stats sum(bytes_in) as bytes_in sum(bytes_out) as bytes_out values(total_bytes_out) as total_bytes_out by src dest

| eval percent_bytes_out = bytes_out/total_bytes_out * 100

| table src dest bytes_in bytes_out total_bytes_out percent_bytes_out

| where percent_bytes_out > 60

| sort - percent_bytes_out dest

特定の宛先に送信されたバイト数の合計の割合

前のサーチ条件を使用し、eventstatsとsum関数を使って、送信元IPアドレスごとに送信バイト数を合計して「総計」を求めます。 

ここで、前述のようにstatsを使ってデータを変換し、送信元/宛先IPペアごとにデータをまとめます。この時点で、ペアごとの受信バイト数の合計(bytes_in)、送信バイト数の合計(bytes_out)、送信元ごとの送信バイト数の合計(total_bytes_out)、送信元IP、宛先IPの値が得られます。 

これだけでも十分な情報ですが、現在の仮説を検証するには異常値を抽出する必要があります。

そこでevalコマンドを使って、bytes_outとtotal_bytes_outから、トラフィック全体に対する割合を計算します。次に、tableコマンドを使ってデータを整形し、割合が60%を超えるデータのみを抽出して、出力をソートします。

これで、1つの宛先に高い割合でデータを送信している送信元IPアドレスがわかったので、それらをさらに詳しく調査できます。実際、出力結果を見ると、上位14件の送信元アドレスはすべて同じ外部IPアドレスと通信していることがわかります。 

この外部アドレスをさらに詳しく調べ、問題がない場合はlookupコマンドを使ってこの宛先をホワイトリストに入れてもよいでしょう。このアプローチでサーチをさらに洗練させて、より高度な仮説を検証することもできます。

streamstatsコマンド

最後はstreamstatsです。streamstatsの基本はstatsと同じですが、このコマンドではイベントが発生するたびに統計を計算できます。結果セットにデータが追加されるたびに累計を求めたり平均を計算し直したりするときに大変便利です。

前述のハンティングの結果から、社内のシステムから外部ホストへの通信は同じタイミングで発生すると考えられます。streamstatsを使って通信量を可視化し、その仮説を検証してみましょう。

sourcetype=fgt_traffic src=192.168.225.80 NOT (dest=192.168.* OR dest=10.* OR dest=8.8.4.4 OR dest=8.8.8.8 OR dest=224.*) bytes_out>0

| sort date

| streamstats sum(bytes_out) as total_bytes_out by src

| table date bytes_out total_bytes_out

streamstatsコマンド

前述の例では、送信元IPアドレス192.168.225.80の全トラフィックの77%が特定の宛先に向けられていました。詳しく調査するため、このアドレスから送信されるデータ量を時系列で見てみます。

最初の基本サーチはこれまでとほぼ同じですが、1つ違うのは、送信元としてアドレス範囲ではなく特定のアドレスを指定している点です。 

情報を日単位で集計するために、日付順にソートします。次に、streamstatsとsum関数を使って、該当する送信元IPアドレスの送信バイト数の合計を計算し、結果のフィールド名をtotal_bytes_outに変更します。最後に、出力結果から、日付(date)、送信バイト数(bytes_out)、累計送信バイト数(total_bytes_out)を列とする表を生成します。

出力は表形式でもグラフ形式でも確認でき、グラフは折れ線グラフと面グラフを切り替えることができます。出力からわかるように、各日のbytes_outが前日のtotal_bytes_outに加算され、当日のtotal_bytes_outと等しくなっています。

stats、eventstats、streamstatsのその他の使い方

stats、eventstats、streamstatsはいずれも、結果セットを詳しく調査して環境内での外れ値を特定する場合に非常に便利です。このブログではネットワークトラフィックを対象に合計とカウントの関数を使用しましたが、ホストに関する分析や、標準偏差、中央値、パーセンタイルなどの統計にも活用できます。

Splunkはセキュリティチームをいつでも支援いたします。

最新の脅威ハンティング手法については、E-book『PEAK脅威ハンティングフレームワーク』もぜひご覧ください。

このブログはこちらの英語ブログの翻訳、阿部 浩人によるレビューです。

Tamara Chacon
Posted by

Tamara Chacon

Tamara is a member of Splunk's SURGe team, where she helps with the behind the scenes work for the team. Before joining Splunk, she worked as a network engineer.

TAGS
Show All Tags
Show Less Tags