Hayabusaの検知結果をElastic Stackで可視化してみた

Hayabusaの検知結果をElastic Stackで可視化してみました。

## Hayabusaとは？

[Yamato Security](https://github.com/Yamato-Security/)によって作成されたWindowsログの解析ツールです。[Sigma](https://github.com/SigmaHQ/Sigma)ルールが使えたり、Rustで実装されてるため高速に動作します。

https://github.com/Yamato-Security/hayabusa

## Elastic Stackとは？

検索エンジンの[Elasticsearch](https://github.com/elastic/elasticsearch)、可視化を行う[Kibana](https://github.com/elastic/kibana)、データシッパーである[Beats](https://github.com/elastic/beats)/[Logstash](https://github.com/elastic/logstash)から構成されているソフトウェア群の総称です。

https://github.com/elastic

## インストール

以下のバージョンをインストールします。

|Name|Version|
|---|---|
|Hayabusa|1.0.0R2(v1.0.0 Initial Public Release 2 Latest)|
|Elastic Stack|8.0.0.rc1(First release candidate of 8.0.0)|

### Hayabusa

Hayabusaをインストールします。せっかくなので、ソースコードからコンパイルします。

```console
$ git clone https://github.com/Yamato-Security/hayabusa
$ cd hayabusa
$ git checkout -b v1.0.0-R2 refs/tags/v1.0.0-R2
```

READMEに記載の通り、cargoを使います。

> ソースコードからのコンパイル（任意）
>
> rustがインストールされている場合、以下のコマンドでソースコードからコンパイルすることができます:
> 
> cargo clean
> cargo build --release

さっそくコンパイルします。

```console
$ cargo --version
cargo 1.58.0
$ cargo clean
$ cargo build --release
<snip>
    Finished release [optimized] target(s) in 11m 59s
```

以下の通り、Usageが出力されれば成功です。

```console
$ ./target/release/hayabusa -h
hayabusa 1.0.0
Yamato-Security(https://github.com/Yamato-Security/hayabusa)
Hayabusa: Aiming to be the world's greatest Windows event log analysis tool!

USAGE:
    -d --directory=[DIRECTORY] 'Directory of multiple .evtx files'
    -f --filepath=[FILEPATH] 'File path to one .evtx file'
    -r --rules=[RULEDIRECTORY] 'Rule file directory (default: ./rules)'
    -o --output=[CSV_TIMELINE] 'Save the timeline in CSV format. Example: results.csv'
    -v --verbose 'Output verbose information'
    -D --enable-deprecated-rules 'Enable sigma rules marked as deprecated'
    -n --enable-noisy-rules 'Enable rules marked as noisy'
    -m --min-level=[LEVEL] 'Minimum level for rules (default: informational)'
    --start-timeline=[STARTTIMELINE] 'Start time of the event to load from event file. Example: '2018/11/28 12:00:00 +09:00''
    --end-timeline=[ENDTIMELINE] 'End time of the event to load from event file. Example: '2018/11/28 12:00:00 +09:00''
    --rfc-2822 'Output date and time in RFC 2822 format. Example: Mon, 07 Aug 2006 12:34:56 -0600'
    --rfc-3339 'Output date and time in RFC 3339 format. Example: 2006-08-07T12:34:56.485214 -06:00'
    -u --utc 'Output time in UTC format (default: local time)'
    -t --thread-number=[NUMBER] 'Thread number (default: optimal number for performance)'
    -s --statistics 'Prints statistics of event IDs'
    -q --quiet 'Quiet mode. Do not display the launch banner'
    -Q --quiet-errors 'Quiet errors mode. Do not save error logs.'
    --contributors 'Prints the list of contributors'

FLAGS:
        --contributors               Prints the list of contributors
    -D, --enable-deprecated-rules    Enable sigma rules marked as deprecated
    -n, --enable-noisy-rules         Enable rules marked as noisy
    -h, --help                       Prints help information
    -q, --quiet                      Quiet mode. Do not display the launch banner
    -Q, --quiet-errors               Quiet errors mode. Do not save error logs.
        --rfc-2822                   Output date and time in RFC 2822 format. Example: Mon, 07 Aug 2006 12:34:56 -0600
        --rfc-3339                   Output date and time in RFC 3339 format. Example: 2006-08-07T12:34:56.485214 -06:00
    -s, --statistics                 Prints statistics of event IDs
    -u, --utc                        Output time in UTC format (default: local time)
    -V, --version                    Prints version information
    -v, --verbose                    Output verbose information

OPTIONS:
    -d, --directory <DIRECTORY>             Directory of multiple .evtx files
        --end-timeline <ENDTIMELINE>        End time of the event to load from event file. Example: '2018/11/28 12:00:00
                                            +09:00'
    -f, --filepath <FILEPATH>               File path to one .evtx file
    -m, --min-level <LEVEL>                 Minimum level for rules (default: informational)
    -o, --output <CSV_TIMELINE>             Save the timeline in CSV format. Example: results.csv
    -r, --rules <RULEDIRECTORY>             Rule file directory (default: ./rules)
        --start-timeline <STARTTIMELINE>    Start time of the event to load from event file. Example: '2018/11/28
                                            12:00:00 +09:00'
    -t, --thread-number <NUMBER>            Thread number (default: optimal number for performance)
```

バージョン情報が`1.0.0R2`になるかと思ったのですが、`1.0.0`のままでした。

### Elastic Stack

いつも使っている[docker-elk](https://github.com/deviantony/docker-elk)を使おうとしたのですが、プルリクに8.0.0-rc1があったので、こちらを試しました。

https://github.com/deviantony/docker-elk/pull/544

```console
$ git clone https://github.com/antoineco/docker-elk
$ cd docker-elk
$ git checkout -b future origin/future
$ cat .env
ELK_VERSION=8.0.0-rc1
```

今回は、ElasticsearchとKibanaのみなので、以下の通り実行します。

```console
$ docker-compose up -d elasticsearch kibana
```

起動確認を行います。

```console
$ curlie localhost:9200 -u elastic -p
Enter host password for user 'elastic':
HTTP/1.1 200 OK
X-elastic-product: Elasticsearch
content-type: application/json
content-length: 543

{
    "name": "72c921347487",
    "cluster_name": "docker-cluster",
    "cluster_uuid": "CYj4tTfrSWqXV_KyeHtHBQ",
    "version": {
        "number": "8.0.0-rc1",
        "build_flavor": "default",
        "build_type": "docker",
        "build_hash": "801c2ac52575b00aabc6d7e9763a74f189b2eea9",
        "build_date": "2022-01-05T17:50:51.186278954Z",
        "build_snapshot": false,
        "lucene_version": "9.0.0",
        "minimum_wire_compatibility_version": "7.17.0",
        "minimum_index_compatibility_version": "7.0.0"
    },
    "tagline": "You Know, for Search"
}
```

Elasticsearchは大丈夫そうです。次にKibanaの起動確認を行います。

```console
$ curlie -I localhost:5601/status
HTTP/1.1 302 Found
location: /login?next=%2Fstatus
x-content-type-options: nosniff
referrer-policy: no-referrer-when-downgrade
kbn-name: kibana
kbn-license-sig: 099d13d615870c660826128b364d3f3a2ba4ddfd99be40bcf937ad84f0bbb2ab
cache-control: private, no-cache, no-store, must-revalidate
content-length: 0
Date: Fri, 28 Jan 2022 18:33:29 GMT
Connection: keep-alive
Keep-Alive: timeout=120
```

起動確認ができました。

## イベント検知

さっそくイベント検知を試してみます。Hayabusaはリリースに合わせてEVTXのサンプルも公開しており、簡単に動作確認が行なえますのでダウンロードします。

https://github.com/Yamato-Security/hayabusa-sample-evtx

```console
$ git clone https://github.com/Yamato-Security/hayabusa-sample-evtx
$ cd hayabusa-sample-evtx
$ git log --oneline
1af5825 (HEAD -> main, origin/main, origin/HEAD) first upload
```

データの準備ができたので、さっそく実行します。

```console
❯ ./target/release/hayabusa --directory ../hayabusa-sample-evtx --output results.csv

██╗  ██╗ █████╗ ██╗   ██╗ █████╗ ██████╗ ██╗   ██╗███████╗ █████╗ 
██║  ██║██╔══██╗╚██╗ ██╔╝██╔══██╗██╔══██╗██║   ██║██╔════╝██╔══██╗
███████║███████║ ╚████╔╝ ███████║██████╔╝██║   ██║███████╗███████║
██╔══██║██╔══██║  ╚██╔╝  ██╔══██║██╔══██╗██║   ██║╚════██║██╔══██║
██║  ██║██║  ██║   ██║   ██║  ██║██████╔╝╚██████╔╝███████║██║  ██║
╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝╚═════╝  ╚═════╝ ╚══════╝╚═╝  ╚═╝
   by Yamato Security 

Analyzing event files: 509
Sigma rules: 1146
Hayabusa rules: 49
Ignored rules: 29
Rule parsing errors: 0
Total enabled detection rules: 1195

509 / 509 [==============================================================] 100.00 % 

Total detections: 10072
Total critical detections: 134
Total high detections: 1350
Total medium detections: 449
Total low detections: 3725
Total informational detections: 4414
Total undefined detections: 0
Unique rules: 289
Unique critical rules: 28
Unique high rules: 136
Unique medium rules: 74
Unique low rules: 30
Unique informational rules: 21
Unique undefined rules: 0

Elapsed Time: 00:00:35.323
```

デフォルトで動作結果のサマリが出力される親切設計になっていました。

なお、検知結果ファイルは以下の通りでした。

```console
$ head -n 2 results.csv
Timestamp,Computer,EventID,Level,RuleTitle,Details,RulePath,FilePath
2013-10-24 01:16:13.843 +09:00,37L4247D28-05,4624,informational,Logon Type 0 - System,Bootup,rules/hayabusa/default/events/Security/Logons/4624_LogonType-0-System.yml,../hayabusa-sample-evtx/DeepBlueCLI/many-events-security.evtx
```

## 可視化

検知結果ファイルができたので、さっそく可視化していきます。CSVファイルでサイズも小さいのでKibanaにそのままアップロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344050/4458216f-7cd4-3f7d-cf09-edf32d426007.png)

タイムスタンプ形式をあわせたり取り込み設定をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344050/5f99e3ef-ec09-ce22-6394-d60d62b991c0.png)

先程の画面だと細かい設定ができなかったので、取り込み前に詳細な設定をします。

- Index name: `hayabusa`
- Data view name[^1]: `hayabusa`
- Index settings
  - シングル構成のため、`"number_of_replicas": 0`を設定しないと、`Index status: yellow`になるため忘れずに設定をします。
- Mappings
  - 集計に使用したいので、`hayabusa.rule.title`のデータタイプを`keyword`に変更します。
  - `Timestamp`フィールドを削除します。
- Ingest pipeline
  - デフォルトだと`message`フィールドを削除しているため、残すようにします。
  - `Timestamp`フィールドを削除するように設定します。(`@timestamp`として残しているので不要です)   

[^1]: 7.xまでの Index Patternに相当 https://www.elastic.co/guide/en/kibana/8.0/data-views.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344050/9d679f2e-ae34-ead8-6ce2-583a7ce94dcc.png)

しばらくすると、以下の通りデータの取り込みに成功します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344050/7661e3b3-3f1e-f763-c738-80642bf6998f.png)

