From dbf3c55bc46b5700270a944258749afaf92cb621 Mon Sep 17 00:00:00 2001 From: Yamato Security <71482215+YamatoSecurity@users.noreply.github.com> Date: Wed, 20 Apr 2022 09:29:25 +0900 Subject: [PATCH 1/6] level tuning (#510) >Co-authored-by: DustInDark Date: Wed, 20 Apr 2022 10:16:25 +0900 Subject: [PATCH 2/6] change path --- README-Japanese.md | 6 +++--- README.md | 6 +++--- config/level_tuning.txt | 7 ------- src/detections/configs.rs | 2 +- src/main.rs | 4 ++-- 5 files changed, 9 insertions(+), 16 deletions(-) delete mode 100644 config/level_tuning.txt diff --git a/README-Japanese.md b/README-Japanese.md index be8d893b..c0816daa 100644 --- a/README-Japanese.md +++ b/README-Japanese.md @@ -320,7 +320,7 @@ USAGE: -s --statistics 'イベント ID の統計情報を表示する。' -q --quiet 'Quietモード。起動バナーを表示しない。' -Q --quiet-errors 'Quiet errorsモード。エラーログを保存しない。' - --level-tuning 'ルールlevelのチューニング [default: ./config/level_tuning.txt]' + --level-tuning 'ルールlevelのチューニング [default: ./rules/config/level_tuning.txt]' -p --pivot-keywords-list 'ピボットキーワードの一覧作成。' --contributors 'コントリビュータの一覧表示。' ``` @@ -560,10 +560,10 @@ Hayabusaルールは、Windowsのイベントログ解析専用に設計され ## 検知レベルのlevelチューニング Hayabusaルール、Sigmaルールはそれぞれの作者が検知した際のリスクレベルを決めています。 -ユーザが独自のリスクレベルに設定するには`./config/level_tuning.txt`に変換情報を書き、`hayabusa.exe --level-tuning`を実行することでルールファイルが書き換えられます。 +ユーザが独自のリスクレベルに設定するには`./rules/config/level_tuning.txt`に変換情報を書き、`hayabusa.exe --level-tuning`を実行することでルールファイルが書き換えられます。 ルールファイルが直接書き換えられることに注意して使用してください。 -`./config/level_tuning.txt`の例: +`./rules/config/level_tuning.txt`の例: ``` id,new_level 00000000-0000-0000-0000-000000000000,informational # sample level tuning line diff --git a/README.md b/README.md index 07a69398..0ed57fe9 100644 --- a/README.md +++ b/README.md @@ -313,7 +313,7 @@ USAGE: -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.' - --level-tuning 'Tune the rule level [default: ./config/level_tuning.txt]' + --level-tuning 'Tune the rule level [default: ./rules/config/level_tuning.txt]' -p --pivot-keywords-list 'Create a list of pivot keywords.' --contributors 'Prints the list of contributors.' ``` @@ -552,10 +552,10 @@ 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 `./config/level_tuning.txt` and executing `hayabusa.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.exe --level-tuning` which will update the `level` line in the rule file. Please note that the rule file will be updated directly. -`./config/level_tuning.txt` sample line: +`./rules/config/level_tuning.txt` sample line: ``` id,new_level diff --git a/config/level_tuning.txt b/config/level_tuning.txt deleted file mode 100644 index 5e3051b3..00000000 --- a/config/level_tuning.txt +++ /dev/null @@ -1,7 +0,0 @@ -id,new_level -00000000-0000-0000-0000-000000000000,informational # sample level tuning line -fdb62a13-9a81-4e5c-a38f-ea93a16f6d7c,medium # "Encoded FromBase64String". Originally critical. -61a7697c-cb79-42a8-a2ff-5f0cdfae0130,high # "CobaltStrike Service Installations in Registry". Originally critical. -36803969-5421-41ec-b92f-8500f79c23b0,low # "Detects persistence registry keys". Originally critical. Changed to low due to a high possibility of false positives. -06d71506-7beb-4f22-8888-e2e5e2ca7fd8,medium # "Mimikatz Use". Originally critical. Rule creates tons of false positives so lowered to medium. -dae8171c-5ec6-4396-b210-8466585b53e9,medium # "SCM Database Privileged Operation" \ No newline at end of file diff --git a/src/detections/configs.rs b/src/detections/configs.rs index f336aa1e..eff22a24 100644 --- a/src/detections/configs.rs +++ b/src/detections/configs.rs @@ -102,7 +102,7 @@ fn build_app<'a>() -> ArgMatches<'a> { .arg( // TODO: When update claps to 3.x, these can write in usage texts... Arg::from_usage("--level-tuning=[LEVEL_TUNING_FILE] 'Adjust rule level.'") - .default_value("./config/level_tuning.txt"), + .default_value("./rules/config/level_tuning.txt"), ) .usage(usages) .args_from_usage(usages) diff --git a/src/main.rs b/src/main.rs index dc3fdf9d..5b7d6abd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -235,7 +235,7 @@ impl App { .unwrap() .args .value_of("level-tuning") - .unwrap_or("./config/level_tuning.txt") + .unwrap_or("./rules/config/level_tuning.txt") .to_string(); if Path::new(&level_tuning_config_path).exists() { @@ -253,7 +253,7 @@ impl App { } else { AlertMessage::alert( &mut BufWriter::new(std::io::stderr().lock()), - "Need rule_levels.txt file to use --level-tuning option [default: ./config/level_tuning.txt]", + "Need rule_levels.txt file to use --level-tuning option [default: ./rules/config/level_tuning.txt]", ) .ok(); } From b43eb853e918d3b89fc58a53ae6092cb52757431 Mon Sep 17 00:00:00 2001 From: DustInDark Date: Wed, 20 Apr 2022 16:12:53 +0900 Subject: [PATCH 3/6] Added Channel column and Channel Abbreviations (#508) * added Channel output #504 * added test #504 * fixed clippy warnings * fixed convert serde value to Channel #504 * added channel output config #504 * added doc #504 * added Channel column and Channel addreviation * fixed file name typo * changed channel position #504 * fixed markdown warnings in CHANGELOG * readme update Co-authored-by: Tanaka Zakku <71482215+YamatoSecurity@users.noreply.github.com> --- CHANGELOG-Japanese.md | 11 ++++++++ CHANGELOG.md | 10 +++++++ README-Japanese.md | 34 ++++++++++++++++++++++++ README.md | 34 ++++++++++++++++++++++++ config/channel_abbreviations.txt | 27 +++++++++++++++++++ src/afterfact.rs | 45 +++++++++++++++++++++++--------- src/detections/detection.rs | 10 ++++++- src/detections/print.rs | 19 +++++++++----- src/detections/utils.rs | 8 +++--- 9 files changed, 175 insertions(+), 23 deletions(-) create mode 100644 config/channel_abbreviations.txt diff --git a/CHANGELOG-Japanese.md b/CHANGELOG-Japanese.md index fff7f601..1d0cb573 100644 --- a/CHANGELOG-Japanese.md +++ b/CHANGELOG-Japanese.md @@ -1,7 +1,9 @@ # 変更点 ## v1.2.0 [2022/04/15] Black Hat Asia Arsenal 2022 Preview Release + **新機能:** + - `-C / --config` オプションの追加。検知ルールのコンフィグを指定することが可能。(Windowsでのライブ調査に便利) (@hitenkoku) - `|equalsfield` と記載することでルール内で二つのフィールドの値が一致するかを記載に対応。 (@hach1yon) - `-p / --pivot-keywords-list` オプションの追加。攻撃されたマシン名や疑わしいユーザ名などの情報をピボットキーワードリストとして出力する。 (@kazuminn) @@ -9,6 +11,7 @@ - `--level-tuning` オプションの追加。ルールの検知ファイルを設定したコンフィグファイルに従って検知レベルをチューニングすることが可能(@itib、@hitenkoku) **改善:** + - 検知ルールとドキュメントの更新。 (@YamatoSecurity) - MacとLinuxのバイナリに必要なOpenSSLライブラリを静的コンパイルした。 (@YamatoSecurity) - タブ等の文字が含まれたフィールドに対しての検知性能の改善。 (@hach1yon、@hitenkoku) @@ -18,19 +21,24 @@ - イベントIDとタイトルが記載されたコンフィグファイルの名前を `timeline_event_info.txt` から `statistics_event_info.txt`に変更。 (@YamatoSecurity、 @garigariganzy) - 64bit Windowsで32bit版のバイナリを実行しないように修正(@hitenkoku) - MITRE ATT&CKのデータの出力を`output_tag.txt`で修正できるように修正(@hitenkoku) +- 出力にChannel名のカラムを追加(@hitenkoku) **バグ修正:** + - `.git` フォルダ内にある `.yml` ファイルがパースエラーを引き起こしていた問題の修正。 (@hitenkoku) - テスト用のルールファイルの読み込みエラーで不必要な改行が発生していた問題の修正。 (@hitenkoku) - Windows Terminalのバグで標準出力が途中で止まる場合がありましたが、Hayabusa側で解決しました。 (@hitenkoku) ## v1.1.0 [2022/03/03] + **新機能:** + - `-r / --rules`オプションで一つのルール指定が可能。(ルールをテストする際に便利!) (@kazuminn) - ルール更新オプション (`-u / --update-rules`): [hayabusa-rules](https://github.com/Yamato-Security/hayabusa-rules)レポジトリにある最新のルールに更新できる。 (@hitenkoku) - ライブ調査オプション (`-l / --live-analysis`): Windowsイベントログディレクトリを指定しないで、楽にWindows端末でライブ調査ができる。(@hitenkoku) **改善:** + - ドキュメンテーションの更新。 (@kazuminn、@itiB、@hitenkoku、@YamatoSecurity) - ルールの更新。(Hayabusaルール: 20個以上、Sigmaルール: 200個以上) (@YamatoSecurity) - Windowsバイナリは静的でコンパイルしているので、Visual C++ 再頒布可能パッケージをインストールする必要はない。(@hitenkoku) @@ -42,12 +50,15 @@ - Cargo crateの更新。 (@YamatoSecurity) **バグ修正:** + - `cargo update`がより安定するために、clapのバージョンを固定した。(@hitenkoku) - フィールドのタブや改行がある場合に、ルールが検知しなかったので、修正した。(@hitenkoku) ## v1.0.0-Release 2 [2022/01/27] + - アンチウィルスに誤検知されたExcelの結果ファイルの削除。(@YamatoSecurity) - Rustのevtxライブラリを0.7.2に更新。 (@YamatoSecurity) ## v1.0.0 [2021/12/25] + - 最初のリリース diff --git a/CHANGELOG.md b/CHANGELOG.md index fb3d8bff..6fb3bda5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v1.2.0 [2022/04/15] Black Hat Asia Arsenal 2022 Preview Release **New Features:** + - Specify config directory (`-C / --config`): When specifying a different rules directory, the rules config directory will still be the default `rules/config`, so this option is useful when you want to test rules and their config files in a different directory. (@hitenkoku) - `|equalsfield` aggregator: In order to write rules that compare if two fields are equal or not. (@hach1yon) - Pivot keyword list generator feature (`-p / --pivot-keywords-list`): Will generate a list of keywords to grep for to quickly identify compromised machines, suspicious usernames, files, etc... (@kazuminn) @@ -10,6 +11,7 @@ - `--level-tuning` option: You can tune the risk `level` in hayabusa and sigma rules to your environment. (@itib and @hitenkoku) **Enhancements:** + - Updated detection rules and documentation. (@YamatoSecurity) - Mac and Linux binaries now statically compile the OpenSSL libraries. (@YamatoSecurity) - Performance and accuracy improvement for fields with tabs, etc... in them. (@hach1yon and @hitenkoku) @@ -19,19 +21,24 @@ - Updated the event ID and title config file (`timeline_event_info.txt`) and changed the name to `statistics_event_info.txt`. (@YamatoSecurity and @garigariganzy) - 32-bit Hayabusa Windows binaries are now prevented from running on 64-bit Windows as it would cause unexpected results. (@hitenkoku) - MITRE ATT&CK tag output can be customized in `output_tag.txt`. (@hitenkoku) +- Added Channel column output. (@hitenkoku) **Bug Fixes:** + - `.yml` files in the `.git` folder would cause parse errors so they are now ignored. (@hitenkoku) - Removed unnecessary newline due to loading test file rules. (@hitenkoku) - Fixed output stopping in Windows Terminal due a bug in Terminal itself. (@hitenkoku) ## v1.1.0 [2022/03/03] + **New Features:** + - Can specify a single rule with the `-r / --rules` option. (Great for testing rules!) (@kazuminn) - Rule update option (`-u / --update-rules`): Update to the latest rules in the [hayabusa-rules](https://github.com/Yamato-Security/hayabusa-rules) repository. (@hitenkoku) - Live analysis option (`-l / --live-analysis`): Can easily perform live analysis on Windows machines without specifying the Windows event log directory. (@hitenkoku) **Enhancements:** + - Updated documentation. (@kazuminn , @hitenkoku , @YamatoSecurity) - Updated rules. (20+ Hayabusa rules, 200+ Sigma rules) (@YamatoSecurity) - Windows binaries are now statically compiled so installing Visual C++ Redistributable is not required. (@hitenkoku) @@ -43,12 +50,15 @@ - Updated cargo crates. (@YamatoSecurity) **Bug Fixes:** + - Made the clap library version static to make `cargo update` more stable. (@hitenkoku) - Some rules were not alerting if there were tabs or carriage returns in the fields. (@hitenkoku) ## v1.0.0-Release 2 [2022/01/27] + - Removed Excel result sample files as they were being flagged by anti-virus. (@YamatoSecurity) - Updated the Rust evtx library to 0.7.2 (@YamatoSecurity) ## v1.0.0 [2021/12/25] + - Initial release. diff --git a/README-Japanese.md b/README-Japanese.md index be8d893b..b0a648e4 100644 --- a/README-Japanese.md +++ b/README-Japanese.md @@ -56,6 +56,7 @@ Hayabusaは、日本の[Yamato Security](https://yamatosecurity.connpass.com/) - [サンプルevtxファイルでHayabusaをテストする](#サンプルevtxファイルでhayabusaをテストする) - [Hayabusaの出力](#hayabusaの出力) - [MITRE ATT&CK戦術の省略](#mitre-attck戦術の省略) + - [Channel情報の省略](#channel情報の省略) - [プログレスバー](#プログレスバー) - [標準出力へのカラー設定](#標準出力へのカラー設定) - [Hayabusaルール](#hayabusaルール) @@ -460,6 +461,7 @@ Hayabusaの結果を標準出力に表示しているとき(デフォルト) * `Timestamp`: デフォルトでは`YYYY-MM-DD HH:mm:ss.sss +hh:mm`形式になっています。イベントログの``フィールドから来ています。デフォルトのタイムゾーンはローカルのタイムゾーンになりますが、`--utc` オプションで UTC に変更することができます。 * `Computer`: イベントログの``フィールドから来ています。 +* `Channel`: ログ名です。イベントログの``フィールドから来ています。 * `Event ID`: イベントログの``フィールドから来ています。 * `Level`: YML検知ルールの`level`フィールドから来ています。(例:`informational`, `low`, `medium`, `high`, `critical`) デフォルトでは、すべてのレベルのアラートとイベントが出力されますが、`-m`オプションで最低のレベルを指定することができます。例えば`-m high`オプションを付けると、`high`と`critical`アラートしか出力されません。 * `Title`: YML検知ルールの`title`フィールドから来ています。 @@ -493,6 +495,38 @@ CSVファイルとして保存する場合、以下の列が追加されます: * `Exfil` : Exfiltration (持ち出し) * `Impact` : Impact (影響) +## Channel情報の省略 + +簡潔に出力するためにChannelの表示を以下のように省略しています。 +`config/channel_abbreviations.txt`の設定ファイルで自由に編集できます。 + +* `Application` : App +* `DNS Server` : DNS-Svr +* `Microsoft-ServiceBus-Client` : SvcBusCli +* `Microsoft-Windows-CodeIntegrity/Operational` : CodeInteg +* `Microsoft-Windows-LDAP-Client/Debug` : LDAP-Cli +* `Microsoft-Windows-AppLocker/MSI and Script` : AppLocker +* `Microsoft-Windows-AppLocker/EXE and DLL` : AppLocker +* `Microsoft-Windows-AppLocker/Packaged app-Deployment` : AppLocker +* `Microsoft-Windows-AppLocker/Packaged app-Execution` : AppLocker +* `Microsoft-Windows-Bits-Client/Operational` : BitsCli +* `Microsoft-Windows-DHCP-Server/Operational` : DHCP-Svr +* `Microsoft-Windows-DriverFrameworks-UserMode/Operational` : DvrFmwk +* `Microsoft-Windows-NTLM/Operational` : NTLM +* `Microsoft-Windows-SmbClient/Security` : SmbCliSec +* `Microsoft-Windows-Sysmon/Operational` : Sysmon +* `Microsoft-Windows-TaskScheduler/Operational` : TaskSch +* `Microsoft-Windows-PrintService/Admin` : PrintAdm +* `Microsoft-Windows-PrintService/Operational` : PrintOp +* `Microsoft-Windows-PowerShell/Operational` : PwSh +* `Microsoft-Windows-Windows Defender/Operational` : Defender +* `Microsoft-Windows-Windows Firewall With Advanced Security/Firewall` : Firewall +* `Microsoft-Windows-WMI-Activity/Operational` : WMI +* `MSExchange Management` : Exchange +* `Security` : Sec +* `System` : Sys +* `Windows PowerShell` : WinPwSh + ## プログレスバー プログレス・バーは、複数のevtxファイルに対してのみ機能します。 diff --git a/README.md b/README.md index 07a69398..2cf3d007 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Hayabusa is a **Windows event log fast forensics timeline generator** and **thre - [Testing Hayabusa on Sample Evtx Files](#testing-hayabusa-on-sample-evtx-files) - [Hayabusa Output](#hayabusa-output) - [MITRE ATT&CK Tactics Abbreviations](#mitre-attck-tactics-abbreviations) + - [Channel Abbreviations](#channel-abbreviations) - [Progress Bar](#progress-bar) - [Color Output](#color-output) - [Hayabusa Rules](#hayabusa-rules) @@ -453,6 +454,7 @@ When hayabusa output is being displayed to the screen (the default), it will dis * `Timestamp`: Default is `YYYY-MM-DD HH:mm:ss.sss +hh:mm` format. This comes from the `` field in the event log. The default timezone will be the local timezone but you can change the timezone to UTC with the `--utc` option. * `Computer`: This comes from the `` field in the event log. +* `Channel`: The name of log. This comes from the `` field in the event log. * `Event ID`: This comes from the `` field in the event log. * `Level`: This comes from the `level` field in the YML detection rule. (`informational`, `low`, `medium`, `high`, `critical`) By default, all level alerts will be displayed but you can set the minimum level with `-m`. For example, you can set `-m high`) in order to only scan for and display high and critical alerts. * `Title`: This comes from the `title` field in the YML detection rule. @@ -486,6 +488,38 @@ You can freely edit these abbreviations in the `config/output_tag.txt` configura * `Exfil` : Exfiltration * `Impact` : Impact +## Channel Abbreviations + +In order to save space, we use the following abbreviations when displaying Channel. +You can freely edit these abbreviations in the `config/config/channel_abbreviations.txt` configuration file. + +* `Application` : App +* `DNS Server` : DNS-Svr +* `Microsoft-ServiceBus-Client` : SvcBusCli +* `Microsoft-Windows-CodeIntegrity/Operational` : CodeInteg +* `Microsoft-Windows-LDAP-Client/Debug` : LDAP-Cli +* `Microsoft-Windows-AppLocker/MSI and Script` : AppLocker +* `Microsoft-Windows-AppLocker/EXE and DLL` : AppLocker +* `Microsoft-Windows-AppLocker/Packaged app-Deployment` : AppLocker +* `Microsoft-Windows-AppLocker/Packaged app-Execution` : AppLocker +* `Microsoft-Windows-Bits-Client/Operational` : BitsCli +* `Microsoft-Windows-DHCP-Server/Operational` : DHCP-Svr +* `Microsoft-Windows-DriverFrameworks-UserMode/Operational` : DvrFmwk +* `Microsoft-Windows-NTLM/Operational` : NTLM +* `Microsoft-Windows-SmbClient/Security` : SmbCliSec +* `Microsoft-Windows-Sysmon/Operational` : Sysmon +* `Microsoft-Windows-TaskScheduler/Operational` : TaskSch +* `Microsoft-Windows-PrintService/Admin` : PrintAdm +* `Microsoft-Windows-PrintService/Operational` : PrintOp +* `Microsoft-Windows-PowerShell/Operational` : PwSh +* `Microsoft-Windows-Windows Defender/Operational` : Defender +* `Microsoft-Windows-Windows Firewall With Advanced Security/Firewall` : Firewall +* `Microsoft-Windows-WMI-Activity/Operational` : WMI +* `MSExchange Management` : Exchange +* `Security` : Sec +* `System` : Sys +* `Windows PowerShell` : WinPwSh + ## Progress Bar The progress bar will only work with multiple evtx files. diff --git a/config/channel_abbreviations.txt b/config/channel_abbreviations.txt new file mode 100644 index 00000000..471fafa8 --- /dev/null +++ b/config/channel_abbreviations.txt @@ -0,0 +1,27 @@ +Channel,Abbreviation +Application,App +DNS Server,DNS-Svr +Microsoft-ServiceBus-Client,SvcBusCli +Microsoft-Windows-CodeIntegrity/Operational,CodeInteg +Microsoft-Windows-LDAP-Client/Debug,LDAP-Cli +Microsoft-Windows-AppLocker/MSI and Script,AppLocker +Microsoft-Windows-AppLocker/EXE and DLL,AppLocker +Microsoft-Windows-AppLocker/Packaged app-Deployment,AppLocker +Microsoft-Windows-AppLocker/Packaged app-Execution,AppLocker +Microsoft-Windows-Bits-Client/Operational,BitsCli +Microsoft-Windows-DHCP-Server/Operational,DHCP-Svr +Microsoft-Windows-DriverFrameworks-UserMode/Operational,DvrFmwk +Microsoft-Windows-NTLM/Operational,NTLM +Microsoft-Windows-SmbClient/Security,SmbCliSec +Microsoft-Windows-Sysmon/Operational,Sysmon +Microsoft-Windows-TaskScheduler/Operational,TaskSch +Microsoft-Windows-PrintService/Admin,PrintAdm +Microsoft-Windows-PrintService/Operational,PrintOp +Microsoft-Windows-PowerShell/Operational,PwSh +Microsoft-Windows-Windows Defender/Operational,Defender +Microsoft-Windows-Windows Firewall With Advanced Security/Firewall,Firewall +Microsoft-Windows-WMI-Activity/Operational,WMI +MSExchange Management,Exchange +Security,Sec +System,Sys +Windows PowerShell,WinPwSh \ No newline at end of file diff --git a/src/afterfact.rs b/src/afterfact.rs index df195f8d..036a0cd4 100644 --- a/src/afterfact.rs +++ b/src/afterfact.rs @@ -19,6 +19,7 @@ use std::process; pub struct CsvFormat<'a> { timestamp: &'a str, computer: &'a str, + channel: &'a str, event_i_d: &'a str, level: &'a str, mitre_attack: &'a str, @@ -35,6 +36,7 @@ pub struct CsvFormat<'a> { pub struct DisplayFormat<'a> { timestamp: &'a str, pub computer: &'a str, + pub channel: &'a str, pub event_i_d: &'a str, pub level: &'a str, pub rule_title: &'a str, @@ -167,6 +169,7 @@ fn emit_csv( level: &_format_cell(&level, ColPos::Other, colors), computer: &_format_cell(&detect_info.computername, ColPos::Other, colors), event_i_d: &_format_cell(&detect_info.eventid, ColPos::Other, colors), + channel: &_format_cell(&detect_info.channel, ColPos::Other, colors), rule_title: &_format_cell(&detect_info.alert, ColPos::Other, colors), details: &_format_cell(&details, ColPos::Other, colors), record_information: recinfo.as_deref(), @@ -179,6 +182,7 @@ fn emit_csv( level: &level, computer: &detect_info.computername, event_i_d: &detect_info.eventid, + channel: &detect_info.channel, mitre_attack: &detect_info.tag_info, rule_title: &detect_info.alert, details: &detect_info.detail, @@ -323,6 +327,7 @@ mod tests { use crate::afterfact::emit_csv; use crate::detections::print; use crate::detections::print::DetectInfo; + use crate::detections::print::CH_CONFIG; use chrono::{Local, TimeZone, Utc}; use serde_json::Value; use std::fs::File; @@ -337,12 +342,13 @@ mod tests { } fn test_emit_csv_output() { - let testfilepath: &str = "test.evtx"; - let testrulepath: &str = "test-rule.yml"; + let test_filepath: &str = "test.evtx"; + let test_rulepath: &str = "test-rule.yml"; let test_title = "test_title"; let test_level = "high"; let test_computername = "testcomputer"; let test_eventid = "1111"; + let test_channel = "Sec"; let output = "pokepoke"; let test_attack = "execution/txxxx.yyy"; let test_recinfo = "record_infoinfo11"; @@ -368,11 +374,15 @@ mod tests { &event, output.to_string(), DetectInfo { - filepath: testfilepath.to_string(), - rulepath: testrulepath.to_string(), + filepath: test_filepath.to_string(), + rulepath: test_rulepath.to_string(), level: test_level.to_string(), computername: test_computername.to_string(), eventid: test_eventid.to_string(), + channel: CH_CONFIG + .get("Security") + .unwrap_or(&String::default()) + .to_string(), alert: test_title.to_string(), detail: String::default(), tag_info: test_attack.to_string(), @@ -385,7 +395,7 @@ mod tests { .unwrap(); let expect_tz = expect_time.with_timezone(&Local); let expect = - "Timestamp,Computer,EventID,Level,MitreAttack,RuleTitle,Details,RecordInformation,RulePath,FilePath\n" + "Timestamp,Computer,Channel,EventID,Level,MitreAttack,RuleTitle,Details,RecordInformation,RulePath,FilePath\n" .to_string() + &expect_tz .clone() @@ -394,6 +404,8 @@ mod tests { + "," + test_computername + "," + + test_channel + + "," + test_eventid + "," + test_level @@ -406,9 +418,9 @@ mod tests { + "," + test_recinfo + "," - + testrulepath + + test_rulepath + "," - + testfilepath + + test_filepath + "\n"; let mut file: Box = Box::new(File::create("./test_emit_csv.csv").unwrap()); assert!(emit_csv(&mut file, false, None).is_ok()); @@ -423,12 +435,13 @@ mod tests { } fn check_emit_csv_display() { - let testfilepath: &str = "test2.evtx"; - let testrulepath: &str = "test-rule2.yml"; + let test_filepath: &str = "test2.evtx"; + let test_rulepath: &str = "test-rule2.yml"; let test_title = "test_title2"; let test_level = "medium"; let test_computername = "testcomputer2"; let test_eventid = "2222"; + let expect_channel = "Sysmon"; let output = "displaytest"; let test_attack = "execution/txxxx.zzz"; { @@ -453,11 +466,15 @@ mod tests { &event, output.to_string(), DetectInfo { - filepath: testfilepath.to_string(), - rulepath: testrulepath.to_string(), + filepath: test_filepath.to_string(), + rulepath: test_rulepath.to_string(), level: test_level.to_string(), computername: test_computername.to_string(), eventid: test_eventid.to_string(), + channel: CH_CONFIG + .get("Microsoft-Windows-Sysmon/Operational") + .unwrap_or(&String::default()) + .to_string(), alert: test_title.to_string(), detail: String::default(), tag_info: test_attack.to_string(), @@ -471,7 +488,7 @@ mod tests { .unwrap(); let expect_tz = expect_time.with_timezone(&Local); let expect_header = - "Timestamp|Computer|EventID|Level|RuleTitle|Details|RecordInformation\n"; + "Timestamp|Computer|Channel|EventID|Level|RuleTitle|Details|RecordInformation\n"; let expect_colored = expect_header.to_string() + &get_white_color_string( &expect_tz @@ -482,6 +499,8 @@ mod tests { + " | " + &get_white_color_string(test_computername) + " | " + + &get_white_color_string(expect_channel) + + " | " + &get_white_color_string(test_eventid) + " | " + &get_white_color_string(test_level) @@ -500,6 +519,8 @@ mod tests { + " | " + test_computername + " | " + + expect_channel + + " | " + test_eventid + " | " + test_level diff --git a/src/detections/detection.rs b/src/detections/detection.rs index 47754ecc..b6b578d8 100644 --- a/src/detections/detection.rs +++ b/src/detections/detection.rs @@ -9,7 +9,7 @@ use crate::detections::print::MESSAGES; use crate::detections::print::PIVOT_KEYWORD_LIST_FLAG; use crate::detections::print::QUIET_ERRORS_FLAG; use crate::detections::print::STATISTICS_FLAG; -use crate::detections::print::TAGS_CONFIG; +use crate::detections::print::{CH_CONFIG, TAGS_CONFIG}; use crate::detections::rule; use crate::detections::rule::AggResult; use crate::detections::rule::RuleNode; @@ -219,6 +219,13 @@ impl Detection { .replace('\"', ""), eventid: get_serde_number_to_string(&record_info.record["Event"]["System"]["EventID"]) .unwrap_or_else(|| "-".to_owned()), + channel: CH_CONFIG + .get( + &get_serde_number_to_string(&record_info.record["Event"]["System"]["Channel"]) + .unwrap_or_default(), + ) + .unwrap_or(&String::default()) + .to_string(), alert: rule.yaml["title"].as_str().unwrap_or("").to_string(), detail: String::default(), tag_info: tag_info.join(" | "), @@ -252,6 +259,7 @@ impl Detection { level: rule.yaml["level"].as_str().unwrap_or("").to_owned(), computername: "-".to_owned(), eventid: "-".to_owned(), + channel: "-".to_owned(), alert: rule.yaml["title"].as_str().unwrap_or("").to_owned(), detail: output, record_information: rec_info, diff --git a/src/detections/print.rs b/src/detections/print.rs index 4cf13f07..4ba395c2 100644 --- a/src/detections/print.rs +++ b/src/detections/print.rs @@ -28,6 +28,7 @@ pub struct DetectInfo { pub level: String, pub computername: String, pub eventid: String, + pub channel: String, pub alert: String, pub detail: String, pub tag_info: String, @@ -55,7 +56,9 @@ lazy_static! { .args .is_present("statistics"); pub static ref TAGS_CONFIG: HashMap = - Message::create_tags_config("config/output_tag.txt"); + Message::create_output_filter_config("config/output_tag.txt"); + pub static ref CH_CONFIG: HashMap = + Message::create_output_filter_config("config/channel_abbreviations.txt"); pub static ref PIVOT_KEYWORD_LIST_FLAG: bool = configs::CONFIG .read() .unwrap() @@ -77,7 +80,7 @@ impl Message { /// ファイルパスで記載されたtagでのフル名、表示の際に置き換えられる文字列のHashMapを作成する関数。tagではこのHashMapのキーに対応しない出力は出力しないものとする /// ex. attack.impact,Impact - pub fn create_tags_config(path: &str) -> HashMap { + pub fn create_output_filter_config(path: &str) -> HashMap { let read_result = utils::read_csv(path); if read_result.is_err() { AlertMessage::alert( @@ -283,6 +286,7 @@ mod tests { level: "high".to_string(), computername: "testcomputer1".to_string(), eventid: "1".to_string(), + channel: String::default(), alert: "test1".to_string(), detail: String::default(), tag_info: "txxx.001".to_string(), @@ -314,6 +318,7 @@ mod tests { level: "high".to_string(), computername: "testcomputer2".to_string(), eventid: "2".to_string(), + channel: String::default(), alert: "test2".to_string(), detail: String::default(), tag_info: "txxx.002".to_string(), @@ -345,6 +350,7 @@ mod tests { level: "high".to_string(), computername: "testcomputer3".to_string(), eventid: "3".to_string(), + channel: String::default(), alert: "test3".to_string(), detail: String::default(), tag_info: "txxx.003".to_string(), @@ -371,6 +377,7 @@ mod tests { level: "medium".to_string(), computername: "testcomputer4".to_string(), eventid: "4".to_string(), + channel: String::default(), alert: "test4".to_string(), detail: String::default(), tag_info: "txxx.004".to_string(), @@ -380,7 +387,7 @@ mod tests { let display = format!("{}", format_args!("{:?}", message)); println!("display::::{}", display); - let expect = "Message { map: {1970-01-01T00:00:00Z: [DetectInfo { filepath: \"a\", rulepath: \"test_rule4\", level: \"medium\", computername: \"testcomputer4\", eventid: \"4\", alert: \"test4\", detail: \"CommandLine4: hoge\", tag_info: \"txxx.004\", record_information: Some(\"record_information4\") }], 1996-02-27T01:05:01Z: [DetectInfo { filepath: \"a\", rulepath: \"test_rule\", level: \"high\", computername: \"testcomputer1\", eventid: \"1\", alert: \"test1\", detail: \"CommandLine1: hoge\", tag_info: \"txxx.001\", record_information: Some(\"record_information1\") }, DetectInfo { filepath: \"a\", rulepath: \"test_rule2\", level: \"high\", computername: \"testcomputer2\", eventid: \"2\", alert: \"test2\", detail: \"CommandLine2: hoge\", tag_info: \"txxx.002\", record_information: Some(\"record_information2\") }], 2000-01-21T09:06:01Z: [DetectInfo { filepath: \"a\", rulepath: \"test_rule3\", level: \"high\", computername: \"testcomputer3\", eventid: \"3\", alert: \"test3\", detail: \"CommandLine3: hoge\", tag_info: \"txxx.003\", record_information: Some(\"record_information3\") }]} }"; + let expect = "Message { map: {1970-01-01T00:00:00Z: [DetectInfo { filepath: \"a\", rulepath: \"test_rule4\", level: \"medium\", computername: \"testcomputer4\", eventid: \"4\", channel: \"\", alert: \"test4\", detail: \"CommandLine4: hoge\", tag_info: \"txxx.004\", record_information: Some(\"record_information4\") }], 1996-02-27T01:05:01Z: [DetectInfo { filepath: \"a\", rulepath: \"test_rule\", level: \"high\", computername: \"testcomputer1\", eventid: \"1\", channel: \"\", alert: \"test1\", detail: \"CommandLine1: hoge\", tag_info: \"txxx.001\", record_information: Some(\"record_information1\") }, DetectInfo { filepath: \"a\", rulepath: \"test_rule2\", level: \"high\", computername: \"testcomputer2\", eventid: \"2\", channel: \"\", alert: \"test2\", detail: \"CommandLine2: hoge\", tag_info: \"txxx.002\", record_information: Some(\"record_information2\") }], 2000-01-21T09:06:01Z: [DetectInfo { filepath: \"a\", rulepath: \"test_rule3\", level: \"high\", computername: \"testcomputer3\", eventid: \"3\", channel: \"\", alert: \"test3\", detail: \"CommandLine3: hoge\", tag_info: \"txxx.003\", record_information: Some(\"record_information3\") }]} }"; assert_eq!(display, expect); } @@ -474,7 +481,7 @@ mod tests { ); } #[test] - /// outputで指定されているキー(eventkey_alias.txt内で設定済み)が対象のレコード内に該当する情報がない場合の出力テスト + /// output test when no exist info in target record output and described key-value data in eventkey_alias.txt fn test_parse_message_not_exist_value_in_record() { let mut message = Message::new(); let json_str = r##" @@ -502,9 +509,9 @@ mod tests { ); } #[test] - /// output_tag.txtの読み込みテスト + /// test of loading output filter config by output_tag.txt fn test_load_output_tag() { - let actual = Message::create_tags_config("test_files/config/output_tag.txt"); + let actual = Message::create_output_filter_config("test_files/config/output_tag.txt"); let expected: HashMap = HashMap::from([ ("attack.impact".to_string(), "Impact".to_string()), ("xxx".to_string(), "yyy".to_string()), diff --git a/src/detections/utils.rs b/src/detections/utils.rs index 7172f931..7fe6603c 100644 --- a/src/detections/utils.rs +++ b/src/detections/utils.rs @@ -184,11 +184,11 @@ pub fn get_event_value<'a>(key: &str, event_value: &'a Value) -> Option<&'a Valu pub fn get_thread_num() -> usize { let def_thread_num_str = num_cpus::get().to_string(); let conf = configs::CONFIG.read().unwrap(); - let threadnum = &conf - .args + conf.args .value_of("thread-number") - .unwrap_or(def_thread_num_str.as_str()); - threadnum.parse::().unwrap() + .unwrap_or(def_thread_num_str.as_str()) + .parse::() + .unwrap() } pub fn create_tokio_runtime() -> Runtime { From 06ccf8382b34f96316e45ed86508592d4ccf6413 Mon Sep 17 00:00:00 2001 From: DustInDark Date: Wed, 20 Apr 2022 18:30:05 +0900 Subject: [PATCH 4/6] fixed to include noisy and exclude rules when level tuning #511 --- src/filter.rs | 12 +++++++++--- src/main.rs | 4 +--- src/options/level_tuning.rs | 5 +++-- src/yaml.rs | 12 +++--------- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/filter.rs b/src/filter.rs index 636436f9..766f2d35 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -19,10 +19,16 @@ pub struct RuleExclude { pub no_use_rule: HashSet, } +impl RuleExclude { + pub fn default() -> RuleExclude { + RuleExclude { + no_use_rule: HashSet::new(), + } + } +} + pub fn exclude_ids() -> RuleExclude { - let mut exclude_ids = RuleExclude { - no_use_rule: HashSet::new(), - }; + let mut exclude_ids = RuleExclude::default(); if !configs::CONFIG .read() diff --git a/src/main.rs b/src/main.rs index 5b7d6abd..359465e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -775,9 +775,7 @@ impl App { .read_dir( rule_folder_path, "INFORMATIONAL", - &filter::RuleExclude { - no_use_rule: HashSet::new(), - }, + &filter::RuleExclude::default(), ) .ok(); diff --git a/src/options/level_tuning.rs b/src/options/level_tuning.rs index 9ca51d18..4aede5b8 100644 --- a/src/options/level_tuning.rs +++ b/src/options/level_tuning.rs @@ -1,5 +1,5 @@ use crate::detections::{configs, utils}; -use crate::filter; +use crate::filter::RuleExclude; use crate::yaml::ParseYaml; use std::collections::HashMap; use std::fs::{self, File}; @@ -45,8 +45,9 @@ impl LevelTuning { // Read Rule files let mut rulefile_loader = ParseYaml::new(); + //noisy rules and exclude rules treats as update target let result_readdir = - rulefile_loader.read_dir(rules_path, "informational", &filter::exclude_ids()); + rulefile_loader.read_dir(rules_path, "informational", &RuleExclude::default()); if result_readdir.is_err() { return Result::Err(format!("{}", result_readdir.unwrap_err())); } diff --git a/src/yaml.rs b/src/yaml.rs index e16ce277..192fe41f 100644 --- a/src/yaml.rs +++ b/src/yaml.rs @@ -290,9 +290,7 @@ mod tests { AlertMessage::create_error_log(ERROR_LOG_PATH.to_string()); let mut yaml = yaml::ParseYaml::new(); - let exclude_ids = RuleExclude { - no_use_rule: HashSet::new(), - }; + let exclude_ids = RuleExclude::default(); let _ = &yaml.read_dir( "test_files/rules/yaml/1.yml", &String::default(), @@ -401,9 +399,7 @@ mod tests { let mut yaml = yaml::ParseYaml::new(); let path = Path::new("test_files/rules/yaml"); - let exclude_ids = RuleExclude { - no_use_rule: HashSet::new(), - }; + let exclude_ids = RuleExclude::default(); yaml.read_dir(path, "", &exclude_ids).unwrap(); assert_eq!(yaml.ignorerule_count, 0); } @@ -411,9 +407,7 @@ mod tests { fn test_exclude_deprecated_rules_file() { let mut yaml = yaml::ParseYaml::new(); let path = Path::new("test_files/rules/deprecated"); - let exclude_ids = RuleExclude { - no_use_rule: HashSet::new(), - }; + let exclude_ids = RuleExclude::default(); yaml.read_dir(path, "", &exclude_ids).unwrap(); assert_eq!(yaml.ignorerule_count, 1); } From ca735817d4b17b84ac713cc6d0bbb095bde427de Mon Sep 17 00:00:00 2001 From: DustInDark Date: Wed, 20 Apr 2022 18:32:41 +0900 Subject: [PATCH 5/6] removed comment out import --- src/options/level_tuning.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/options/level_tuning.rs b/src/options/level_tuning.rs index 4aede5b8..c8cf6283 100644 --- a/src/options/level_tuning.rs +++ b/src/options/level_tuning.rs @@ -99,9 +99,6 @@ impl LevelTuning { #[cfg(test)] mod tests { - // use crate::{filter::RuleExclude, yaml}; - // use hashbrown::HashSet; - use super::*; #[test] From 0414b5af7829ed285ff3668bc8287d4d683ef553 Mon Sep 17 00:00:00 2001 From: DustInDark Date: Thu, 21 Apr 2022 21:20:31 +0900 Subject: [PATCH 6/6] changed force update to hayabusa-rules #490 (#509) * changed force update to hayabusa-rules #490 * added note when update option is used * readme update * cargo and changelog updates * changed jp translation Co-authored-by: Tanaka Zakku <71482215+YamatoSecurity@users.noreply.github.com> --- CHANGELOG-Japanese.md | 9 +++++++++ CHANGELOG.md | 10 +++++++++- Cargo.lock | 40 +++++++++++++++++++--------------------- Cargo.toml | 2 +- README-Japanese.md | 5 +++++ README.md | 5 +++++ src/main.rs | 35 ++++++++++++++++++++++++++--------- 7 files changed, 74 insertions(+), 32 deletions(-) diff --git a/CHANGELOG-Japanese.md b/CHANGELOG-Japanese.md index 1d0cb573..5c1e0b95 100644 --- a/CHANGELOG-Japanese.md +++ b/CHANGELOG-Japanese.md @@ -1,5 +1,14 @@ # 変更点 +## v1.2.1 [2022/04/20] Black Hat Asia Arsenal 2022 Preview Release + +**新機能:** +- Added a `Channel` column to the output based on the `./config/channel_abbreviations` config file. (@hitenkoku) +- Rule and rule config files are now forcefully updated. (@hitenkoku) + +**バグ修正:** +- Rules marked as noisy or excluded would not have their `level` changed with `--level-tuning` but now all rules will be checked. (@hitenkoku) + ## v1.2.0 [2022/04/15] Black Hat Asia Arsenal 2022 Preview Release **新機能:** diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fb3bda5..6baa48c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,17 @@ # Changes +## v1.2.1 [2022/04/20] Black Hat Asia Arsenal 2022 Preview Release + +**New Features:** +- Added a `Channel` column to the output based on the `./config/channel_abbreviations.txt` config file. (@hitenkoku) +- Rule and rule config files are now forcefully updated. (@hitenkoku) + +**Bug Fixes:** +- Rules marked as noisy or excluded would not have their `level` changed with `--level-tuning` but now all rules will be checked. (@hitenkoku) + ## v1.2.0 [2022/04/15] Black Hat Asia Arsenal 2022 Preview Release **New Features:** - - Specify config directory (`-C / --config`): When specifying a different rules directory, the rules config directory will still be the default `rules/config`, so this option is useful when you want to test rules and their config files in a different directory. (@hitenkoku) - `|equalsfield` aggregator: In order to write rules that compare if two fields are equal or not. (@hach1yon) - Pivot keyword list generator feature (`-p / --pivot-keywords-list`): Will generate a list of keywords to grep for to quickly identify compromised machines, suspicious usernames, files, etc... (@kazuminn) diff --git a/Cargo.lock b/Cargo.lock index 32666b64..a67cedfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,9 +80,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" +checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" dependencies = [ "addr2line", "cc", @@ -684,9 +684,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" dependencies = [ "cfg-if 1.0.0", "crc32fast", @@ -842,7 +842,7 @@ dependencies = [ [[package]] name = "hayabusa" -version = "1.2.0" +version = "1.2.1" dependencies = [ "base64 0.13.0", "chrono", @@ -930,9 +930,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" +checksum = "6330e8a36bd8c859f3fa6d9382911fbb7147ec39807f63b923933a247240b9ba" [[package]] name = "humantime" @@ -1114,9 +1114,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.122" +version = "0.2.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" +checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" [[package]] name = "libgit2-sys" @@ -1246,12 +1246,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" dependencies = [ "adler", - "autocfg 1.1.0", ] [[package]] @@ -1388,9 +1387,9 @@ dependencies = [ [[package]] name = "object" -version = "0.27.1" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +checksum = "40bec70ba014595f99f7aa110b84331ffe1ee9aece7fe6f387cc7e3ecda4d456" dependencies = [ "memchr", ] @@ -1698,9 +1697,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221" dependencies = [ "autocfg 1.1.0", "crossbeam-deque 0.8.1", @@ -1710,14 +1709,13 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "9f51245e1e62e1f1629cbfec37b5793bbabcaeb90f30e94d2ba03564687353e4" dependencies = [ "crossbeam-channel", "crossbeam-deque 0.8.1", "crossbeam-utils 0.8.8", - "lazy_static", "num_cpus", ] @@ -1822,9 +1820,9 @@ dependencies = [ [[package]] name = "rpmalloc-sys" -version = "0.2.2+1.4.1" +version = "0.2.3+b097fd0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "370e623bf2ca97dd497b7dd0e2889ec953a46c8c268489a818a5e305633e8609" +checksum = "8d4b7d5e225a53887ee57fcec492eaf114b8e290f7072d035adc6ddd6810b67b" dependencies = [ "cc", "libc", diff --git a/Cargo.toml b/Cargo.toml index 276eefb8..e36b1f6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hayabusa" -version = "1.2.0" +version = "1.2.1" authors = ["Yamato Security @SecurityYamato"] edition = "2021" diff --git a/README-Japanese.md b/README-Japanese.md index 57a273a1..335bb4cf 100644 --- a/README-Japanese.md +++ b/README-Japanese.md @@ -171,6 +171,11 @@ hayabusa.exe -u アップデートが失敗した場合は、`rules`フォルダの名前を変更してから、もう一回アップデートしてみて下さい。 +>> 注意: アップデートを実行する際に `rules` フォルダは [hayabusa-rules](https://github.com/Yamato-Security/hayabusa-rules) レポジトリの最新のルールとコンフィグファイルに置き換えられます +>> 既存ファイルへの修正はすべて上書きされますので、アップデート実行前に編集したファイルのバックアップをおすすめします。 +>> もし、`--level-tuning` を行っているのであれば、アップデート後にルールファイルの再調整をしてください +>> `rules`フォルダ内に新しく追加したルールは、アップデート時に上書きもしくは削除は行われません。 + # ソースコードからのコンパイル(任意) Rustがインストールされている場合、以下のコマンドでソースコードからコンパイルすることができます: diff --git a/README.md b/README.md index c880df3b..4278b1e3 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,11 @@ hayabusa.exe -u If the update fails, you may need to rename the `rules` folder and try again. +>> Caution: When updating, rules and config files in the `rules` folder are replaced with the latest rules and config files in the [hayabusa-rules](https://github.com/Yamato-Security/hayabusa-rules) repository. +>> Any changes you make to existing files will be overwritten, so we recommend that you make backups of any files that you edit before updating. +>> If you are performing level tuning with `--level-tuning`, please re-tune your rule files after each update. +>> If you add new rules inside of the `rules` folder, they will **not** be overwritten or deleted when updating. + # Compiling From Source (Optional) If you have Rust installed, you can compile from source with the following command: diff --git a/src/main.rs b/src/main.rs index 359465e8..f81629f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -654,17 +654,21 @@ impl App { println!( "Attempting to git clone the hayabusa-rules repository into the rules folder." ); - // レポジトリが開けなかった段階でhayabusa rulesのgit cloneを実施する + // execution git clone of hayabusa-rules repository when failed open hayabusa repository. result = self.clone_rules(); } else if hayabusa_rule_repo.is_ok() { - // rulesのrepositoryが確認できる場合 - // origin/mainのfetchができなくなるケースはネットワークなどのケースが考えられるため、git cloneは実施しない + // case of exist hayabusa-rules repository + self._repo_main_reset_hard(hayabusa_rule_repo.as_ref().unwrap())?; + // case of failed fetching origin/main, git clone is not executed so network error has occurred possibly. prev_modified_rules = self.get_updated_rules("rules", &prev_modified_time); prev_modified_time = fs::metadata("rules").unwrap().modified().unwrap(); - result = self.pull_repository(hayabusa_rule_repo.unwrap()); + result = self.pull_repository(&hayabusa_rule_repo.unwrap()); } else { - // hayabusa-rulesのrepositoryがrulesに存在しない場合 - // hayabusa repositoryがあればsubmodule情報もあると思われるのでupdate + // case of no exist hayabusa-rules repository in rules. + // execute update because submodule information exists if hayabusa repository exists submodule information. + + self._repo_main_reset_hard(hayabusa_rule_repo.as_ref().unwrap())?; + prev_modified_time = fs::metadata("rules").unwrap().modified().unwrap(); let rules_path = Path::new("rules"); if !rules_path.exists() { @@ -673,12 +677,12 @@ impl App { let hayabusa_repo = hayabusa_repo.unwrap(); let submodules = hayabusa_repo.submodules()?; let mut is_success_submodule_update = true; - // submoduleのname参照だと参照先を変えることで意図しないフォルダを削除する可能性があるためハードコーディングする + // submodule rules erase path is hard coding to avoid unintentional remove folder. fs::remove_dir_all(".git/.submodule/rules").ok(); for mut submodule in submodules { submodule.update(true, None)?; let submodule_repo = submodule.open()?; - if let Err(e) = self.pull_repository(submodule_repo) { + if let Err(e) = self.pull_repository(&submodule_repo) { AlertMessage::alert( &mut BufWriter::new(std::io::stderr().lock()), &format!("Failed submodule update. {}", e), @@ -701,8 +705,21 @@ impl App { result } + /// hard reset in main branch + fn _repo_main_reset_hard(&self, input_repo: &Repository) -> Result<(), git2::Error> { + let branch = input_repo + .find_branch("main", git2::BranchType::Local) + .unwrap(); + let local_head = branch.get().target().unwrap(); + let object = input_repo.find_object(local_head, None).unwrap(); + match input_repo.reset(&object, git2::ResetType::Hard, None) { + Ok(()) => Ok(()), + _ => Err(git2::Error::from_str("Failed reset main branch in rules")), + } + } + /// Pull(fetch and fast-forward merge) repositoryto input_repo. - fn pull_repository(&self, input_repo: Repository) -> Result { + fn pull_repository(&self, input_repo: &Repository) -> Result { match input_repo .find_remote("origin")? .fetch(&["main"], None, None)