reduce output mitre attack detail tachnique No. by config file (#483)
* reduced mitre attck tag output by config file #477 * prepared 1.2.0 version toml * added test files and mitre attck strategy tag file #477 * fixed cargo.toml version * updated cargo.lock * output tag english update * cargo fmt Co-authored-by: Tanaka Zakku <71482215+YamatoSecurity@users.noreply.github.com>
This commit is contained in:
12
Cargo.lock
generated
12
Cargo.lock
generated
@@ -108,12 +108,6 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base64"
|
|
||||||
version = "0.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@@ -842,9 +836,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hayabusa"
|
name = "hayabusa"
|
||||||
version = "1.1.0"
|
version = "1.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.13.0",
|
"base64",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"colored",
|
"colored",
|
||||||
@@ -1782,7 +1776,7 @@ version = "0.9.24"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab"
|
checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.10.1",
|
"base64",
|
||||||
"bytes 0.4.12",
|
"bytes 0.4.12",
|
||||||
"cookie",
|
"cookie",
|
||||||
"cookie_store",
|
"cookie_store",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "hayabusa"
|
name = "hayabusa"
|
||||||
version = "1.1.0"
|
version = "1.2.0"
|
||||||
authors = ["Yamato Security @SecurityYamato"]
|
authors = ["Yamato Security @SecurityYamato"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|||||||
15
config/output_tag.txt
Normal file
15
config/output_tag.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
tag_full_str,tag_output_str
|
||||||
|
attack.reconnaissance,Recon
|
||||||
|
attack.resource_development,ResDev
|
||||||
|
attack.initial_access,InitAccess
|
||||||
|
attack.execution,Exec
|
||||||
|
attack.persistence,Persis
|
||||||
|
attack.privilege_escalation,PrivEsc
|
||||||
|
attack.defense_evasion,Evas
|
||||||
|
attack.credential_access,CredAccess
|
||||||
|
attack.discovery,Disc
|
||||||
|
attack.lateral_movement,LatMov
|
||||||
|
attack.collection,Collect
|
||||||
|
attack.command_and_control,C2
|
||||||
|
attack.exfiltration,Exfil
|
||||||
|
attack.impact,Impact
|
||||||
@@ -9,6 +9,7 @@ use crate::detections::print::MESSAGES;
|
|||||||
use crate::detections::print::PIVOT_KEYWORD_LIST_FLAG;
|
use crate::detections::print::PIVOT_KEYWORD_LIST_FLAG;
|
||||||
use crate::detections::print::QUIET_ERRORS_FLAG;
|
use crate::detections::print::QUIET_ERRORS_FLAG;
|
||||||
use crate::detections::print::STATISTICS_FLAG;
|
use crate::detections::print::STATISTICS_FLAG;
|
||||||
|
use crate::detections::print::TAGS_CONFIG;
|
||||||
use crate::detections::rule;
|
use crate::detections::rule;
|
||||||
use crate::detections::rule::AggResult;
|
use crate::detections::rule::AggResult;
|
||||||
use crate::detections::rule::RuleNode;
|
use crate::detections::rule::RuleNode;
|
||||||
@@ -200,7 +201,8 @@ impl Detection {
|
|||||||
.as_vec()
|
.as_vec()
|
||||||
.unwrap_or(&Vec::default())
|
.unwrap_or(&Vec::default())
|
||||||
.iter()
|
.iter()
|
||||||
.map(|info| info.as_str().unwrap_or("").replace("attack.", ""))
|
.filter_map(|info| TAGS_CONFIG.get(info.as_str().unwrap_or(&String::default())))
|
||||||
|
.map(|str| str.to_owned())
|
||||||
.collect();
|
.collect();
|
||||||
MESSAGES.lock().unwrap().insert(
|
MESSAGES.lock().unwrap().insert(
|
||||||
&record_info.record,
|
&record_info.record,
|
||||||
@@ -218,7 +220,7 @@ impl Detection {
|
|||||||
.unwrap_or_else(|| "-".to_owned()),
|
.unwrap_or_else(|| "-".to_owned()),
|
||||||
alert: rule.yaml["title"].as_str().unwrap_or("").to_string(),
|
alert: rule.yaml["title"].as_str().unwrap_or("").to_string(),
|
||||||
detail: String::default(),
|
detail: String::default(),
|
||||||
tag_info: tag_info.join(" : "),
|
tag_info: tag_info.join(" | "),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ lazy_static! {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.args
|
.args
|
||||||
.is_present("statistics");
|
.is_present("statistics");
|
||||||
|
pub static ref TAGS_CONFIG: HashMap<String, String> =
|
||||||
|
Message::create_tags_config("config/output_tag.txt");
|
||||||
pub static ref PIVOT_KEYWORD_LIST_FLAG: bool = configs::CONFIG
|
pub static ref PIVOT_KEYWORD_LIST_FLAG: bool = configs::CONFIG
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -72,6 +74,33 @@ impl Message {
|
|||||||
Message { map: messages }
|
Message { map: messages }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ファイルパスで記載されたtagでのフル名、表示の際に置き換えられる文字列のHashMapを作成する関数。tagではこのHashMapのキーに対応しない出力は出力しないものとする
|
||||||
|
/// ex. attack.impact,Impact
|
||||||
|
pub fn create_tags_config(path: &str) -> HashMap<String, String> {
|
||||||
|
let read_result = utils::read_csv(path);
|
||||||
|
if read_result.is_err() {
|
||||||
|
AlertMessage::alert(
|
||||||
|
&mut BufWriter::new(std::io::stderr().lock()),
|
||||||
|
read_result.as_ref().unwrap_err(),
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
return HashMap::default();
|
||||||
|
}
|
||||||
|
let mut ret: HashMap<String, String> = HashMap::new();
|
||||||
|
read_result.unwrap().into_iter().for_each(|line| {
|
||||||
|
if line.len() != 2 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let empty = &"".to_string();
|
||||||
|
let tag_full_str = line.get(0).unwrap_or(empty).trim();
|
||||||
|
let tag_replace_str = line.get(1).unwrap_or(empty).trim();
|
||||||
|
|
||||||
|
ret.insert(tag_full_str.to_owned(), tag_replace_str.to_owned());
|
||||||
|
});
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
/// メッセージの設定を行う関数。aggcondition対応のためrecordではなく出力をする対象時間がDatetime形式での入力としている
|
/// メッセージの設定を行う関数。aggcondition対応のためrecordではなく出力をする対象時間がDatetime形式での入力としている
|
||||||
pub fn insert_message(&mut self, detect_info: DetectInfo, event_time: DateTime<Utc>) {
|
pub fn insert_message(&mut self, detect_info: DetectInfo, event_time: DateTime<Utc>) {
|
||||||
if let Some(v) = self.map.get_mut(&event_time) {
|
if let Some(v) = self.map.get_mut(&event_time) {
|
||||||
@@ -222,6 +251,7 @@ impl AlertMessage {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use crate::detections::print::DetectInfo;
|
use crate::detections::print::DetectInfo;
|
||||||
use crate::detections::print::{AlertMessage, Message};
|
use crate::detections::print::{AlertMessage, Message};
|
||||||
|
use hashbrown::HashMap;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::io::BufWriter;
|
use std::io::BufWriter;
|
||||||
|
|
||||||
@@ -466,4 +496,18 @@ mod tests {
|
|||||||
expected,
|
expected,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
/// output_tag.txtの読み込みテスト
|
||||||
|
fn test_load_output_tag() {
|
||||||
|
let actual = Message::create_tags_config("test_files/config/output_tag.txt");
|
||||||
|
let expected: HashMap<String, String> = HashMap::from([
|
||||||
|
("attack.impact".to_string(), "Impact".to_string()),
|
||||||
|
("xxx".to_string(), "yyy".to_string()),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_eq!(actual.len(), expected.len());
|
||||||
|
for (k, v) in expected.iter() {
|
||||||
|
assert!(actual.get(k).unwrap_or(&String::default()) == v);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
test_files/config/output_tag.txt
Normal file
3
test_files/config/output_tag.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
tag_full_str,tag_output_str
|
||||||
|
attack.impact,Impact
|
||||||
|
xxx,yyy
|
||||||
Reference in New Issue
Block a user