Merge branch 'main' into 597-moved-update-rules-option-process

This commit is contained in:
DustInDark
2022-06-29 00:46:48 +09:00
19 changed files with 349 additions and 236 deletions
+5 -3
View File
@@ -1,6 +1,6 @@
# 変更点
## v1.4.0 [2022/XX/XX]
## v1.4.0 [2022/06/26]
**新機能:**
@@ -9,14 +9,16 @@
**改善:**
- ルール内に`details`フィールドがないときに、`rules/config/default_details.txt`に設定されたデフォルトの出力を行えるようにした。 (#359) (@hitenkoku)
- Clap Crateパッケージの更新 (#413) (@hitenkoku)
- オプションの指定がないときに、`--help`と同じ画面出力を行うように変更した。(#387) (@hitenkoku)
- ルール内に`details`フィールドがないときに、`rules/config/default_details.txt`に設定されたデフォルトの出力を行えるようにした。 (#359) (@hitenkoku)
- hayabusa.exeをカレントワーキングディレクトリ以外から動作できるようにした。 (#592) (@hitenkoku)
- `output` オプションで指定されファイルのサイズを出力するようにした。 (#595) (@hitenkoku)
**バグ修正:**
- XXX
- カラー出力で長い出力があった場合にエラーが出て終了する問題を修正した。 (#603) (@hitenkoku)
- `Excluded rules`の合計で`rules/tools/sigmac/testfiles`配下のテストルールも入っていたので、無視するようにした。 (#602) (@hitenkoku)
## v1.3.2 [2022/06/13]
+5 -4
View File
@@ -1,6 +1,6 @@
# Changes
## v1.4.0 [2022/XX/XX]
## v1.4.0 [2022/06/26]
**New Features:**
@@ -9,15 +9,16 @@
**Enhancements:**
- Added default details output based on `rules/config/default_details.txt` when no `details` field in a rule is specified. (i.e. Sigma rules) (#359) (@hitenkoku)
- Updated clap crate package to version 3. (#413) (@hitnekoku)
- Updated the default usage and help menu. (#387) (@hitenkoku)
- Added default details output based on `rules/config/default_details.txt` when no `details` field in a rule is specified. (i.e. Sigma rules) (#359) (@hitenkoku)
- Hayabusa can be run from any directory, not just from the current directory. (#592) (@hitenkoku)
- Added saved file size output when `output` is specified. (#595) (@hitenkoku)
- Ignored loading yml file in `rules/tools/sigmac/testfiles`. (#602) (@hitenkoku)
**Bug Fixes:**
- XXX
- Fixed output error and program termination when long output is displayed with color. (#603) (@hitenkoku)
- Ignore loading yml files in `rules/tools/sigmac/testfiles` to fix `Excluded rules` count. (#602) (@hitenkoku)
## v1.3.2 [2022/06/13]
Generated
+34 -34
View File
@@ -74,9 +74,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "base-x"
version = "0.2.10"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc19a4937b4fbd3fe3379793130e42060d10627a360f2127802b10b87e7baf74"
checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
[[package]]
name = "base64"
@@ -220,9 +220,9 @@ dependencies = [
[[package]]
name = "clap"
version = "3.2.5"
version = "3.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53da17d37dba964b9b3ecb5c5a1f193a2762c700e6829201e645b9381c99dc7"
checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a"
dependencies = [
"atty",
"bitflags",
@@ -237,9 +237,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "3.2.5"
version = "3.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9"
checksum = "ed6db9e867166a43a53f7199b5e4d1f522a1e5bd626654be263c999ce59df39a"
dependencies = [
"heck",
"proc-macro-error",
@@ -250,9 +250,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613"
checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4"
dependencies = [
"os_str_bytes",
]
@@ -330,9 +330,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.9"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978"
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
dependencies = [
"cfg-if",
"once_cell",
@@ -496,7 +496,7 @@ dependencies = [
[[package]]
name = "evtx"
version = "0.7.3"
source = "git+https://github.com/Yamato-Security/hayabusa-evtx.git?rev=158d496#158d496e6f40a036fa30b35e245683c3f7981df6"
source = "git+https://github.com/Yamato-Security/hayabusa-evtx.git#825f8aa7ce3477cfb405f4f8041747db75382590"
dependencies = [
"anyhow",
"bitflags",
@@ -673,12 +673,12 @@ dependencies = [
[[package]]
name = "hayabusa"
version = "1.4.0-dev"
version = "1.4.0"
dependencies = [
"base64",
"bytesize",
"chrono",
"clap 3.2.5",
"clap 3.2.6",
"crossbeam-utils",
"csv",
"downcast-rs",
@@ -819,9 +819,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.9.0"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c6392766afd7964e2531940894cffe4bd8d7d17dbc3c1c4857040fd4b33bdb3"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
@@ -877,9 +877,9 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "jemalloc-sys"
version = "0.5.0+5.3.0"
version = "0.5.1+5.3.0-patched"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f655c3ecfa6b0d03634595b4b54551d4bd5ac208b9e0124873949a7ab168f70b"
checksum = "b7c2b313609b95939cb0c5a5c6917fb9b7c9394562aa3ef44eb66ffa51736432"
dependencies = [
"cc",
"fs_extra",
@@ -914,7 +914,7 @@ dependencies = [
"anyhow",
"atty",
"chrono",
"clap 3.2.5",
"clap 3.2.6",
"file-chunker",
"indicatif",
"memmap2",
@@ -980,9 +980,9 @@ dependencies = [
[[package]]
name = "linked-hash-map"
version = "0.5.4"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "lock_api"
@@ -1044,9 +1044,9 @@ dependencies = [
[[package]]
name = "mio"
version = "0.8.3"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
dependencies = [
"libc",
"log",
@@ -1140,9 +1140,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-src"
version = "111.20.0+1.1.1o"
version = "111.21.0+1.1.1p"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92892c4f87d56e376e469ace79f1128fdaded07646ddf73aa0be4706ff712dec"
checksum = "6d0a8313729211913936f1b95ca47a5fc7f2e04cd658c115388287f8a8361008"
dependencies = [
"cc",
]
@@ -1272,9 +1272,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.39"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-ident",
]
@@ -1314,9 +1314,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.19"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f53dc8cf16a769a6f677e09e7ff2cd4be1ea0f48754aac39520536962011de0d"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
@@ -1572,9 +1572,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.8.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2"
[[package]]
name = "socket2"
@@ -1866,9 +1866,9 @@ dependencies = [
[[package]]
name = "tracing-core"
version = "0.1.27"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921"
checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
dependencies = [
"once_cell",
]
@@ -1902,9 +1902,9 @@ checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]]
name = "unicode-normalization"
version = "0.1.19"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
checksum = "81dee68f85cab8cf68dec42158baf3a79a1cdc065a8b103025965d6ccb7f6cbd"
dependencies = [
"tinyvec",
]
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "hayabusa"
version = "1.4.0-dev"
version = "1.4.0"
authors = ["Yamato Security @SecurityYamato"]
edition = "2021"
@@ -8,7 +8,7 @@ edition = "2021"
[dependencies]
clap = { version = "3.*", features = ["derive", "cargo"]}
evtx = { git = "https://github.com/Yamato-Security/hayabusa-evtx.git" , rev = "158d496" , features = ["fast-alloc"]}
evtx = { git = "https://github.com/Yamato-Security/hayabusa-evtx.git" , features = ["fast-alloc"]}
quick-xml = {version = "0.*", features = ["serialize"] }
serde = { version = "1.*", features = ["derive"] }
serde_json = { version = "1.0"}
Binary file not shown.
BIN
View File
Binary file not shown.
+67 -67
View File
@@ -104,23 +104,23 @@ Hayabusaは従来のWindowsイベントログ分析解析と比較して、分
## 起動画面
![Hayabusa 起動画面](/screenshots/Hayabusa-Startup.png)
![Hayabusa 起動画面](screenshots/Hayabusa-Startup.png)
## ターミナル出力画面
![Hayabusa ターミナル出力画面](/screenshots/Hayabusa-Results.png)
![Hayabusa ターミナル出力画面](screenshots/Hayabusa-Results.png)
## イベント頻度タイムライン出力画面 (`-V`オプション)
![Hayabusa イベント頻度タイムライン出力画面](/screenshots/HayabusaEventFrequencyTimeline.png)
![Hayabusa イベント頻度タイムライン出力画面](screenshots/HayabusaEventFrequencyTimeline.png)
## 結果サマリ画面
![Hayabusa 結果サマリ画面](/screenshots/HayabusaResultsSummary.png)
![Hayabusa 結果サマリ画面](screenshots/HayabusaResultsSummary.png)
## Excelでの解析
![Hayabusa Excelでの解析](/screenshots/ExcelScreenshot.png)
![Hayabusa Excelでの解析](screenshots/ExcelScreenshot.png)
## Timeline Explorerでの解析
@@ -182,7 +182,7 @@ git clone https://github.com/Yamato-Security/hayabusa.git --recursive
`git pull --recurse-submodules`コマンド、もしくは以下のコマンドで`rules`フォルダを同期し、Hayabusaの最新のルールを更新することができます:
```bash
hayabusa-1.3.2-win-x64.exe -u
hayabusa-1.4.0-win-x64.exe -u
```
アップデートが失敗した場合は、`rules`フォルダの名前を変更してから、もう一回アップデートしてみて下さい。
@@ -264,20 +264,20 @@ Hayabusa実行する際や、`.yml`ルールのダウンロードや実行時に
## Windows
コマンドプロンプトやWindows Terminalから32ビットもしくは64ビットのWindowsバイナリをHayabusaのルートディレクトリから実行します。
例: `hayabusa-1.3.2-windows-x64.exe`
例: `hayabusa-1.4.0-windows-x64.exe`
## Linux
まず、バイナリに実行権限を与える必要があります。
```bash
chmod +x ./hayabusa-1.3.2-linux-x64-gnu
chmod +x ./hayabusa-1.4.0-linux-x64-gnu
```
次に、Hayabusaのルートディレクトリから実行します:
```bash
./hayabusa-1.3.2-linux-x64-gnu
./hayabusa-1.4.0-linux-x64-gnu
```
## macOS
@@ -285,32 +285,32 @@ chmod +x ./hayabusa-1.3.2-linux-x64-gnu
まず、ターミナルやiTerm2からバイナリに実行権限を与える必要があります。
```bash
chmod +x ./hayabusa-1.3.2-mac-intel
chmod +x ./hayabusa-1.4.0-mac-intel
```
次に、Hayabusaのルートディレクトリから実行してみてください:
```bash
./hayabusa-1.3.2-mac-intel
./hayabusa-1.4.0-mac-intel
```
macOSの最新版では、以下のセキュリティ警告が出る可能性があります:
![Mac Error 1 JP](/screenshots/MacOS-RunError-1-JP.png)
![Mac Error 1 JP](screenshots/MacOS-RunError-1-JP.png)
macOSの環境設定から「セキュリティとプライバシー」を開き、「一般」タブから「このまま許可」ボタンをクリックしてください。
![Mac Error 2 JP](/screenshots/MacOS-RunError-2-JP.png)
![Mac Error 2 JP](screenshots/MacOS-RunError-2-JP.png)
その後、ターミナルからもう一回実行してみてください:
```bash
./hayabusa-1.3.2-mac-intel
./hayabusa-1.4.0-mac-intel
```
以下の警告が出るので、「開く」をクリックしてください。
![Mac Error 3 JP](/screenshots/MacOS-RunError-3-JP.png)
![Mac Error 3 JP](screenshots/MacOS-RunError-3-JP.png)
これで実行できるようになります。
@@ -323,42 +323,42 @@ USAGE:
hayabusa.exe -f file.evtx [OPTIONS] / hayabusa.exe -d evtx-directory [OPTIONS]
OPTIONS:
--European-time ヨーロッパ形式で日付と時刻を出力する (例: 22-02-2022 22:00:00.123 +02:00)
--RFC-2822 RFC 2822形式で日付と時刻を出力する (例: Fri, 22 Feb 2022 22:00:00 -0600)
--RFC-3339 RFC 3339形式で日付と時刻を出力する (例: 2022-02-22 22:00:00.123456-06:00)
--US-military-time 24時間制(ミリタリータイム)のアメリカ形式で日付と時刻を出力する (例: 02-22-2022 22:00:00.123 -06:00)
--US-time アメリカ形式で日付と時刻を出力する (例: 02-22-2022 10:00:00.123 PM -06:00)
--target-file-ext <EVTX_FILE_EXT>... evtx以外の拡張子を解析対象に追加する。 (例1: evtx_data 例2:evtx1 evtx2)
--all-tags 出力したCSVファイルにルール内のタグ情報を全て出力する
-c, --config <RULE_CONFIG_DIRECTORY> ルールフォルダのコンフィグディレクトリ (デフォルト: ./rules/config)
--contributors コントリビュータの一覧表示
-d, --directory <DIRECTORY> .evtxファイルを持つディレクトリのパス
-D, --enable-deprecated-rules Deprecatedルールを有効にする
--end-timeline <END_TIMELINE> 解析対象とするイベントログの終了時刻 (例: "2022-02-22 23:59:59 +09:00")
--exclude-status <EXCLUDE_STATUS>... 読み込み対象外とするルール内でのステータス (ex: experimental) (ex: stable test)
-f, --filepath <FILE_PATH> 1つの.evtxファイルに対して解析を行う
-F, --full-data 全てのフィールド情報を出力する
-h, --help ヘルプ情報を表示する
-l, --live-analysis ローカル端末のC:\Windows\System32\winevt\Logsフォルダを解析する
-L, --logon-summary 成功と失敗したログオン情報の要約を出力する
--level-tuning <LEVEL_TUNING_FILE> ルールlevelのチューニング (デフォルト: ./rules/config/level_tuning.txt)
-m, --min-level <LEVEL> 結果出力をするルールの最低レベル (デフォルト: informational)
-n, --enable-noisy-rules Noisyルールを有効にする
--no_color カラー出力を無効にする
-o, --output <CSV_TIMELINE> タイムラインをCSV形式で保存する (例: results.csv)
-p, --pivot-keywords-list ピボットキーワードの一覧作成
-q, --quiet Quietモード: 起動バナーを表示しない
-Q, --quiet-errors Quiet errorsモード: エラーログを保存しない
-r, --rules <RULE_DIRECTORY/RULE_FILE> ルールファイルまたはルールファイルを持つディレクトリ (デフォルト: ./rules)
-R, --hide-record-id イベントレコードIDを表示しない
-s, --statistics イベントIDの統計情報を表示する
--start-timeline <START_TIMELINE> 解析対象とするイベントログの開始時刻 (例: "2020-02-22 00:00:00 +09:00")
-t, --thread-number <NUMBER> スレッド数 (デフォルト: パフォーマンスに最適な数値)
-u, --update-rules rulesフォルダをhayabusa-rulesのgithubリポジトリの最新版に更新する
-U, --UTC UTC形式で日付と時刻を出力する (デフォルト: 現地時間)
-v, --verbose 詳細な情報を出力する
-V, --visualize-timeline イベント頻度タイムラインを出力する
--version バージョン情報を表示する
--European-time ヨーロッパ形式で日付と時刻を出力する (例: 22-02-2022 22:00:00.123 +02:00)
--RFC-2822 RFC 2822形式で日付と時刻を出力する (例: Fri, 22 Feb 2022 22:00:00 -0600)
--RFC-3339 RFC 3339形式で日付と時刻を出力する (例: 2022-02-22 22:00:00.123456-06:00)
--US-military-time 24時間制(ミリタリータイム)のアメリカ形式で日付と時刻を出力する (例: 02-22-2022 22:00:00.123 -06:00)
--US-time アメリカ形式で日付と時刻を出力する (例: 02-22-2022 10:00:00.123 PM -06:00)
--target-file-ext <EVTX_FILE_EXT>... evtx以外の拡張子を解析対象に追加する。 (例1: evtx_data 例2:evtx1 evtx2)
--all-tags 出力したCSVファイルにルール内のタグ情報を全て出力する
-c, --rules-config <RULE_CONFIG_DIRECTORY> ルールフォルダのコンフィグディレクトリ (デフォルト: ./rules/config)
--contributors コントリビュータの一覧表示
-d, --directory <DIRECTORY> .evtxファイルを持つディレクトリのパス
-D, --enable-deprecated-rules Deprecatedルールを有効にする
--end-timeline <END_TIMELINE> 解析対象とするイベントログの終了時刻 (例: "2022-02-22 23:59:59 +09:00")
--exclude-status <EXCLUDE_STATUS>... 読み込み対象外とするルール内でのステータス (ex: experimental) (ex: stable test)
-f, --filepath <FILE_PATH> 1つの.evtxファイルに対して解析を行う
-F, --full-data 全てのフィールド情報を出力する
-h, --help ヘルプ情報を表示する
-l, --live-analysis ローカル端末のC:\Windows\System32\winevt\Logsフォルダを解析する
-L, --logon-summary 成功と失敗したログオン情報の要約を出力する
--level-tuning [<LEVEL_TUNING_FILE>] ルールlevelのチューニング (デフォルト: ./rules/config/level_tuning.txt)
-m, --min-level <LEVEL> 結果出力をするルールの最低レベル (デフォルト: informational)
-n, --enable-noisy-rules Noisyルールを有効にする
--no_color カラー出力を無効にする
-o, --output <CSV_TIMELINE> タイムラインをCSV形式で保存する (例: results.csv)
-p, --pivot-keywords-list ピボットキーワードの一覧作成
-q, --quiet Quietモード: 起動バナーを表示しない
-Q, --quiet-errors Quiet errorsモード: エラーログを保存しない
-r, --rules <RULE_DIRECTORY/RULE_FILE> ルールファイルまたはルールファイルを持つディレクトリ (デフォルト: ./rules)
-R, --hide-record-id イベントレコードIDを表示しない
-s, --statistics イベントIDの統計情報を表示する
--start-timeline <START_TIMELINE> 解析対象とするイベントログの開始時刻 (例: "2020-02-22 00:00:00 +09:00")
-t, --thread-number <NUMBER> スレッド数 (デフォルト: パフォーマンスに最適な数値)
-u, --update-rules rulesフォルダをhayabusa-rulesのgithubリポジトリの最新版に更新する
-U, --UTC UTC形式で日付と時刻を出力する (デフォルト: 現地時間)
-v, --verbose 詳細な情報を出力する
-V, --visualize-timeline イベント頻度タイムラインを出力する
--version バージョン情報を表示する
```
## 使用例
@@ -366,79 +366,79 @@ OPTIONS:
* 1つのWindowsイベントログファイルに対してHayabusaを実行します:
```bash
hayabusa-1.3.2-win-x64.exe -f eventlog.evtx
hayabusa-1.4.0-win-x64.exe -f eventlog.evtx
```
* 複数のWindowsイベントログファイルのあるsample-evtxディレクトリに対して、Hayabusaを実行します:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx
```
* 全てのフィールド情報も含めて1つのCSVファイルにエクスポートして、Excel、Timeline Explorer、Elastic Stack等でさらに分析することができます:
* 全てのフィールド情報も含めて1つのCSVファイルにエクスポートして、Excel、Timeline Explorer、Elastic Stack等でさらに分析することができます(注意: `-F`を有効にすると、出力するファイルのサイズがとても大きくなります!):
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -o results.csv -F
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -o results.csv -F
```
* Hayabusaルールのみを実行します(デフォルトでは `-r .\rules` にあるすべてのルールが利用されます):
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa -o results.csv
```
* Windowsでデフォルトで有効になっているログに対してのみ、Hayabusaルールを実行します:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\default -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\default -o results.csv
```
* Sysmonログに対してのみHayabusaルールを実行します:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\sysmon -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\sysmon -o results.csv
```
* Sigmaルールのみを実行します:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\sigma -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\sigma -o results.csv
```
* 廃棄(deprecated)されたルール(`status``deprecated`になっているルール)とノイジールール(`.\rules\config\noisy_rules.txt`にルールIDが書かれているルール)を有効にします:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx --enable-deprecated-rules --enable-noisy-rules -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx --enable-deprecated-rules --enable-noisy-rules -o results.csv
```
* ログオン情報を分析するルールのみを実行し、UTCタイムゾーンで出力します:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\default\events\Security\Logons -U -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\default\events\Security\Logons -U -o results.csv
```
* 起動中のWindows端末上で実行し(Administrator権限が必要)、アラート(悪意のある可能性のある動作)のみを検知します:
```bash
hayabusa-1.3.2-win-x64.exe -l -m low
hayabusa-1.4.0-win-x64.exe -l -m low
```
* criticalレベルのアラートからピボットキーワードの一覧を作成します(結果は結果毎に`keywords-Ip Address.txt``keyworss-Users.txt`等に出力されます):
```bash
hayabusa-1.3.2-win-x64.exe -l -m critical -p -o keywords
hayabusa-1.4.0-win-x64.exe -l -m critical -p -o keywords
```
* イベントIDの統計情報を取得します:
```bash
hayabusa-1.3.2-win-x64.exe -f Security.evtx -s
hayabusa-1.4.0-win-x64.exe -f Security.evtx -s
```
* 詳細なメッセージを出力します(処理に時間がかかるファイル、パースエラー等を特定するのに便利):
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -v
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -v
```
* Verbose出力の例:
@@ -659,7 +659,7 @@ Hayabusaルールは、Windowsのイベントログ解析専用に設計され
## 検知レベルのlevelチューニング
Hayabusaルール、Sigmaルールはそれぞれの作者が検知した際のリスクレベルを決めています。
ユーザが独自のリスクレベルに設定するには`./rules/config/level_tuning.txt`に変換情報を書き、`hayabusa-1.3.2-win-x64.exe --level-tuning`を実行することでルールファイルが書き換えられます。
ユーザが独自のリスクレベルに設定するには`./rules/config/level_tuning.txt`に変換情報を書き、`hayabusa-1.4.0-win-x64.exe --level-tuning`を実行することでルールファイルが書き換えられます。
ルールファイルが直接書き換えられることに注意して使用してください。
`./rules/config/level_tuning.txt`の例:
@@ -685,7 +685,7 @@ id,new_level
* [APT-Hunter](https://github.com/ahmedkhlief/APT-Hunter) - Pythonで開発された攻撃検知ツール。
* [Awesome Event IDs](https://github.com/stuhli/awesome-event-ids) - フォレンジック調査とインシデント対応に役立つイベントIDのリソース。
* [Chainsaw](https://github.com/countercept/chainsaw) - Rustで開発された同様のSigmaベースの攻撃検知ツール。
* [Chainsaw](https://github.com/countercept/chainsaw) - Rustで開発されたSigmaベースの攻撃検知ツール。
* [DeepBlueCLI](https://github.com/sans-blue-team/DeepBlueCLI) - [Eric Conrad](https://twitter.com/eric_conrad) によってPowershellで開発された攻撃検知ツール。
* [Epagneul](https://github.com/jurelou/epagneul) - Windowsイベントログの可視化ツール。
* [EventList](https://github.com/miriamxyra/EventList/) - [Miriam Wiesner](https://github.com/miriamxyra)によるセキュリティベースラインの有効なイベントIDをMITRE ATT&CKにマッピングするPowerShellツール。
+67 -67
View File
@@ -98,23 +98,23 @@ Hayabusa hopes to let analysts get 80% of their work done in 20% of the time whe
## Startup
![Hayabusa Startup](/screenshots/Hayabusa-Startup.png)
![Hayabusa Startup](screenshots/Hayabusa-Startup.png)
## Terminal Output
![Hayabusa terminal output](/screenshots/Hayabusa-Results.png)
![Hayabusa terminal output](screenshots/Hayabusa-Results.png)
## Event Fequency Timeline (`-V` option)
![Hayabusa Event Frequency Timeline](/screenshots/HayabusaEventFrequencyTimeline.png)
![Hayabusa Event Frequency Timeline](screenshots/HayabusaEventFrequencyTimeline.png)
## Results Summary
![Hayabusa results summary](/screenshots/HayabusaResultsSummary.png)
![Hayabusa results summary](screenshots/HayabusaResultsSummary.png)
## Analysis in Excel
![Hayabusa analysis in Excel](/screenshots/ExcelScreenshot.png)
![Hayabusa analysis in Excel](screenshots/ExcelScreenshot.png)
## Analysis in Timeline Explorer
@@ -175,7 +175,7 @@ Note: If you forget to use --recursive option, the `rules` folder, which is mana
You can sync the `rules` folder and get latest Hayabusa rules with `git pull --recurse-submodules` or use the following command:
```bash
hayabusa-1.3.2-win-x64.exe -u
hayabusa-1.4.0-win-x64.exe -u
```
If the update fails, you may need to rename the `rules` folder and try again.
@@ -260,20 +260,20 @@ If you are worried about malware or supply chain attacks, please check the hayab
## Windows
In Command Prompt or Windows Terminal, just run the 32-bit or 64-bit Windows binary from the hayabusa root directory.
Example: `hayabusa-1.3.2-windows-x64.exe`
Example: `hayabusa-1.4.0-windows-x64.exe`
## Linux
You first need to make the binary executable.
```bash
chmod +x ./hayabusa-1.3.2-linux-x64-gnu
chmod +x ./hayabusa-1.4.0-linux-x64-gnu
```
Then run it from the Hayabusa root directory:
```bash
./hayabusa-1.3.2-linux-x64-gnu
./hayabusa-1.4.0-linux-x64-gnu
```
## macOS
@@ -281,32 +281,32 @@ Then run it from the Hayabusa root directory:
From Terminal or iTerm2, you first need to make the binary executable.
```bash
chmod +x ./hayabusa-1.3.2-mac-intel
chmod +x ./hayabusa-1.4.0-mac-intel
```
Then, try to run it from the Hayabusa root directory:
```bash
./hayabusa-1.3.2-mac-intel
./hayabusa-1.4.0-mac-intel
```
On the latest version of macOS, you may receive the following security error when you try to run it:
![Mac Error 1 EN](/screenshots/MacOS-RunError-1-EN.png)
![Mac Error 1 EN](screenshots/MacOS-RunError-1-EN.png)
Click "Cancel" and then from System Preferences, open "Security & Privacy" and from the General tab, click "Allow Anyway".
![Mac Error 2 EN](/screenshots/MacOS-RunError-2-EN.png)
![Mac Error 2 EN](screenshots/MacOS-RunError-2-EN.png)
After that, try to run it again.
```bash
./hayabusa-1.3.2-mac-intel
./hayabusa-1.4.0-mac-intel
```
The following warning will pop up, so please click "Open".
![Mac Error 3 EN](/screenshots/MacOS-RunError-3-EN.png)
![Mac Error 3 EN](screenshots/MacOS-RunError-3-EN.png)
You should now be able to run hayabusa.
@@ -319,42 +319,42 @@ USAGE:
hayabusa.exe -f file.evtx [OPTIONS] / hayabusa.exe -d evtx-directory [OPTIONS]
OPTIONS:
--European-time Output timestamp in European time format (ex: 22-02-2022 22:00:00.123 +02:00)
--RFC-2822 Output timestamp in RFC 2822 format (ex: Fri, 22 Feb 2022 22:00:00 -0600)
--RFC-3339 Output timestamp in RFC 3339 format (ex: 2022-02-22 22:00:00.123456-06:00)
--US-military-time Output timestamp in US military time format (ex: 02-22-2022 22:00:00.123 -06:00)
--US-time Output timestamp in US time format (ex: 02-22-2022 10:00:00.123 PM -06:00)
--target-file-ext <EVTX_FILE_EXT>... Specify additional target file extensions (ex: evtx_data) (ex: evtx1 evtx2)
--all-tags Output all tags when saving to a CSV file
-c, --config <RULE_CONFIG_DIRECTORY> Specify custom rule config folder (default: ./rules/config)
--contributors Print the list of contributors
-d, --directory <DIRECTORY> Directory of multiple .evtx files
-D, --enable-deprecated-rules Enable rules marked as deprecated
--end-timeline <END_TIMELINE> End time of the event logs to load (ex: "2022-02-22 23:59:59 +09:00")
--exclude-status <EXCLUDE_STATUS>... Ignore rules according to status (ex: experimental) (ex: stable test)
-f, --filepath <FILE_PATH> File path to one .evtx file
-F, --full-data Print all field information
-h, --help Print help information
-l, --live-analysis Analyze the local C:\Windows\System32\winevt\Logs folder
-L, --logon-summary Print a summary of successful and failed logons
--level-tuning <LEVEL_TUNING_FILE> Tune alert levels (default: ./rules/config/level_tuning.txt)
-m, --min-level <LEVEL> Minimum level for rules (default: informational)
-n, --enable-noisy-rules Enable rules marked as noisy
--no-color Disable color output
-o, --output <CSV_TIMELINE> Save the timeline in CSV format (ex: results.csv)
-p, --pivot-keywords-list Create a list of pivot keywords
-q, --quiet Quiet mode: do not display the launch banner
-Q, --quiet-errors Quiet errors mode: do not save error logs
-r, --rules <RULE_DIRECTORY/RULE_FILE> Specify a rule directory or file (default: ./rules)
-R, --hide-record-ID Do not display EventRecordID numbers
-s, --statistics Print statistics of event IDs
--start-timeline <START_TIMELINE> Start time of the event logs to load (ex: "2020-02-22 00:00:00 +09:00")
-t, --thread-number <NUMBER> Thread number (default: optimal number for performance)
-u, --update-rules Update to the latest rules in the hayabusa-rules github repository
-U, --UTC Output time in UTC format (default: local time)
-v, --verbose Output verbose information
-V, --visualize-timeline Output event frequency timeline
--version Print version information
--European-time Output timestamp in European time format (ex: 22-02-2022 22:00:00.123 +02:00)
--RFC-2822 Output timestamp in RFC 2822 format (ex: Fri, 22 Feb 2022 22:00:00 -0600)
--RFC-3339 Output timestamp in RFC 3339 format (ex: 2022-02-22 22:00:00.123456-06:00)
--US-military-time Output timestamp in US military time format (ex: 02-22-2022 22:00:00.123 -06:00)
--US-time Output timestamp in US time format (ex: 02-22-2022 10:00:00.123 PM -06:00)
--target-file-ext <EVTX_FILE_EXT>... Specify additional target file extensions (ex: evtx_data) (ex: evtx1 evtx2)
--all-tags Output all tags when saving to a CSV file
-c, --rules-config <RULE_CONFIG_DIRECTORY> Specify custom rule config folder (default: ./rules/config)
--contributors Print the list of contributors
-d, --directory <DIRECTORY> Directory of multiple .evtx files
-D, --enable-deprecated-rules Enable rules marked as deprecated
--end-timeline <END_TIMELINE> End time of the event logs to load (ex: "2022-02-22 23:59:59 +09:00")
--exclude-status <EXCLUDE_STATUS>... Ignore rules according to status (ex: experimental) (ex: stable test)
-f, --filepath <FILE_PATH> File path to one .evtx file
-F, --full-data Print all field information
-h, --help Print help information
-l, --live-analysis Analyze the local C:\Windows\System32\winevt\Logs folder
-L, --logon-summary Print a summary of successful and failed logons
--level-tuning [<LEVEL_TUNING_FILE>] Tune alert levels (default: ./rules/config/level_tuning.txt)
-m, --min-level <LEVEL> Minimum level for rules (default: informational)
-n, --enable-noisy-rules Enable rules marked as noisy
--no-color Disable color output
-o, --output <CSV_TIMELINE> Save the timeline in CSV format (ex: results.csv)
-p, --pivot-keywords-list Create a list of pivot keywords
-q, --quiet Quiet mode: do not display the launch banner
-Q, --quiet-errors Quiet errors mode: do not save error logs
-r, --rules <RULE_DIRECTORY/RULE_FILE> Specify a rule directory or file (default: ./rules)
-R, --hide-record-ID Do not display EventRecordID numbers
-s, --statistics Print statistics of event IDs
--start-timeline <START_TIMELINE> Start time of the event logs to load (ex: "2020-02-22 00:00:00 +09:00")
-t, --thread-number <NUMBER> Thread number (default: optimal number for performance)
-u, --update-rules Update to the latest rules in the hayabusa-rules github repository
-U, --UTC Output time in UTC format (default: local time)
-v, --verbose Output verbose information
-V, --visualize-timeline Output event frequency timeline
--version Print version information
```
## Usage Examples
@@ -362,79 +362,79 @@ OPTIONS:
* Run hayabusa against one Windows event log file:
```bash
hayabusa-1.3.2-win-x64.exe -f eventlog.evtx
hayabusa-1.4.0-win-x64.exe -f eventlog.evtx
```
* Run hayabusa against the sample-evtx directory with multiple Windows event log files:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx
```
* Export to a single CSV file for further analysis with excel, timeline explorer, elastic stack, etc... and include all field information:
* Export to a single CSV file for further analysis with excel, timeline explorer, elastic stack, etc... and include all field information (Warning: your file output size will become much larger with `-F` enabled!):
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -o results.csv -F
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -o results.csv -F
```
* Only run hayabusa rules (the default is to run all the rules in `-r .\rules`):
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa -o results.csv
```
* Only run hayabusa rules for logs that are enabled by default on Windows:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\default -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\default -o results.csv
```
* Only run hayabusa rules for sysmon logs:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\sysmon -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\sysmon -o results.csv
```
* Only run sigma rules:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\sigma -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\sigma -o results.csv
```
* Enable deprecated rules (those with `status` marked as `deprecated`) and noisy rules (those whose rule ID is listed in `.\rules\config\noisy_rules.txt`):
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx --enable-noisy-rules --enable-deprecated-rules -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx --enable-noisy-rules --enable-deprecated-rules -o results.csv
```
* Only run rules to analyze logons and output in the UTC timezone:
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\default\events\Security\Logons -U -o results.csv
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -r .\rules\hayabusa\default\events\Security\Logons -U -o results.csv
```
* Run on a live Windows machine (requires Administrator privileges) and only detect alerts (potentially malicious behavior):
```bash
hayabusa-1.3.2-win-x64.exe -l -m low
hayabusa-1.4.0-win-x64.exe -l -m low
```
* Create a list of pivot keywords from critical alerts and save the results. (Results will be saved to `keywords-Ip Addresses.txt`, `keywords-Users.txt`, etc...):
```bash
hayabusa-1.3.2-win-x64.exe -l -m critical -p -o keywords
hayabusa-1.4.0-win-x64.exe -l -m critical -p -o keywords
```
* Print Event ID statistics:
```bash
hayabusa-1.3.2-win-x64.exe -f Security.evtx -s
hayabusa-1.4.0-win-x64.exe -f Security.evtx -s
```
* Print verbose information (useful for determining which files take long to process, parsing errors, etc...):
```bash
hayabusa-1.3.2-win-x64.exe -d .\hayabusa-sample-evtx -v
hayabusa-1.4.0-win-x64.exe -d .\hayabusa-sample-evtx -v
```
* Verbose output example:
@@ -655,7 +655,7 @@ You can also add a rule ID to `rules/config/noisy_rules.txt` in order to ignore
Hayabusa and Sigma rule authors will determine the risk level of the alert when writing their rules.
However, the actual risk level will differ between environments.
You can tune the risk level of the rules by adding them to `./rules/config/level_tuning.txt` and executing `hayabusa-1.3.2-win-x64.exe --level-tuning` which will update the `level` line in the rule file.
You can tune the risk level of the rules by adding them to `./rules/config/level_tuning.txt` and executing `hayabusa-1.4.0-win-x64.exe --level-tuning` which will update the `level` line in the rule file.
Please note that the rule file will be updated directly.
`./rules/config/level_tuning.txt` sample line:
@@ -682,7 +682,7 @@ There is no "one tool to rule them all" and we have found that each has its own
* [APT-Hunter](https://github.com/ahmedkhlief/APT-Hunter) - Attack detection tool written in Python.
* [Awesome Event IDs](https://github.com/stuhli/awesome-event-ids) - Collection of Event ID resources useful for Digital Forensics and Incident Response
* [Chainsaw](https://github.com/countercept/chainsaw) - A similar sigma-based attack detection tool written in Rust.
* [Chainsaw](https://github.com/countercept/chainsaw) - Another sigma-based attack detection tool written in Rust.
* [DeepBlueCLI](https://github.com/sans-blue-team/DeepBlueCLI) - Attack detection tool written in Powershell by [Eric Conrad](https://twitter.com/eric_conrad).
* [Epagneul](https://github.com/jurelou/epagneul) - Graph visualization for Windows event logs.
* [EventList](https://github.com/miriamxyra/EventList/) - Map security baseline event IDs to MITRE ATT&CK by [Miriam Wiesner](https://github.com/miriamxyra).
+1 -1
Submodule rules updated: 8c14d12be3...e8e20ee427
Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 KiB

After

Width:  |  Height:  |  Size: 899 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 KiB

After

Width:  |  Height:  |  Size: 120 KiB

+33 -22
View File
@@ -1,5 +1,5 @@
use crate::detections::configs;
use crate::detections::configs::TERM_SIZE;
use crate::detections::configs::{CURRENT_EXE_PATH, TERM_SIZE};
use crate::detections::print;
use crate::detections::print::{AlertMessage, IS_HIDE_RECORD_ID};
use crate::detections::utils;
@@ -64,7 +64,12 @@ lazy_static! {
/// level_color.txtファイルを読み込み対応する文字色のマッピングを返却する関数
pub fn set_output_color() -> HashMap<String, Color> {
let read_result = utils::read_csv("config/level_color.txt");
let read_result = utils::read_csv(
CURRENT_EXE_PATH
.join("config/level_color.txt")
.to_str()
.unwrap(),
);
let mut color_map: HashMap<String, Color> = HashMap::new();
if configs::CONFIG.read().unwrap().args.no_color {
return color_map;
@@ -283,18 +288,20 @@ fn emit_csv<W: std::io::Write>(
//ヘッダーのみを出力
if plus_header {
write!(disp_wtr_buf, "{}", _get_serialized_disp_output(None)).ok();
plus_header = false;
}
disp_wtr_buf
.set_color(
ColorSpec::new().set_fg(_get_output_color(&color_map, &detect_info.level)),
write_color_buffer(
&disp_wtr,
get_writable_color(None),
&_get_serialized_disp_output(None),
true,
)
.ok();
write!(
disp_wtr_buf,
"{}",
_get_serialized_disp_output(Some(dispformat))
plus_header = false;
}
write_color_buffer(
&disp_wtr,
get_writable_color(_get_output_color(&color_map, &detect_info.level)),
&_get_serialized_disp_output(Some(dispformat)),
false,
)
.ok();
} else {
@@ -354,7 +361,6 @@ fn emit_csv<W: std::io::Write>(
}
}
if displayflag {
disp_wtr.print(&disp_wtr_buf)?;
println!();
} else {
wtr.flush()?;
@@ -382,8 +388,9 @@ fn emit_csv<W: std::io::Write>(
disp_wtr_buf.clear();
write_color_buffer(
&disp_wtr,
get_writable_color(Some(Color::Green)),
get_writable_color(Some(Color::Rgb(0, 255, 0))),
"Results Summary:",
true,
)
.ok();
@@ -407,6 +414,7 @@ fn emit_csv<W: std::io::Write>(
&disp_wtr,
get_writable_color(None),
&format!("Total events: {}", all_record_cnt),
true,
)
.ok();
write_color_buffer(
@@ -416,10 +424,10 @@ fn emit_csv<W: std::io::Write>(
"Data reduction: {} events ({:.2}%)",
reducted_record_cnt, reducted_percent
),
true,
)
.ok();
println!();
println!();
_print_unique_results(
total_detect_counts_by_level,
@@ -472,7 +480,7 @@ fn _get_serialized_disp_output(dispformat: Option<DisplayFormat>) -> String {
if configs::CONFIG.read().unwrap().args.full_data {
titles.push("RecordInformation");
}
return format!("{}\n", titles.join("|"));
return titles.join("|");
}
let mut disp_serializer = csv::WriterBuilder::new()
.double_quote(false)
@@ -522,8 +530,9 @@ fn _print_unique_results(
"{} {}: {}",
head_word,
tail_word,
counts_by_level.iter().sum::<u128>()
counts_by_level.iter().sum::<u128>(),
),
true,
)
.ok();
@@ -539,6 +548,7 @@ fn _print_unique_results(
&BufferWriter::stdout(ColorChoice::Always),
_get_output_color(color_map, level_name),
&output_raw_str,
true,
)
.ok();
}
@@ -695,8 +705,7 @@ mod tests {
use crate::afterfact::emit_csv;
use crate::afterfact::format_time;
use crate::detections::print;
use crate::detections::print::DetectInfo;
use crate::detections::print::CH_CONFIG;
use crate::detections::print::{DetectInfo, Message};
use chrono::{Local, TimeZone, Utc};
use hashbrown::HashMap;
use serde_json::Value;
@@ -712,6 +721,8 @@ mod tests {
}
fn test_emit_csv_output() {
let mock_ch_filter =
Message::create_output_filter_config("config/channel_abbreviations.txt", true, false);
let test_filepath: &str = "test.evtx";
let test_rulepath: &str = "test-rule.yml";
let test_title = "test_title";
@@ -750,7 +761,7 @@ mod tests {
level: test_level.to_string(),
computername: test_computername.to_string(),
eventid: test_eventid.to_string(),
channel: CH_CONFIG
channel: mock_ch_filter
.get("Security")
.unwrap_or(&String::default())
.to_string(),
@@ -821,7 +832,7 @@ mod tests {
let test_timestamp = Utc
.datetime_from_str("1996-02-27T01:05:01Z", "%Y-%m-%dT%H:%M:%SZ")
.unwrap();
let expect_header = "Timestamp|Computer|Channel|EventID|Level|RecordID|RuleTitle|Details\n";
let expect_header = "Timestamp|Computer|Channel|EventID|Level|RecordID|RuleTitle|Details";
let expect_tz = test_timestamp.with_timezone(&Local);
let expect_no_header = expect_tz
@@ -845,7 +856,7 @@ mod tests {
+ "|"
+ test_recinfo
+ "\n";
assert_eq!(_get_serialized_disp_output(None,), expect_header);
assert_eq!(_get_serialized_disp_output(None), expect_header);
assert_eq!(
_get_serialized_disp_output(Some(DisplayFormat {
timestamp: &format_time(&test_timestamp, false),
+17 -5
View File
@@ -8,6 +8,7 @@ use hashbrown::HashMap;
use hashbrown::HashSet;
use lazy_static::lazy_static;
use regex::Regex;
use std::env::current_exe;
use std::path::PathBuf;
use std::sync::RwLock;
use terminal_size::{terminal_size, Height, Width};
@@ -32,6 +33,8 @@ lazy_static! {
pub static ref TERM_SIZE: Option<(Width, Height)> = terminal_size();
pub static ref TARGET_EXTENSIONS: HashSet<String> =
get_target_extensions(CONFIG.read().unwrap().args.evtx_file_ext.as_ref());
pub static ref CURRENT_EXE_PATH: PathBuf =
current_exe().unwrap().parent().unwrap().to_path_buf();
pub static ref EXCLUDE_STATUS: HashSet<String> =
convert_option_vecs_to_hs(CONFIG.read().unwrap().args.exclude_status.as_ref());
}
@@ -84,7 +87,7 @@ pub struct Config {
/// Specify custom rule config folder (default: ./rules/config)
#[clap(
short = 'c',
long,
long = "rules-config",
default_value = "./rules/config",
hide_default_value = true,
value_name = "RULE_CONFIG_DIRECTORY"
@@ -188,11 +191,10 @@ pub struct Config {
/// Tune alert levels (default: ./rules/config/level_tuning.txt)
#[clap(
long = "level-tuning",
default_value = "./rules/config/level_tuning.txt",
hide_default_value = true,
value_name = "LEVEL_TUNING_FILE"
)]
pub level_tuning: PathBuf,
pub level_tuning: Option<Option<String>>,
/// Quiet mode: do not display the launch banner
#[clap(short, long)]
@@ -234,8 +236,18 @@ impl ConfigReader<'_> {
app: build_cmd,
args: parse,
headless_help: String::default(),
event_timeline_config: load_eventcode_info("config/statistics_event_info.txt"),
target_eventids: load_target_ids("config/target_eventids.txt"),
event_timeline_config: load_eventcode_info(
CURRENT_EXE_PATH
.join("config/statistics_event_info.txt")
.to_str()
.unwrap(),
),
target_eventids: load_target_ids(
CURRENT_EXE_PATH
.join("config/target_eventids.txt")
.to_str()
.unwrap(),
),
}
}
}
+3
View File
@@ -394,6 +394,7 @@ impl Detection {
&BufferWriter::stdout(ColorChoice::Always),
Some(Color::Red),
&format!("Rule parsing errors: {}", err_rc),
true,
)
.ok();
}
@@ -421,6 +422,7 @@ impl Detection {
rate,
deprecated_flag
),
true,
)
.ok();
}
@@ -434,6 +436,7 @@ impl Detection {
&BufferWriter::stdout(ColorChoice::Always),
None,
&format!("{} rules: {}", key, value),
true,
)
.ok();
});
+11 -2
View File
@@ -1,5 +1,6 @@
extern crate lazy_static;
use crate::detections::configs;
use crate::detections::configs::CURRENT_EXE_PATH;
use crate::detections::utils;
use crate::detections::utils::get_serde_number_to_string;
use crate::detections::utils::write_color_buffer;
@@ -53,12 +54,18 @@ lazy_static! {
pub static ref STATISTICS_FLAG: bool = configs::CONFIG.read().unwrap().args.statistics;
pub static ref LOGONSUMMARY_FLAG: bool = configs::CONFIG.read().unwrap().args.logon_summary;
pub static ref TAGS_CONFIG: HashMap<String, String> = Message::create_output_filter_config(
"config/output_tag.txt",
CURRENT_EXE_PATH
.join("config/output_tag.txt")
.to_str()
.unwrap(),
true,
configs::CONFIG.read().unwrap().args.all_tags
);
pub static ref CH_CONFIG: HashMap<String, String> = Message::create_output_filter_config(
"config/channel_abbreviations.txt",
CURRENT_EXE_PATH
.join("config/channel_abbreviations.txt")
.to_str()
.unwrap(),
false,
configs::CONFIG.read().unwrap().args.all_tags
);
@@ -327,6 +334,7 @@ impl AlertMessage {
&BufferWriter::stderr(ColorChoice::Always),
None,
&format!("[ERROR] {}", contents),
true,
)
}
@@ -336,6 +344,7 @@ impl AlertMessage {
&BufferWriter::stderr(ColorChoice::Always),
None,
&format!("[WARN] {}", contents),
true,
)
}
}
+5 -5
View File
@@ -523,8 +523,8 @@ mod tests {
- ホスト アプリケーション
ImagePath:
min_length: 1234321
regexes: ./rules/config/regex/detectlist_suspicous_services.txt
allowlist: ./rules/config/regex/allowlist_legitimate_services.txt
regexes: ./../../../rules/config/regex/detectlist_suspicous_services.txt
allowlist: ./../../../rules/config/regex/allowlist_legitimate_services.txt
falsepositives:
- unknown
level: medium
@@ -1111,7 +1111,7 @@ mod tests {
selection:
EventID: 4103
Channel:
- allowlist: ./rules/config/regex/allowlist_legitimate_services.txt
- allowlist: ./../../../rules/config/regex/allowlist_legitimate_services.txt
details: 'command=%CommandLine%'
"#;
@@ -1145,7 +1145,7 @@ mod tests {
selection:
EventID: 4103
Channel:
- allowlist: ./rules/config/regex/allowlist_legitimate_services.txt
- allowlist: ./../../../rules/config/regex/allowlist_legitimate_services.txt
details: 'command=%CommandLine%'
"#;
@@ -1179,7 +1179,7 @@ mod tests {
selection:
EventID: 4103
Channel:
- allowlist: ./rules/config/regex/allowlist_legitimate_services.txt
- allowlist: ./../../../rules/config/regex/allowlist_legitimate_services.txt
details: 'command=%CommandLine%'
"#;
+20 -4
View File
@@ -3,6 +3,8 @@ extern crate csv;
extern crate regex;
use crate::detections::configs;
use crate::detections::configs::CURRENT_EXE_PATH;
use termcolor::Color;
use tokio::runtime::Builder;
@@ -66,7 +68,16 @@ pub fn value_to_string(value: &Value) -> Option<String> {
}
pub fn read_txt(filename: &str) -> Result<Vec<String>, String> {
let f = File::open(filename);
let filepath = if filename.starts_with("./") {
CURRENT_EXE_PATH
.join(filename)
.to_str()
.unwrap()
.to_string()
} else {
filename.to_string()
};
let f = File::open(filepath);
if f.is_err() {
let errmsg = format!("Cannot open file. [file:{}]", filename);
return Result::Err(errmsg);
@@ -245,10 +256,15 @@ pub fn write_color_buffer(
wtr: &BufferWriter,
color: Option<Color>,
output_str: &str,
newline_flag: bool,
) -> io::Result<()> {
let mut buf = wtr.buffer();
buf.set_color(ColorSpec::new().set_fg(color)).ok();
writeln!(buf, "{}", output_str).ok();
if newline_flag {
writeln!(buf, "{}", output_str).ok();
} else {
write!(buf, "{}", output_str).ok();
}
wtr.print(&buf)
}
@@ -432,7 +448,7 @@ mod tests {
#[test]
fn test_check_regex() {
let regexes: Vec<Regex> =
utils::read_txt("./rules/config/regex/detectlist_suspicous_services.txt")
utils::read_txt("./../../../rules/config/regex/detectlist_suspicous_services.txt")
.unwrap()
.into_iter()
.map(|regex_str| Regex::new(&regex_str).unwrap())
@@ -448,7 +464,7 @@ mod tests {
fn test_check_allowlist() {
let commandline = "\"C:\\Program Files\\Google\\Update\\GoogleUpdate.exe\"";
let allowlist: Vec<Regex> =
utils::read_txt("./rules/config/regex/allowlist_legitimate_services.txt")
utils::read_txt("./../../../rules/config/regex/allowlist_legitimate_services.txt")
.unwrap()
.into_iter()
.map(|allow_str| Regex::new(&allow_str).unwrap())
+77 -20
View File
@@ -10,6 +10,7 @@ use bytesize::ByteSize;
use chrono::{DateTime, Datelike, Local};
use evtx::{EvtxParser, ParserSettings};
use hashbrown::{HashMap, HashSet};
use hayabusa::detections::configs::CURRENT_EXE_PATH;
use hayabusa::detections::configs::{load_pivot_keywords, TargetEventTime, TARGET_EXTENSIONS};
use hayabusa::detections::detection::{self, EvtxRecordInfo};
use hayabusa::detections::pivot::PivotKeyword;
@@ -77,7 +78,12 @@ impl App {
fn exec(&mut self) {
if *PIVOT_KEYWORD_LIST_FLAG {
load_pivot_keywords("config/pivot_keywords.txt");
load_pivot_keywords(
CURRENT_EXE_PATH
.join("config/pivot_keywords.txt")
.to_str()
.unwrap(),
);
}
let analysis_start_time: DateTime<Local> = Local::now();
@@ -115,6 +121,7 @@ impl App {
&BufferWriter::stdout(ColorChoice::Always),
None,
"Rules updated successfully.",
true,
)
.ok();
}
@@ -126,14 +133,30 @@ impl App {
println!();
return;
}
if !Path::new("./config").exists() {
// 実行時のexeファイルのパスをベースに変更する必要があるためデフォルトの値であった場合はそのexeファイルと同一階層を探すようにする
if !CURRENT_EXE_PATH.join("config").exists() {
AlertMessage::alert(
"Hayabusa could not find the config directory.\nPlease run it from the Hayabusa root directory.\nExample: ./hayabusa-1.0.0-windows-x64.exe"
"Hayabusa could not find the config directory.\nPlease make sure that it is in the same directory as the hayabusa executable."
)
.ok();
return;
}
// ワーキングディレクトリ以外からの実行の際にrules-configオプションの指定がないとエラーが発生することを防ぐための処理
if configs::CONFIG
.read()
.unwrap()
.args
.config
.to_str()
.unwrap()
== "./rules/config"
{
configs::CONFIG.write().unwrap().args.config = CURRENT_EXE_PATH.join("rules/config");
}
// ワーキングディレクトリ以外からの実行の際にrules-configオプションの指定がないとエラーが発生することを防ぐための処理
if configs::CONFIG.read().unwrap().args.rules.to_str().unwrap() == "./rules" {
configs::CONFIG.write().unwrap().args.rules = CURRENT_EXE_PATH.join("rules");
}
if let Some(csv_path) = &configs::CONFIG.read().unwrap().args.output {
let pivot_key_unions = PIVOT_KEYWORD.read().unwrap();
@@ -168,6 +191,7 @@ impl App {
&BufferWriter::stdout(ColorChoice::Always),
None,
"Generating Event ID Statistics",
true,
)
.ok();
println!();
@@ -177,6 +201,7 @@ impl App {
&BufferWriter::stdout(ColorChoice::Always),
None,
"Generating Logons Summary",
true,
)
.ok();
println!();
@@ -221,18 +246,21 @@ impl App {
} else if configs::CONFIG.read().unwrap().args.contributors {
self.print_contributors();
return;
} else if std::env::args()
.into_iter()
.any(|arg| arg.contains("level-tuning"))
{
let level_tuning_config_path = configs::CONFIG
} else if configs::CONFIG.read().unwrap().args.level_tuning.is_some() {
let level_tuning_val = &configs::CONFIG
.read()
.unwrap()
.args
.level_tuning
.as_path()
.display()
.to_string();
.clone()
.unwrap();
let level_tuning_config_path = match level_tuning_val {
Some(path) => path.to_owned(),
_ => CURRENT_EXE_PATH
.join("./rules/config/level_tuning.txt")
.display()
.to_string(),
};
if Path::new(&level_tuning_config_path).exists() {
if let Err(err) = LevelTuning::run(
@@ -260,6 +288,7 @@ impl App {
&BufferWriter::stdout(ColorChoice::Always),
None,
&configs::CONFIG.read().unwrap().headless_help,
true,
)
.ok();
return;
@@ -272,6 +301,7 @@ impl App {
&BufferWriter::stdout(ColorChoice::Always),
None,
&format!("Elapsed Time: {}", &analysis_duration.hhmmssxxx()),
true,
)
.ok();
println!();
@@ -324,17 +354,30 @@ impl App {
)
.ok();
});
write_color_buffer(&BufferWriter::stdout(ColorChoice::Always), None, &output).ok();
write_color_buffer(
&BufferWriter::stdout(ColorChoice::Always),
None,
&output,
true,
)
.ok();
} else {
//標準出力の場合
let output = "The following pivot keywords were found:".to_string();
write_color_buffer(&BufferWriter::stdout(ColorChoice::Always), None, &output).ok();
write_color_buffer(
&BufferWriter::stdout(ColorChoice::Always),
None,
&output,
true,
)
.ok();
pivot_key_unions.iter().for_each(|(key, pivot_keyword)| {
write_color_buffer(
&BufferWriter::stdout(ColorChoice::Always),
None,
&create_output(String::default(), key, pivot_keyword),
true,
)
.ok();
});
@@ -418,10 +461,15 @@ impl App {
}
fn print_contributors(&self) {
match fs::read_to_string("./contributors.txt") {
match fs::read_to_string(CURRENT_EXE_PATH.join("contributors.txt")) {
Ok(contents) => {
write_color_buffer(&BufferWriter::stdout(ColorChoice::Always), None, &contents)
.ok();
write_color_buffer(
&BufferWriter::stdout(ColorChoice::Always),
None,
&contents,
true,
)
.ok();
}
Err(err) => {
AlertMessage::alert(&format!("{}", err)).ok();
@@ -440,6 +488,7 @@ impl App {
&BufferWriter::stdout(ColorChoice::Always),
None,
&format!("Analyzing event files: {:?}", evtx_files.len()),
true,
)
.ok();
@@ -655,7 +704,7 @@ impl App {
/// output logo
fn output_logo(&self) {
let fp = &"art/logo.txt".to_string();
let fp = CURRENT_EXE_PATH.join("art/logo.txt");
let content = fs::read_to_string(fp).unwrap_or_default();
let output_color = if configs::CONFIG.read().unwrap().args.no_color {
None
@@ -666,6 +715,7 @@ impl App {
&BufferWriter::stdout(ColorChoice::Always),
output_color,
&content,
true,
)
.ok();
}
@@ -681,8 +731,15 @@ impl App {
match eggs.get(exec_datestr) {
None => {}
Some(path) => {
let content = fs::read_to_string(path).unwrap_or_default();
write_color_buffer(&BufferWriter::stdout(ColorChoice::Always), None, &content).ok();
let egg_path = CURRENT_EXE_PATH.join(path);
let content = fs::read_to_string(egg_path).unwrap_or_default();
write_color_buffer(
&BufferWriter::stdout(ColorChoice::Always),
None,
&content,
true,
)
.ok();
}
}
}
+2
View File
@@ -62,6 +62,7 @@ impl LevelTuning {
&BufferWriter::stdout(ColorChoice::Always),
None,
&format!("path: {}", path),
true,
)
.ok();
let mut content = match fs::read_to_string(&path) {
@@ -101,6 +102,7 @@ impl LevelTuning {
rule["level"].as_str().unwrap(),
new_level
),
true,
)
.ok();
}