Feature/verbose output rule and file#188 (#219)
* added verbose output rule and evtx path #188 * fixed typo * changed yaml read error to warn message #188 - added AlertMessage::warn - yaml read error changed from error to warn
This commit is contained in:
@@ -51,6 +51,7 @@ fn build_app<'a>() -> ArgMatches<'a> {
|
|||||||
--csv-timeline=[CSV_TIMELINE] 'Csv output timeline'
|
--csv-timeline=[CSV_TIMELINE] 'Csv output timeline'
|
||||||
--rfc-2822 'Output date and time in RFC 2822 format. Example: Mon, 07 Aug 2006 12:34:56 -0600'
|
--rfc-2822 'Output date and time in RFC 2822 format. Example: Mon, 07 Aug 2006 12:34:56 -0600'
|
||||||
--rfc-3339 'Output date and time in RFC 3339 format. Example: 2006-08-07T12:34:56.485214 -06:00'
|
--rfc-3339 'Output date and time in RFC 3339 format. Example: 2006-08-07T12:34:56.485214 -06:00'
|
||||||
|
--verbose 'Output check information to target event file path and rule file.'
|
||||||
-l --lang=[LANG] 'Output language'
|
-l --lang=[LANG] 'Output language'
|
||||||
-L --level=[LEVEL] 'Specified execute rule level(default: INFO)'
|
-L --level=[LEVEL] 'Specified execute rule level(default: INFO)'
|
||||||
-u --utc 'Output time in UTC format(default: local time)'
|
-u --utc 'Output time in UTC format(default: local time)'
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ impl Detection {
|
|||||||
pub fn parse_rule_files(level: String) -> Vec<RuleNode> {
|
pub fn parse_rule_files(level: String) -> Vec<RuleNode> {
|
||||||
// ルールファイルのパースを実行
|
// ルールファイルのパースを実行
|
||||||
let mut rulefile_loader = ParseYaml::new();
|
let mut rulefile_loader = ParseYaml::new();
|
||||||
let resutl_readdir = rulefile_loader.read_dir(DIRPATH_RULES, &level);
|
let result_readdir = rulefile_loader.read_dir(DIRPATH_RULES, &level);
|
||||||
if resutl_readdir.is_err() {
|
if result_readdir.is_err() {
|
||||||
AlertMessage::alert(
|
AlertMessage::alert(
|
||||||
&mut std::io::stderr().lock(),
|
&mut std::io::stderr().lock(),
|
||||||
format!("{}", resutl_readdir.unwrap_err()),
|
format!("{}", result_readdir.unwrap_err()),
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
return vec![];
|
return vec![];
|
||||||
@@ -69,10 +69,10 @@ impl Detection {
|
|||||||
err_msgs_result.err().iter().for_each(|err_msgs| {
|
err_msgs_result.err().iter().for_each(|err_msgs| {
|
||||||
let errmsg_body =
|
let errmsg_body =
|
||||||
format!("Failed to parse Rule file. (FilePath : {})", rule.rulepath);
|
format!("Failed to parse Rule file. (FilePath : {})", rule.rulepath);
|
||||||
AlertMessage::alert(&mut std::io::stderr().lock(), errmsg_body).ok();
|
AlertMessage::warn(&mut std::io::stdout().lock(), errmsg_body).ok();
|
||||||
|
|
||||||
err_msgs.iter().for_each(|err_msg| {
|
err_msgs.iter().for_each(|err_msg| {
|
||||||
AlertMessage::alert(&mut std::io::stderr().lock(), err_msg.to_string()).ok();
|
AlertMessage::warn(&mut std::io::stdout().lock(), err_msg.to_string()).ok();
|
||||||
});
|
});
|
||||||
println!(""); // 一行開けるためのprintln
|
println!(""); // 一行開けるためのprintln
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -193,6 +193,9 @@ impl AlertMessage {
|
|||||||
pub fn alert<W: Write>(w: &mut W, contents: String) -> io::Result<()> {
|
pub fn alert<W: Write>(w: &mut W, contents: String) -> io::Result<()> {
|
||||||
writeln!(w, "[ERROR] {}", contents)
|
writeln!(w, "[ERROR] {}", contents)
|
||||||
}
|
}
|
||||||
|
pub fn warn<W: Write>(w: &mut W, contents: String) -> io::Result<()> {
|
||||||
|
writeln!(w, "[WARN] {}", contents)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -315,4 +318,12 @@ mod tests {
|
|||||||
let mut stdout = stdout.lock();
|
let mut stdout = stdout.lock();
|
||||||
AlertMessage::alert(&mut stdout, input.to_string()).expect("[ERROR] TEST!");
|
AlertMessage::alert(&mut stdout, input.to_string()).expect("[ERROR] TEST!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_warn_message() {
|
||||||
|
let input = "TESTWarn!";
|
||||||
|
let stdout = std::io::stdout();
|
||||||
|
let mut stdout = stdout.lock();
|
||||||
|
AlertMessage::alert(&mut stdout, input.to_string()).expect("[WARN] TESTWarn!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,9 @@ fn analysis_files(evtx_files: Vec<PathBuf>) {
|
|||||||
let rule_files = detection::Detection::parse_rule_files(level);
|
let rule_files = detection::Detection::parse_rule_files(level);
|
||||||
let mut detection = detection::Detection::new(rule_files);
|
let mut detection = detection::Detection::new(rule_files);
|
||||||
for evtx_file in evtx_files {
|
for evtx_file in evtx_files {
|
||||||
|
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||||
|
println!("check target evtx FilePath: {:?}", &evtx_file);
|
||||||
|
}
|
||||||
detection = analysis_file(evtx_file, detection);
|
detection = analysis_file(evtx_file, detection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/yaml.rs
12
src/yaml.rs
@@ -56,8 +56,8 @@ impl ParseYaml {
|
|||||||
// 個別のファイルの読み込みは即終了としない。
|
// 個別のファイルの読み込みは即終了としない。
|
||||||
let read_content = self.read_file(path);
|
let read_content = self.read_file(path);
|
||||||
if read_content.is_err() {
|
if read_content.is_err() {
|
||||||
AlertMessage::alert(
|
AlertMessage::warn(
|
||||||
&mut std::io::stderr().lock(),
|
&mut std::io::stdout().lock(),
|
||||||
format!(
|
format!(
|
||||||
"fail to read file: {}\n{} ",
|
"fail to read file: {}\n{} ",
|
||||||
entry.path().display(),
|
entry.path().display(),
|
||||||
@@ -70,8 +70,8 @@ impl ParseYaml {
|
|||||||
// ここも個別のファイルの読み込みは即終了としない。
|
// ここも個別のファイルの読み込みは即終了としない。
|
||||||
let yaml_contents = YamlLoader::load_from_str(&read_content.unwrap());
|
let yaml_contents = YamlLoader::load_from_str(&read_content.unwrap());
|
||||||
if yaml_contents.is_err() {
|
if yaml_contents.is_err() {
|
||||||
AlertMessage::alert(
|
AlertMessage::warn(
|
||||||
&mut std::io::stderr().lock(),
|
&mut std::io::stdout().lock(),
|
||||||
format!(
|
format!(
|
||||||
"fail to parse as yaml: {}\n{} ",
|
"fail to parse as yaml: {}\n{} ",
|
||||||
entry.path().display(),
|
entry.path().display(),
|
||||||
@@ -96,7 +96,9 @@ impl ParseYaml {
|
|||||||
if yaml_doc["ignore"].as_bool().unwrap_or(false) {
|
if yaml_doc["ignore"].as_bool().unwrap_or(false) {
|
||||||
return Option::None;
|
return Option::None;
|
||||||
}
|
}
|
||||||
|
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||||
|
println!("Loaded yml FilePath: {}", filepath);
|
||||||
|
}
|
||||||
// 指定されたレベルより低いルールは無視する
|
// 指定されたレベルより低いルールは無視する
|
||||||
let doc_level = &yaml_doc["level"]
|
let doc_level = &yaml_doc["level"]
|
||||||
.as_str()
|
.as_str()
|
||||||
|
|||||||
Reference in New Issue
Block a user