SplunkでJPCERTログ分析トレーニング（ハンズオン　その１）

https://blogs.jpcert.or.jp/ja/2020/07/log_analysis_training.html
で「インシデント対応ハンズオン」でやってきたデータが公開されたのでSplunkでやってみる。

2020/08/12 準備その３で`CommandLine`が上手く抽出できていなかったので、`transforms.conf`を修正

#準備
https://jpcertcc.github.io/log-analysis-training/
から
https://github.com/JPCERTCC/log-analysis-training
に飛んで、
`git clone https://github.com/JPCERTCC/log-analysis-training.git`

レポジトリがダウンロードできるので
`tar cvf Handson1.tar.gz Handson1` で固めて、そのままSplunkにファイルアップロード。設定は全部デフォルト。
:sweat:本当に適当

```sql:check.spl
source="Handson1.tar.gz:*"
```
で結果がでれば大丈夫。
:koala:フィールド抽出は？


#準備その２
感想とか見て、やっぱりフィールドを抽出したほうがいいと思ったので、props.confを書いてみた

##Security.csv
```configuration:props.conf
[security_csv]
FIELD_NAMES = level,date,source,eventID,category,data
INDEXED_EXTRACTIONS = csv
LINE_BREAKER = ([\r\n]+)情報
NO_BINARY_CHECK = true
SEDCMD-trim = s/^レベル.*//
SHOULD_LINEMERGE = false
category = Structured
description = CSV
disabled = false
pulldown_type = true
```

```sql:field_exstraction.spl
source="Security.csv" sourcetype="security_csv" 
| rex field=data max_match=0 "(?m)^\s+(?<name>[^:]+):\s+(?<value>\S+)$"
| rex field=data "(?m)(?<message>^.*)"
| rex field=name mode=sed "s/(?m)^(.*)$/\"\1\"/g" 
| rex field=value mode=sed "s/(?m)^(.*)$/\"\1\",/g s/\\\/¥/g" 
| eval tmp=mvzip(name,value,": ") 
| nomv tmp 
| eval tmp=rtrim(tmp,",") 
| eval json="{".tmp."}" 
| spath input=json
| fields - tmp json data name value
```

`kv`が使えなかっため、無理やりJSON
途中の`s/\\\/¥/g`はパスの`\`が悪さをしていたので、windows表記に変換しています。

これで、左側にずらっと日本語フィールドが出てきます。
:sweat:こんなにフィールドあったのね

これでSplunkっぽく調査が可能

#準備その３
SPLでいっぱいやるより、やっぱり最初からフィールド抽出がしたい

```configuration:props.conf
[security_csv]
FIELD_NAMES = level,date,source,eventID,category,data
INDEXED_EXTRACTIONS = csv
LINE_BREAKER = ([\r\n]+)情報
NO_BINARY_CHECK = true
PREAMBLE_REGEX = 日付と時刻
SHOULD_LINEMERGE = false
category = Structured
disabled = false
pulldown_type = true
SEDCMD_id = s/\sID:/_ID:/g s/\"+//g
TRANSFORMS-kv = security_kv1, security_kv2
```

```configuration:transforms.conf
[security_kv1]
INGEST_EVAL = data:=replace(data,"\"+","")
WRITE_META = true