Discoverで登録データの確認をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344050/d628d817-d6f9-d08f-f191-56eb84c2dc80.png)

`10,072 hits`が表示されており、問題なく取り込めたことが確認できました。

---

データが取り込めたので、ダッシュボードを作成し可視化をしてみると、全容が見えてきました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344050/f55470d1-012b-ce72-2476-05615941036a.png)

(rc1を使ったので、心配でしたが目的が達成できて安心しました。)

## おまけ

`hayabusa`のヘルプを眺めていたら、`--contributors`オプションがありましたので、実行したところコントリビューター一覧が表示されました！いいオプションです！

```console
$ ./target/release/hayabusa --contributors

██╗  ██╗ █████╗ ██╗   ██╗ █████╗ ██████╗ ██╗   ██╗███████╗ █████╗ 
██║  ██║██╔══██╗╚██╗ ██╔╝██╔══██╗██╔══██╗██║   ██║██╔════╝██╔══██╗
███████║███████║ ╚████╔╝ ███████║██████╔╝██║   ██║███████╗███████║
██╔══██║██╔══██║  ╚██╔╝  ██╔══██║██╔══██╗██║   ██║╚════██║██╔══██║
██║  ██║██║  ██║   ██║   ██║  ██║██████╔╝╚██████╔╝███████║██║  ██║
╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝╚═════╝  ╚═════╝ ╚══════╝╚═╝  ╚═╝
   by Yamato Security 

Hayabusa was possible thanks to the following people (in alphabetical order):

Akira Nishikawa (@nishikawaakira): Previous lead developer, core hayabusa rule support, etc...
Garigariganzy (@garigariganzy31): Developer, event ID statistics implementation, etc... 
ItiB (@itiB_S144) :  Core developer, sigmac hayabusa backend, rule creation, etc...
James Takai / hachiyone(@hach1yon): Current lead developer, tokio multi-threading, sigma aggregation logic, sigmac backend, rule creation, sigma count implementation etc…
Kazuminn (@k47_um1n): Developer
Tsubokku (@ytsuboi0322): Translations
Yusuke Matsui (@apt773): AD hacking working group leader, rule testing, documentation, research, support, etc...
Zach Mathis (@yamatosecurity, Yamato Security Founder): Project leader, tool and concept design, rule creation and tuning, etc…


Hayabusa would not have been possible without first creating RustyBlue, so we would also like to thank the RustyBlue contributors:

Zach Mathis (@yamatosecurity, Yamato Security Founder): Project Leader
Nishikawa Akira (@nishikawaakira): Lead Developer
Kazuminn (@k47_um1n): Core Developer
itiB (@itiB_S144): Core Developer
James Takai / hachiyone (@hach1yon): Core Developer
garigariganzy (@garigariganzy31): Developer
7itoh (@yNitocrypto22): Developer
dai (@__da13__): Developer
siam (@siamease): Developer
mimura (@mimura1133): Developer
Yusuke Matsui (@apt773): AD hacking working group leader, rule testing and supporter
Hiroki Takizawa (@hr_zwtk): Rule testing and supporter
su (@su-10): Supporter
lisbun (@lisbun): Supporter
Tsubokku (@ytsuboi0322): Supporter
Handy (@asasawqv): Supporter
Sachiel (@sachielarcangel): Supporter
Segacchi (@TakahikoSega): Supporter
tanabe (@rtanab): Supporter
```

