Merge branch '651-organize-menu' of https://github.com/Yamato-Security/hayabusa into 651-organize-menu

This commit is contained in:
DastInDark
2022-08-11 18:45:02 +09:00
9 changed files with 453 additions and 211 deletions

View File

@@ -186,7 +186,7 @@ pub struct Config {
/// Tune alert levels (default: ./rules/config/level_tuning.txt)
#[clap(
help_heading = Some("ADVANCED"),
help_heading = Some("OTHER-ACTIONS"),
long = "level-tuning",
hide_default_value = true,
value_name = "FILE"
@@ -217,12 +217,12 @@ pub struct Config {
#[clap(help_heading = Some("FILTERING"), long = "exclude-status", multiple_values = true, value_name = "STATUS")]
pub exclude_status: Option<Vec<String>>,
/// Specify output profile
#[clap(help_heading = Some("OUTPUT-SETTINGS"), short = 'P', long = "profile")]
/// Specify output profile (minimal, standard, verbose, verbose-all-field-info, verbose-details-and-all-field-info)
#[clap(help_heading = Some("OUTPUT"), short = 'P', long = "profile")]
pub profile: Option<String>,
/// Set default output profile
#[clap(help_heading = Some("OUTPUT-SETTINGS"), long = "set-default-profile", value_name = "PROFILE")]
#[clap(help_heading = Some("OTHER-ACTIONS"), long = "set-default-profile", value_name = "PROFILE")]
pub set_default_profile: Option<String>,
}

View File

@@ -218,7 +218,7 @@ impl DefaultMatcher {
});
}
/// YEAのルールファイルのフィールド名とそれに続いて指定されるパイプを、正規表現形式の文字列に変換します。
/// Hayabusaのルールファイルのフィールド名とそれに続いて指定されるパイプを、正規表現形式の文字列に変換します。
/// ワイルドカードの文字列を正規表現にする処理もこのメソッドに実装されています。patternにワイルドカードの文字列を指定して、pipesにPipeElement::Wildcardを指定すればOK!!
fn from_pattern_to_regex_str(pattern: String, pipes: &[PipeElement]) -> String {
// パターンをPipeで処理する。
@@ -346,6 +346,17 @@ impl LeafMatcher for DefaultMatcher {
return false;
}
// yamlにnullが設定されていた場合
if self.re.is_none() {
// レコード内に対象のフィールドが存在しなければ検知したものとして扱う
for v in self.key_list.iter() {
if recinfo.get_value(v).is_none() {
return true;
}
}
return false;
}
if event_value.is_none() {
return false;
}
@@ -353,7 +364,7 @@ impl LeafMatcher for DefaultMatcher {
let event_value_str = event_value.unwrap();
if self.key_list.is_empty() {
// この場合ただのgrep検索なので、ただ正規表現に一致するかどうか調べればよいだけ
return self.re.as_ref().unwrap().is_match(event_value_str);
self.re.as_ref().unwrap().is_match(event_value_str)
} else {
// 通常の検索はこっち
self.is_regex_fullmatch(event_value_str)
@@ -1984,4 +1995,65 @@ mod tests {
}
}
}
#[test]
fn test_eq_field_null() {
// 値でnullであった場合に対象のフィールドが存在しないことを確認
let rule_str = r#"
enabled: true
detection:
selection:
Channel:
value: Security
Takoyaki:
value: null
details: 'command=%CommandLine%'
"#;
let record_json_str = r#"
{
"Event": {"System": {"EventID": 4103, "Channel": "Security", "Computer": "Powershell" }},
"Event_attributes": {"xmlns": "http://schemas.microsoft.com/win/2004/08/events/event"}
}"#;
let mut rule_node = parse_rule_from_str(rule_str);
match serde_json::from_str(record_json_str) {
Ok(record) => {
let keys = detections::rule::get_detection_keys(&rule_node);
let recinfo = utils::create_rec_info(record, "testpath".to_owned(), &keys);
assert!(rule_node.select(&recinfo));
}
Err(_) => {
panic!("Failed to parse json record.");
}
}
}
#[test]
fn test_eq_field_null_not_detect() {
// 値でnullであった場合に対象のフィールドが存在しないことを確認するテスト
let rule_str = r#"
enabled: true
detection:
selection:
EventID: null
details: 'command=%CommandLine%'
"#;
let record_json_str = r#"{
"Event": {"System": {"EventID": 4103, "Channel": "Security", "Computer": "Powershell"}},
"Event_attributes": {"xmlns": "http://schemas.microsoft.com/win/2004/08/events/event"}
}"#;
let mut rule_node = parse_rule_from_str(rule_str);
match serde_json::from_str(record_json_str) {
Ok(record) => {
let keys = detections::rule::get_detection_keys(&rule_node);
let recinfo = utils::create_rec_info(record, "testpath".to_owned(), &keys);
assert!(!rule_node.select(&recinfo));
}
Err(e) => {
panic!("Failed to parse json record.{:?}", e);
}
}
}
}