[security_kv2]
SOURCE_KEY = field:data
REGEX = (?m)^\s*(?<name>[^:]+):[\t ]+(?<value>.+)$
FORMAT = "$1"::"$2"
REPEAT_MATCH = true
WRITE_META = true
```

:heart_eyes: `props.conf`と`transforms.conf`を先に書いておいてデータをアップロードした時設定したときフィールドが抽出されているのが嬉しい。

```sql:search.spl
source="Security.csv"
```
これで左側にもいっぱいフィールドが抽出される。

なお、いったん取り込んだデータを再度取り込み直したいときは

```sql:delete.spl
source="Security.csv"
| delete
```
で消して再取り込み。

`props.conf`と`transforms.conf`を修正した時は再設定を忘れずに。

:sweat: これを作るのに１０回は繰り返してます。

:koala:　transforms.confを頑張ったので`zip -r Handson1.zip ./Handson1`で固めてアップロード、ソースタイプを`security_csv`に設定でも動くよ。



#報告書
いつでも便利なJPCERTの報告書。今回も適宜みることになる。
[第１版](https://www.jpcert.or.jp/research/20160628ac-ir_research.pdf)
[第２版](https://www.jpcert.or.jp/research/20171109ac-ir_research2.pdf)
[ツール分析結果シート](https://jpcertcc.github.io/ToolAnalysisResultSheet_jp/)
#マルウェアの通信先IPアドレスを特定してください
log-analysis_handson.pdf　を見つつ実施する。
`win.exe`をウィルス検知したということなので、

```sql:win_exe.spl
source="Handson1.tar.gz:*" win.exe 
| rex "(?ms)(?<level>[^,]+),(?<date>[^,]+),(?<source>[^,]+),(?<eventID>\d+),(?<category>.*)" 
| reverse
```
で結果を確認してみる。
フィールド抽出は説明通りにしている。

ログがでてくるので、もう一つの情報`Win7_64JP_01`のIPアドレス`192.168.16.101`を追加して検索する。
ついでに宛先アドレスも抽出してみる。

```sql:dest.spl
source="Handson1.tar.gz:*" win.exe 192.168.16.101
| rex "(?ms)(?<level>[^,]+),(?<date>[^,]+),(?<source>[^,]+),(?<eventID>\d+),(?<category>.*)" 
| reverse
| rex field=category "宛先アドレス:\s*(?<dest>\S+)"
```

`dest`フィールドに値が抽出される。　:sweat:あってた。

#マルウエアの動作開始時刻とマルウエアの実行方法を特定してください。
いったん検索を戻してみる

```sql:win_exe.spl
source="Handson1.tar.gz:*" win.exe 
| rex "(?ms)(?<level>[^,]+),(?<date>[^,]+),(?<source>[^,]+),(?<eventID>\d+),(?<category>.*)" 
| reverse
```

ログをつらつら見ていくと、`Security.csv`と`Sysmon.csv`の両方にログがでている時間があり、そこでコマンドが実行されているのがわかる。

`cmd.exe /c ....` が`C:\Windows\System32\taskeng.exe`　*Task Scheduler Engine*に登録されて、動作していることがわかる。
報告書第１版のP22を見ても、これで合っていると思う。


```sql:answer.spl
source="Handson1.tar.gz:*" win.exe 
| rex "(?ms)(?<level>[^,]+),(?<date>[^,]+),(?<source>[^,]+),(?<eventID>\d+),(?<category>.*)" 
| reverse
| search eventID=4688
```
とかでもいいみたいです。

#攻撃者はWin7_64JP_01から別のマシンに侵入を試みています。侵入を試みた別の端末(ホスト名orIPアドレス)を特定してください。

ヒントをみると`net use`がキーワードらしい

```sql:commandline.spl
source="Handson1.tar.gz:*" "Microsoft-Windows-Sysmon" "chiyoda.tokyo"| rex "(?ms)(?<level>[^,]+),(?<date>[^,]+),(?<source>[^,]+),(?<eventID>\d+),(?<category>.*)"  | reverse
| rex field=category "CommandLine:\s*(?<CommandLine>.*)"
| stats count by CommandLine
| sort - count
```
一覧を出して、確認するとホスト名が出てくる
`ping`は別なIPアドレスに打っているけど、これは侵入ではないよな。　
:sweat:これまたなんとか

#攻撃者はWin7_64JP_01に別のマシンから侵入しています。不正ログオン元のIPアドレスと使用されたアカウント名は何ですか？
```sql:win_exe.spl
source="Handson1.tar.gz:*" win.exe 
| rex "(?ms)(?<level>[^,]+),(?<date>[^,]+),(?<source>[^,]+),(?<eventID>\d+),(?<category>.*)" 
| reverse
```
また、最初の検索に戻って、一番最初のログをみると、送信元のIPアドレスとアカウント名が出ている。
:sweat:Splunkだとこうなります。
#Win7_64JP_01でPowerShellファイルが実行されたようです。このファイルは何を行うものですか？
```sql:ps.spl
source="Handson1.tar.gz:*" .ps1
| rex "(?ms)(?<level>[^,]+),(?<date>[^,]+),(?<source>[^,]+),(?<eventID>\d+),(?<category>.*)" 
| reverse
```
powershellなので`.ps1`で検索
コマンドが出てくるので、見てみるとwebか〜
８個のイベントを見てみると２個のファイルダウンロードが確認できる。

#準備その２をした人向け

まずは日本語のフィールドを全て選択して、表示させる。

```sql:win_exe.spl
source="Security.csv" sourcetype="security_csv"
| rex field=data max_match=0 "(?m)^\s+(?<name>[^:]+):\s+(?<value>\S+)$" | rex field=data "(?m)(?<message>^.*)" 
| rex field=name mode=sed "s/(?m)^(.*)$/\"\1\"/g"  
| rex field=value mode=sed "s/(?m)^(.*)$/\"\1\",/g s/\\\/¥/g"  
| eval tmp=mvzip(name,value,": ")  | nomv tmp  
| eval tmp=rtrim(tmp,",")  | eval json="{".tmp."}"  
| spath input=json | fields - tmp json data name value
| search win.exe
| reverse
```

左側に抽出されている気になるフィールドの値を見つつ

- クリックして調査
- ブラウザーで戻る
- タイムラインを絞る
- `| search "調べたいこと" OR "調べたいことsono２"`を追加してみる。

とかを繰り返していく。

フィールドは`オブジェクト名`がお薦めです。

#準備その３をした人むけ

`新しいプロセス名`とか、`アカウント名`とかクリックしていくことになります。

#まとめ
ハンズオン資料が`grep`メインに対して、Splunkの場合フィールド抽出すれば俯瞰もできるし時間も絞れるので楽だと思います。

その２はまたの機会に