changed way of getting arg due to clap derive
This commit is contained in:
@@ -63,7 +63,7 @@ lazy_static! {
|
||||
pub fn set_output_color() -> HashMap<String, Color> {
|
||||
let read_result = utils::read_csv("config/level_color.txt");
|
||||
let mut color_map: HashMap<String, Color> = HashMap::new();
|
||||
if configs::CONFIG.read().unwrap().args.is_present("no-color") {
|
||||
if configs::CONFIG.read().unwrap().args.no_color {
|
||||
return color_map;
|
||||
}
|
||||
if read_result.is_err() {
|
||||
@@ -166,7 +166,7 @@ pub fn after_fact(all_record_cnt: usize) {
|
||||
|
||||
let mut displayflag = false;
|
||||
let mut target: Box<dyn io::Write> =
|
||||
if let Some(csv_path) = configs::CONFIG.read().unwrap().args.value_of("output") {
|
||||
if let Some(csv_path) = &configs::CONFIG.read().unwrap().args.output {
|
||||
// output to file
|
||||
match File::create(csv_path) {
|
||||
Ok(file) => Box::new(BufWriter::new(file)),
|
||||
@@ -369,12 +369,7 @@ fn emit_csv<W: std::io::Write>(
|
||||
};
|
||||
println!();
|
||||
|
||||
if configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("visualize-timeline")
|
||||
{
|
||||
if configs::CONFIG.read().unwrap().args.visualize_timeline {
|
||||
_print_timeline_hist(timestamps, terminal_width, 3);
|
||||
println!();
|
||||
}
|
||||
@@ -439,7 +434,7 @@ fn _get_serialized_disp_output(dispformat: Option<DisplayFormat>) -> String {
|
||||
if !*IS_HIDE_RECORD_ID {
|
||||
titles.insert(5, "RecordID");
|
||||
}
|
||||
if configs::CONFIG.read().unwrap().args.is_present("full-data") {
|
||||
if configs::CONFIG.read().unwrap().args.full_data {
|
||||
titles.push("RecordInformation");
|
||||
}
|
||||
return format!("{}\n", titles.join("|"));
|
||||
@@ -598,7 +593,7 @@ fn _print_detection_summary_by_computer(
|
||||
}
|
||||
|
||||
fn format_time(time: &DateTime<Utc>, date_only: bool) -> String {
|
||||
if configs::CONFIG.read().unwrap().args.is_present("utc") {
|
||||
if configs::CONFIG.read().unwrap().args.utc {
|
||||
format_rfc(time, date_only)
|
||||
} else {
|
||||
format_rfc(&time.with_timezone(&Local), date_only)
|
||||
@@ -607,7 +602,7 @@ fn format_time(time: &DateTime<Utc>, date_only: bool) -> String {
|
||||
|
||||
/// get timestamp to input datetime.
|
||||
fn _get_timestamp(time: &DateTime<Utc>) -> i64 {
|
||||
if configs::CONFIG.read().unwrap().args.is_present("utc") {
|
||||
if configs::CONFIG.read().unwrap().args.utc {
|
||||
time.timestamp()
|
||||
} else {
|
||||
let offset_sec = Local.timestamp(0, 0).offset().local_minus_utc();
|
||||
@@ -621,31 +616,31 @@ where
|
||||
Tz::Offset: std::fmt::Display,
|
||||
{
|
||||
let time_args = &configs::CONFIG.read().unwrap().args;
|
||||
if time_args.is_present("rfc-2822") {
|
||||
if time_args.rfc_2822 {
|
||||
if date_only {
|
||||
time.format("%a, %e %b %Y").to_string()
|
||||
} else {
|
||||
time.format("%a, %e %b %Y %H:%M:%S %:z").to_string()
|
||||
}
|
||||
} else if time_args.is_present("rfc-3339") {
|
||||
} else if time_args.rfc_3339 {
|
||||
if date_only {
|
||||
time.format("%Y-%m-%d").to_string()
|
||||
} else {
|
||||
time.format("%Y-%m-%d %H:%M:%S%.6f%:z").to_string()
|
||||
}
|
||||
} else if time_args.is_present("us-time") {
|
||||
} else if time_args.us_time {
|
||||
if date_only {
|
||||
time.format("%m-%d-%Y").to_string()
|
||||
} else {
|
||||
time.format("%m-%d-%Y %I:%M:%S%.3f %p %:z").to_string()
|
||||
}
|
||||
} else if time_args.is_present("us-military-time") {
|
||||
} else if time_args.us_military_time {
|
||||
if date_only {
|
||||
time.format("%m-%d-%Y").to_string()
|
||||
} else {
|
||||
time.format("%m-%d-%Y %H:%M:%S%.3f %:z").to_string()
|
||||
}
|
||||
} else if time_args.is_present("european-time") {
|
||||
} else if time_args.european_time {
|
||||
if date_only {
|
||||
time.format("%d-%m-%Y").to_string()
|
||||
} else {
|
||||
|
||||
@@ -293,10 +293,9 @@ impl Default for TargetEventTime {
|
||||
impl TargetEventTime {
|
||||
pub fn new() -> Self {
|
||||
let mut parse_success_flag = true;
|
||||
let start_time =
|
||||
if let Some(s_time) = CONFIG.read().unwrap().args.value_of("start-timeline") {
|
||||
match DateTime::parse_from_str(s_time, "%Y-%m-%d %H:%M:%S %z") // 2014-11-28 21:00:09 +09:00
|
||||
.or_else(|_| DateTime::parse_from_str(s_time, "%Y/%m/%d %H:%M:%S %z")) // 2014/11/28 21:00:09 +09:00
|
||||
let start_time = if let Some(s_time) = &CONFIG.read().unwrap().args.start_timeline {
|
||||
match DateTime::parse_from_str(&s_time, "%Y-%m-%d %H:%M:%S %z") // 2014-11-28 21:00:09 +09:00
|
||||
.or_else(|_| DateTime::parse_from_str(&s_time, "%Y/%m/%d %H:%M:%S %z")) // 2014/11/28 21:00:09 +09:00
|
||||
{
|
||||
Ok(dt) => Some(dt.with_timezone(&Utc)),
|
||||
Err(_) => {
|
||||
@@ -308,10 +307,10 @@ impl TargetEventTime {
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let end_time = if let Some(e_time) = CONFIG.read().unwrap().args.value_of("end-timeline") {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let end_time = if let Some(e_time) = &CONFIG.read().unwrap().args.end_timeline {
|
||||
match DateTime::parse_from_str(e_time, "%Y-%m-%d %H:%M:%S %z") // 2014-11-28 21:00:09 +09:00
|
||||
.or_else(|_| DateTime::parse_from_str(e_time, "%Y/%m/%d %H:%M:%S %z")) // 2014/11/28 21:00:09 +09:00
|
||||
{
|
||||
|
||||
@@ -6,10 +6,10 @@ use crate::detections::print::AlertMessage;
|
||||
use crate::detections::print::DetectInfo;
|
||||
use crate::detections::print::ERROR_LOG_STACK;
|
||||
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::{CH_CONFIG, IS_HIDE_RECORD_ID, TAGS_CONFIG};
|
||||
use crate::detections::print::{
|
||||
LOGONSUMMARY_FLAG, PIVOT_KEYWORD_LIST_FLAG, QUIET_ERRORS_FLAG, STATISTICS_FLAG,
|
||||
};
|
||||
use crate::detections::rule;
|
||||
use crate::detections::rule::AggResult;
|
||||
use crate::detections::rule::RuleNode;
|
||||
@@ -20,11 +20,10 @@ use hashbrown;
|
||||
use hashbrown::HashMap;
|
||||
use serde_json::Value;
|
||||
use std::fmt::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tokio::{runtime::Runtime, spawn, task::JoinHandle};
|
||||
|
||||
const DIRPATH_RULES: &str = "rules";
|
||||
|
||||
// イベントファイルの1レコード分の情報を保持する構造体
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EvtxRecordInfo {
|
||||
@@ -58,16 +57,15 @@ impl Detection {
|
||||
// ルールファイルをパースします。
|
||||
pub fn parse_rule_files(
|
||||
level: String,
|
||||
rulespath: Option<&str>,
|
||||
rulespath: &PathBuf,
|
||||
exclude_ids: &filter::RuleExclude,
|
||||
) -> Vec<RuleNode> {
|
||||
// ルールファイルのパースを実行
|
||||
let mut rulefile_loader = ParseYaml::new();
|
||||
let result_readdir =
|
||||
rulefile_loader.read_dir(rulespath.unwrap_or(DIRPATH_RULES), &level, exclude_ids);
|
||||
let result_readdir = rulefile_loader.read_dir(rulespath.as_path(), &level, exclude_ids);
|
||||
if result_readdir.is_err() {
|
||||
let errmsg = format!("{}", result_readdir.unwrap_err());
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::alert(&errmsg).ok();
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -89,7 +87,7 @@ impl Detection {
|
||||
err_msgs_result.err().iter().for_each(|err_msgs| {
|
||||
let errmsg_body =
|
||||
format!("Failed to parse rule file. (FilePath : {})", rule.rulepath);
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::warn(&errmsg_body).ok();
|
||||
|
||||
err_msgs.iter().for_each(|err_msg| {
|
||||
@@ -120,12 +118,7 @@ impl Detection {
|
||||
.map(|rule_file_tuple| rule::create_rule(rule_file_tuple.0, rule_file_tuple.1))
|
||||
.filter_map(return_if_success)
|
||||
.collect();
|
||||
if !configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("logon-summary")
|
||||
{
|
||||
if !*LOGONSUMMARY_FLAG {
|
||||
let _ = &rulefile_loader
|
||||
.rule_load_cnt
|
||||
.insert(String::from("rule parsing error"), parseerror_count);
|
||||
@@ -276,7 +269,7 @@ impl Detection {
|
||||
.map(|str| str.to_owned())
|
||||
.collect();
|
||||
let output = Detection::create_count_output(rule, &agg_result);
|
||||
let rec_info = if configs::CONFIG.read().unwrap().args.is_present("full-data") {
|
||||
let rec_info = if configs::CONFIG.read().unwrap().args.full_data {
|
||||
Option::Some(String::default())
|
||||
} else {
|
||||
Option::None
|
||||
|
||||
@@ -48,42 +48,23 @@ lazy_static! {
|
||||
"./logs/errorlog-{}.log",
|
||||
Local::now().format("%Y%m%d_%H%M%S")
|
||||
);
|
||||
pub static ref QUIET_ERRORS_FLAG: bool = configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("quiet-errors");
|
||||
pub static ref QUIET_ERRORS_FLAG: bool = configs::CONFIG.read().unwrap().args.quiet_errors;
|
||||
pub static ref ERROR_LOG_STACK: Mutex<Vec<String>> = Mutex::new(Vec::new());
|
||||
pub static ref STATISTICS_FLAG: bool = configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("statistics");
|
||||
pub static ref LOGONSUMMARY_FLAG: bool = configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("logon-summary");
|
||||
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",
|
||||
true,
|
||||
configs::CONFIG.read().unwrap().args.is_present("all-tags")
|
||||
configs::CONFIG.read().unwrap().args.all_tags
|
||||
);
|
||||
pub static ref CH_CONFIG: HashMap<String, String> = Message::create_output_filter_config(
|
||||
"config/channel_abbreviations.txt",
|
||||
false,
|
||||
configs::CONFIG.read().unwrap().args.is_present("all-tags")
|
||||
configs::CONFIG.read().unwrap().args.all_tags
|
||||
);
|
||||
pub static ref PIVOT_KEYWORD_LIST_FLAG: bool = configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("pivot-keywords-list");
|
||||
pub static ref IS_HIDE_RECORD_ID: bool = configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("hide-record-id");
|
||||
pub static ref PIVOT_KEYWORD_LIST_FLAG: bool =
|
||||
configs::CONFIG.read().unwrap().args.pivot_keywords_list;
|
||||
pub static ref IS_HIDE_RECORD_ID: bool = configs::CONFIG.read().unwrap().args.hide_record_id;
|
||||
}
|
||||
|
||||
impl Default for Message {
|
||||
|
||||
@@ -86,7 +86,7 @@ fn get_alias_value_in_record(
|
||||
utils::get_event_value(&utils::get_event_id_key(), record).unwrap()
|
||||
),
|
||||
};
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::alert(&errmsg).ok();
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -188,7 +188,7 @@ impl TimeFrameInfo {
|
||||
tnum.retain(|c| c != 'd');
|
||||
} else {
|
||||
let errmsg = format!("Timeframe is invalid. Input value:{}", value);
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::alert(&errmsg).ok();
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -224,7 +224,7 @@ pub fn get_sec_timeframe(rule: &RuleNode) -> Option<i64> {
|
||||
}
|
||||
Err(err) => {
|
||||
let errmsg = format!("Timeframe number is invalid. timeframe. {}", err);
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::alert(&errmsg).ok();
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
|
||||
@@ -185,13 +185,8 @@ 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();
|
||||
conf.args
|
||||
.value_of("thread-number")
|
||||
.unwrap_or(def_thread_num_str.as_str())
|
||||
.parse::<usize>()
|
||||
.unwrap()
|
||||
conf.args.thread_number.unwrap_or(num_cpus::get())
|
||||
}
|
||||
|
||||
pub fn create_tokio_runtime() -> Runtime {
|
||||
@@ -228,7 +223,7 @@ pub fn create_rec_info(data: Value, path: String, keys: &[String]) -> EvtxRecord
|
||||
|
||||
// EvtxRecordInfoを作る
|
||||
let data_str = data.to_string();
|
||||
let rec_info = if configs::CONFIG.read().unwrap().args.is_present("full-data") {
|
||||
let rec_info = if configs::CONFIG.read().unwrap().args.full_data {
|
||||
Option::Some(create_recordinfos(&data))
|
||||
} else {
|
||||
Option::None
|
||||
@@ -279,7 +274,7 @@ fn create_recordinfos(record: &Value) -> String {
|
||||
.collect();
|
||||
|
||||
// 標準出力する時はセルがハイプ区切りになるので、パイプ区切りにしない
|
||||
if configs::CONFIG.read().unwrap().args.is_present("output") {
|
||||
if configs::CONFIG.read().unwrap().args.output.is_some() {
|
||||
summary.join(" | ")
|
||||
} else {
|
||||
summary.join(" ")
|
||||
|
||||
@@ -29,21 +29,28 @@ impl RuleExclude {
|
||||
pub fn exclude_ids() -> RuleExclude {
|
||||
let mut exclude_ids = RuleExclude::default();
|
||||
|
||||
if !configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("enable-noisy-rules")
|
||||
{
|
||||
if !configs::CONFIG.read().unwrap().args.enable_noisy_rules {
|
||||
exclude_ids.insert_ids(&format!(
|
||||
"{}/noisy_rules.txt",
|
||||
configs::CONFIG.read().unwrap().folder_path
|
||||
configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.config
|
||||
.as_path()
|
||||
.display()
|
||||
));
|
||||
};
|
||||
|
||||
exclude_ids.insert_ids(&format!(
|
||||
"{}/exclude_rules.txt",
|
||||
configs::CONFIG.read().unwrap().folder_path
|
||||
configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.config
|
||||
.as_path()
|
||||
.display()
|
||||
));
|
||||
|
||||
exclude_ids
|
||||
@@ -53,7 +60,7 @@ impl RuleExclude {
|
||||
fn insert_ids(&mut self, filename: &str) {
|
||||
let f = File::open(filename);
|
||||
if f.is_err() {
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::warn(&format!("{} does not exist", filename)).ok();
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
|
||||
99
src/main.rs
99
src/main.rs
@@ -89,18 +89,11 @@ impl App {
|
||||
// Show usage when no arguments.
|
||||
if std::env::args().len() == 1 {
|
||||
self.output_logo();
|
||||
println!();
|
||||
write_color_buffer(
|
||||
BufferWriter::stdout(ColorChoice::Always),
|
||||
None,
|
||||
&configs::CONFIG.read().unwrap().headless_help,
|
||||
)
|
||||
.ok();
|
||||
configs::CONFIG.write().unwrap().app.print_help().ok();
|
||||
println!();
|
||||
return;
|
||||
}
|
||||
|
||||
if !configs::CONFIG.read().unwrap().args.is_present("quiet") {
|
||||
if !configs::CONFIG.read().unwrap().args.quiet {
|
||||
self.output_logo();
|
||||
println!();
|
||||
self.output_eggs(&format!(
|
||||
@@ -119,12 +112,7 @@ impl App {
|
||||
return;
|
||||
}
|
||||
|
||||
if configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("update-rules")
|
||||
{
|
||||
if configs::CONFIG.read().unwrap().args.update_rules {
|
||||
match self.update_rules() {
|
||||
Ok(output) => {
|
||||
if output != "You currently have the latest rules." {
|
||||
@@ -152,10 +140,11 @@ impl App {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(csv_path) = configs::CONFIG.read().unwrap().args.value_of("output") {
|
||||
if let Some(csv_path) = &configs::CONFIG.read().unwrap().args.output {
|
||||
let pivot_key_unions = PIVOT_KEYWORD.read().unwrap();
|
||||
pivot_key_unions.iter().for_each(|(key, _)| {
|
||||
let keywords_file_name = csv_path.to_owned() + "-" + key + ".txt";
|
||||
let keywords_file_name =
|
||||
csv_path.as_path().display().to_string() + "-" + key + ".txt";
|
||||
if Path::new(&keywords_file_name).exists() {
|
||||
AlertMessage::alert(&format!(
|
||||
" The file {} already exists. Please specify a different filename.",
|
||||
@@ -164,10 +153,10 @@ impl App {
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
if Path::new(csv_path).exists() {
|
||||
if csv_path.exists() {
|
||||
AlertMessage::alert(&format!(
|
||||
" The file {} already exists. Please specify a different filename.",
|
||||
csv_path
|
||||
csv_path.as_os_str().to_str().unwrap()
|
||||
))
|
||||
.ok();
|
||||
return;
|
||||
@@ -197,20 +186,16 @@ impl App {
|
||||
.ok();
|
||||
println!();
|
||||
}
|
||||
if configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("live-analysis")
|
||||
{
|
||||
if configs::CONFIG.read().unwrap().args.live_analysis {
|
||||
let live_analysis_list = self.collect_liveanalysis_files();
|
||||
if live_analysis_list.is_none() {
|
||||
return;
|
||||
}
|
||||
self.analysis_files(live_analysis_list.unwrap(), &time_filter);
|
||||
} else if let Some(filepath) = configs::CONFIG.read().unwrap().args.value_of("filepath") {
|
||||
} else if let Some(filepath) = &configs::CONFIG.read().unwrap().args.filepath {
|
||||
if !filepath.ends_with(".evtx")
|
||||
|| Path::new(filepath)
|
||||
|| filepath
|
||||
.as_path()
|
||||
.file_stem()
|
||||
.unwrap_or_else(|| OsStr::new("."))
|
||||
.to_str()
|
||||
@@ -225,36 +210,27 @@ impl App {
|
||||
return;
|
||||
}
|
||||
self.analysis_files(vec![PathBuf::from(filepath)], &time_filter);
|
||||
} else if let Some(directory) = configs::CONFIG.read().unwrap().args.value_of("directory") {
|
||||
let evtx_files = self.collect_evtxfiles(directory);
|
||||
} else if let Some(directory) = &configs::CONFIG.read().unwrap().args.directory {
|
||||
let evtx_files = self.collect_evtxfiles(directory.as_os_str().to_str().unwrap());
|
||||
if evtx_files.is_empty() {
|
||||
AlertMessage::alert("No .evtx files were found.").ok();
|
||||
return;
|
||||
}
|
||||
self.analysis_files(evtx_files, &time_filter);
|
||||
} else if configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("contributors")
|
||||
{
|
||||
} else if configs::CONFIG.read().unwrap().args.contributors {
|
||||
self.print_contributors();
|
||||
return;
|
||||
} else if configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("level-tuning")
|
||||
&& std::env::args()
|
||||
.into_iter()
|
||||
.any(|arg| arg.contains("level-tuning"))
|
||||
} else if std::env::args()
|
||||
.into_iter()
|
||||
.any(|arg| arg.contains("level-tuning"))
|
||||
{
|
||||
let level_tuning_config_path = configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.value_of("level-tuning")
|
||||
.unwrap()
|
||||
.level_tuning
|
||||
.as_path()
|
||||
.display()
|
||||
.to_string();
|
||||
|
||||
if Path::new(&level_tuning_config_path).exists() {
|
||||
@@ -264,7 +240,9 @@ impl App {
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.value_of("rules")
|
||||
.rules
|
||||
.as_os_str()
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
) {
|
||||
AlertMessage::alert(&err).ok();
|
||||
@@ -322,10 +300,13 @@ impl App {
|
||||
};
|
||||
|
||||
//ファイル出力の場合
|
||||
if let Some(pivot_file) = configs::CONFIG.read().unwrap().args.value_of("output") {
|
||||
if let Some(pivot_file) = &configs::CONFIG.read().unwrap().args.output {
|
||||
pivot_key_unions.iter().for_each(|(key, pivot_keyword)| {
|
||||
let mut f = BufWriter::new(
|
||||
fs::File::create(pivot_file.to_owned() + "-" + key + ".txt").unwrap(),
|
||||
fs::File::create(
|
||||
pivot_file.as_path().display().to_string() + "-" + key + ".txt",
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
f.write_all(create_output(String::default(), key, pivot_keyword).as_bytes())
|
||||
.unwrap();
|
||||
@@ -335,7 +316,12 @@ impl App {
|
||||
"Pivot keyword results saved to the following files:\n".to_string();
|
||||
|
||||
pivot_key_unions.iter().for_each(|(key, _)| {
|
||||
writeln!(output, "{}", &(pivot_file.to_owned() + "-" + key + ".txt")).ok();
|
||||
writeln!(
|
||||
output,
|
||||
"{}",
|
||||
&(pivot_file.as_path().display().to_string() + "-" + key + ".txt")
|
||||
)
|
||||
.ok();
|
||||
});
|
||||
write_color_buffer(BufferWriter::stdout(ColorChoice::Always), None, &output).ok();
|
||||
} else {
|
||||
@@ -386,7 +372,7 @@ impl App {
|
||||
let entries = fs::read_dir(dirpath);
|
||||
if entries.is_err() {
|
||||
let errmsg = format!("{}", entries.unwrap_err());
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::alert(&errmsg).ok();
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -445,8 +431,7 @@ impl App {
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.value_of("min-level")
|
||||
.unwrap()
|
||||
.min_level
|
||||
.to_uppercase();
|
||||
write_color_buffer(
|
||||
BufferWriter::stdout(ColorChoice::Always),
|
||||
@@ -467,7 +452,7 @@ impl App {
|
||||
|
||||
let rule_files = detection::Detection::parse_rule_files(
|
||||
level,
|
||||
configs::CONFIG.read().unwrap().args.value_of("rules"),
|
||||
&configs::CONFIG.read().unwrap().args.rules,
|
||||
&filter::exclude_ids(),
|
||||
);
|
||||
|
||||
@@ -485,7 +470,7 @@ impl App {
|
||||
let mut detection = detection::Detection::new(rule_files);
|
||||
let mut total_records: usize = 0;
|
||||
for evtx_file in evtx_files {
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
println!("Checking target evtx FilePath: {:?}", &evtx_file);
|
||||
}
|
||||
let cnt_tmp: usize;
|
||||
@@ -493,7 +478,7 @@ impl App {
|
||||
total_records += cnt_tmp;
|
||||
pb.inc();
|
||||
}
|
||||
if configs::CONFIG.read().unwrap().args.is_present("output") {
|
||||
if configs::CONFIG.read().unwrap().args.output.is_some() {
|
||||
println!();
|
||||
println!();
|
||||
println!("Analysis finished. Please wait while the results are being saved.");
|
||||
@@ -539,7 +524,7 @@ impl App {
|
||||
evtx_filepath,
|
||||
record_result.unwrap_err()
|
||||
);
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::alert(&errmsg).ok();
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -669,7 +654,7 @@ impl App {
|
||||
fn output_logo(&self) {
|
||||
let fp = &"art/logo.txt".to_string();
|
||||
let content = fs::read_to_string(fp).unwrap_or_default();
|
||||
let output_color = if configs::CONFIG.read().unwrap().args.is_present("no-color") {
|
||||
let output_color = if configs::CONFIG.read().unwrap().args.no_color {
|
||||
None
|
||||
} else {
|
||||
Some(Color::Green)
|
||||
|
||||
19
src/yaml.rs
19
src/yaml.rs
@@ -68,7 +68,7 @@ impl ParseYaml {
|
||||
"fail to read metadata of file: {}",
|
||||
path.as_ref().to_path_buf().display(),
|
||||
);
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::alert(&errmsg)?;
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -100,7 +100,7 @@ impl ParseYaml {
|
||||
path.as_ref().to_path_buf().display(),
|
||||
read_content.unwrap_err()
|
||||
);
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::warn(&errmsg)?;
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -121,7 +121,7 @@ impl ParseYaml {
|
||||
path.as_ref().to_path_buf().display(),
|
||||
yaml_contents.unwrap_err()
|
||||
);
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::warn(&errmsg)?;
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -173,7 +173,7 @@ impl ParseYaml {
|
||||
entry.path().display(),
|
||||
read_content.unwrap_err()
|
||||
);
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::warn(&errmsg)?;
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -194,7 +194,7 @@ impl ParseYaml {
|
||||
entry.path().display(),
|
||||
yaml_contents.unwrap_err()
|
||||
);
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
AlertMessage::warn(&errmsg)?;
|
||||
}
|
||||
if !*QUIET_ERRORS_FLAG {
|
||||
@@ -256,7 +256,7 @@ impl ParseYaml {
|
||||
.or_insert(0);
|
||||
*status_cnt += 1;
|
||||
|
||||
if configs::CONFIG.read().unwrap().args.is_present("verbose") {
|
||||
if configs::CONFIG.read().unwrap().args.verbose {
|
||||
println!("Loaded yml file path: {}", filepath);
|
||||
}
|
||||
|
||||
@@ -272,12 +272,7 @@ impl ParseYaml {
|
||||
return Option::None;
|
||||
}
|
||||
|
||||
if !configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.is_present("enable-deprecated-rules")
|
||||
{
|
||||
if !configs::CONFIG.read().unwrap().args.enable_deprecated_rules {
|
||||
let rule_status = &yaml_doc["status"].as_str().unwrap_or_default();
|
||||
if *rule_status == "deprecated" {
|
||||
let entry = self
|
||||
|
||||
Reference in New Issue
Block a user