diff --git a/snaffler_parser/Cargo.lock b/snaffler_parser/Cargo.lock new file mode 100644 index 0000000..2bb61d2 --- /dev/null +++ b/snaffler_parser/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "snaffler_parser" +version = "0.1.0" diff --git a/snaffler_parser/Cargo.toml b/snaffler_parser/Cargo.toml new file mode 100644 index 0000000..a736aca --- /dev/null +++ b/snaffler_parser/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "snaffler_parser" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/snaffler_parser/src/main.rs b/snaffler_parser/src/main.rs new file mode 100644 index 0000000..d22e782 --- /dev/null +++ b/snaffler_parser/src/main.rs @@ -0,0 +1,166 @@ +use std::fs; +use std::env::args; +use std::io::Write; + +fn parse(snaf: String, looking: String, severity: String, outfile: String){ + println!("Srarting Parser function..."); + let mut search = String::new(); + let mut sev: String = String::new(); + let mut sever_vector:Vec<&str> = Vec::new(); + let mut sev_vec = true; + if severity.contains("black"){ + sev_vec = false; + } + let mut outlines = Vec::new(); + match looking.as_str(){ + "file" => search = "[File]".to_owned(), + "info" => search = "[Info]".to_owned(), + "share" => search = "[Share]".to_owned(), + _ => println!("unknonw type, using raw string search") + } + + match severity.as_str(){ + "all" => sev = "{Green}|{Yellow}|{Red}|{Black}".to_owned(), + "green" => sev = "{Green}|{Yellow}|{Red}|{Black}".to_owned(), + "yellow" => sev = "{Yellow}|{Red}|{Black}".to_owned(), + "red" => sev = "{Red}|{Black}".to_owned(), + "black" => sev = "{Black}".to_owned(), + "share" => sev = "{Green}|{Yellow}|{Red}|{Black}".to_owned(), + _ => println!("Unknown severity, defaulting to all") + } + + println!("Searching for {} with severity {}", search, sev); + + if search.len()<=1{ + search = looking.to_owned() + } + + if sev.len()<1{ + sev = "{Green}|{Yellow}|{Red}|{Black}".to_owned() + } + + if sev_vec{ + println!("separating severity into vector..."); + sever_vector = sev.split("|").collect(); + println!("looking for the following severities..."); + for i in &sever_vector{ + println!("{}", i); + } + } + + for line in snaf.split("\n").collect::>(){ + if sev_vec{ + if line.contains(search.as_str()){ + for sever in &sever_vector{ + if line.contains(sever){ + outlines.push(line.to_owned()); + } + } + } + } + else{ + if line.contains(search.as_str()){ + if line.contains(&sev){ + outlines.push(line.to_owned()); + } + } + } + } + let mut output = fs::File::create(outfile).expect("error creating output file"); + for line in outlines{ + println!("{}", line); + let outline = format!("{}\n", line); + output.write_all(outline.as_bytes()).expect("error writing outputline"); + } + } + + +fn admin(snaf: String, outfile: String){ + let mut outlines = Vec::new(); + for line in snaf.split("\n").collect::>(){ + if line.contains("[Share]"){ + if line.contains("ADMIN$") || line.contains("C$"){ + outlines.push(line); + } + } + } + let mut output = fs::File::create(outfile).expect("error creating output file"); + for line in outlines{ + println!("{}", line); + let outline = format!("{}\n", line); + output.write_all(outline.as_bytes()).expect("error writing outputline"); + } +} + +fn default_run(snaf: String, outfile: String){ + fs::create_dir_all(&outfile).expect("error creating output directory"); + let file_output = format!("{}/snaf_files.txt", &outfile); + let share_output = format!("{}/snaf_shares.txt", &outfile); + let admin_output = format!("{}/admin_shares.txt", &outfile); + let red_output = format!("{}/snaf_red+.txt", &outfile); + parse(snaf.clone(), "share".to_owned(), "all".to_owned(), share_output); + parse(snaf.clone(), "file".to_owned(), "all".to_owned(), file_output); + parse(snaf.clone(), "file".to_owned(), "red".to_owned(), red_output); + admin(snaf.clone(), admin_output); +} + + +fn main() { + let args: Vec = args().collect(); + print!(" + _______ _ _______ _______ _______ _______ _______ _______ _______ _______ + ( ____ \\( ( /|( ___ )( ____ \\ ( ____ )( ___ )( ____ )( ____ \\( ____ \\( ____ ) + | ( \\/| \\ ( || ( ) || ( \\/ | ( )|| ( ) || ( )|| ( \\/| ( \\/| ( )| + | (_____ | \\ | || (___) || (__ | (____)|| (___) || (____)|| (_____ | (__ | (____)| + (_____ )| (\\ \\) || ___ || __) | _____)| ___ || __)(_____ )| __) | __) + ) || | \\ || ( ) || ( | ( | ( ) || (\\ ( ) || ( | (\\ ( + /\\____) || ) \\ || ) ( || ) | ) | ) ( || ) \\ \\__/\\____) || (____/\\| ) \\ \\__ + \\_______)|/ )_)|/ \\||/ |/ |/ \\||/ \\__/\\_______)(_______/|/ \\__/ + "); + let usage = " +snafparse /path/to/snaffler/output type severity /path/to/save/file + +TYPES: + file + info + share + +SEVERITIES: + all + green + yellow + red + black + +SPECIAL COMMANDS: + FIND ADMIN SHARES + snafparse ./snafler.log admin shares ./parsed_snaf.txt + RUN ALL FINDERS AND SAVE TO DEFAULT FILE LOCATIONS (specified directory with files named for searches) + snafparse ./snafler.log default run ./snaf_parse_output +EXAMPLES: +FIND ALL FILES + snafparse ./snafler.log file all ./parsed_snaf.txt + + +FIND ALL SHARES + snafpar ./snafler.log share all ./parsed_snaf.txt + + +FIND ALL FILES RED SEVERITY OR HIGHER + snafparse ./snafler.log file red ./parsed_snaf.txt + +"; + if args.len() != 5{ + print!("{}",usage); + } + else{ + let snaf_string = fs::read_to_string(&args[1]).expect("error opening snaffler output file"); + match &args[2].as_str(){ + &"admin" => admin(snaf_string, args[4].to_owned()), + &"default" => default_run(snaf_string, args[4].to_owned()), + _ => parse(snaf_string, args[2].to_owned(), args[3].to_owned(), args[4].to_owned()) + } + println!("\n\n\n\n\n"); + println!("done file or files have been saved at {}", &args[4]); + } +}