Boss of the SOC (BOTS) Investigation Workshop for Splunkのbotv1を使用してScenario #1_APTを順繰りやっていく2回目。
サイバーキルチェーンはここを参照。
前回が偵察(reconnaissance)で、今回がexploitation.
Finding the Average Length of the Passwords During the Brute Force Attack
ブルートフォースに使用されたパスワード長の平均値を調べてみる。
index=botsv1 sourcetype=stream:http http_method=POST
| rex field=form_data "passwd=(?<userpassword>\w+)"
| search userpassword=*
| eval mylen=len(userpassword)
| stats avg(mylen) as avg_len_http
| eval avg_len_http=round(avg_len_http,0)
これは、調査というよりSPLの使用方法の説明かな。
真ん中のsearch
はなくても結果は変化なし。検索時間は短くなる。
Determining The Elapsed Time Between Events
How many seconds elapsed between the time the brute force password scan identified the correct password and the compromised login rounded to 2 decimal places?
ブルートフォースパスワードスキャンが正しいパスワードを識別してから、侵害されたログインを小数点以下2桁に丸めるまでに経過した秒数は?
We now want to understand when the brute force attack gave the adversary the correct password and when the adversary used this password to get into the system. The good news is we have our search for the password extraction and we can build off of our earlier work. However, we need to bring time into our equation.
ここで、ブルートフォース攻撃によって攻撃者に正しいパスワードが与えられたタイミングと、攻撃者がこのパスワードを使用してシステムに侵入したタイミングを理解する必要があります。良いニュースは、パスワード抽出の検索機能があり、以前の作業から構築できることです。ただし、方程式に時間を組み込む必要があります。
Appsだといきなり_batman_で検索しているけど、まず、パスワードの試行状況を確かめてみる。
Search
index=botsv1 sourcetype=stream:http http_method=POST
| rex field=form_data "passwd=(?<userpassword>\w+)"
| eventstats count by userpassword
| stats earliest(_time) as f_time latest(_time) as l_time values(count) as count by userpassword
| foreach *_time [ eval <<FIELD>> = strftime(<<FIELD>>,"%Y-%m-%d %H:%M:%S")]
| sort - count
412個のパスワードが使用されて、2回使用されたものは_batman_というのがわかる。
Calculating a Time Difference Using the transaction Command and Duration Field
先の構文を変更して、2回以上使用されたパスワードについて、パスワード使用間隔を調べてみる。
index=botsv1 sourcetype=stream:http http_method=POST
| rex field=form_data "passwd=(?<userpassword>\w+)"
| eventstats count by userpassword
| search count > 1
| stats earliest(_time) as f_time latest(_time) as l_time values(count) as count by userpassword
| eval duration=l_time-f_time
| convert dur2sec(duration)
| foreach *_time [ eval <<FIELD>> = strftime(<<FIELD>>,"%Y-%m-%d %H:%M:%S")]
Appsだとtransaction
コマンドを使用して、duration
フィールドを表示しているけど、基本的にtransaction
は重いコマンドだし、まとめるフィールドがない場合、そのログが検索できないという問題がある。
というわけで、頑張ってstats
でやってみる。
3回以上の試行で、時間間隔を調査することになったら、
index=botsv1 sourcetype=stream:http http_method=POST
| rex field=form_data "passwd=(?<userpassword>\w+)"
| eventstats count by userpassword
| search count > 1
| stats values(_time) as time values(count) as count by userpassword
| mvexpand time
| autoregress time as last_time
| eval dur= time - last_time
| convert dur2sec(dur)
| eval time = strftime(time,"%Y-%m-%d %H:%M:%S")
とかで。autoregress
こんな使いかたできるのね。
Identifying the Number of Unique Passwords Attempted During the Brute Force Attack
前項でstats
を_userpassword_でまとめたので、dc
の結果が統計情報の数だし、count
の結果はeventstats
で数えた数の合計。計算めんどい時はaddcoltotals
にお任せ。
これでExploitationはおしまい。長くなったのでここまで。