## さいごに

Hayabusa/Elastic Stackのインストール、Hayabusaによる検知の実施、Kibanaによる可視化まで試してみました。

`hayabusa`フィールド[^2]を作ってみたくて、ECS[^3]に準拠しないまま値を格納するなど、まだまだ改善の余地がありますが、可視化することで全容把握が容易になるのでインシデントハンドリングがさらに捗る印象を受けました。

[^2]: Fortinetなどのセキュリティアプライアンスは独自に、`fortinet.firewall.alert`などの独自フィールドを作成し格納しているので、真似したくなりました。 
 https://www.elastic.co/guide/en/beats/filebeat/current/exported-fields-fortinet.html
[^3]: Elastic Common Schema: https://www.elastic.co/guide/en/ecs/current/index.html

Hayabusaの[マイルストーン](https://github.com/Yamato-Security/hayabusa/milestones)を見ると、v2.0まで計画されており活発に開発されているのがわかりました。今後が楽しみです。

## 参考情報

- [Windowsイベントログ解析ツール「Hayabusa」を使ってみる | itiblog](https://itib.hatenablog.com/entry/2021/12/31/222946)
- [HAYABUSAのなかみ(Hayabusa internals) | KazuminEngine](https://kazuminkun.hatenablog.com/entry/2021/12/27/190535)
- [Elastic Stack 8.0.0-rc1 released](https://www.elastic.co/jp/blog/elastic-stack-8-0-0-rc1-release)