diff --git a/Cargo.lock b/Cargo.lock index 8496feb..b7983e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -257,7 +257,7 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "snaferrous" -version = "0.1.0" +version = "1.2.0" dependencies = [ "clap", "colored", diff --git a/Cargo.toml b/Cargo.toml index a5a0f11..4136b6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "snaferrous" -version = "0.1.0" +version = "1.2.0" edition = "2024" [dependencies] diff --git a/README.md b/README.md index 8729411..d8bc7ec 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,12 @@ Options: -t, --targets specific targets. should be comma separated. + -f, --filter_targets specific targets that should be ingored. Comma separated. + + -l, --local scan the current hot's file system (defaults to false) + + -d --disable_network disable network file discovery + -v, --verbose echo all found files to the console, regardless of keyword matching. (all files will still be saved to the log file) -h, --help Print help (see more with '--help') diff --git a/src/main.rs b/src/main.rs index 08911b7..10d047d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,8 +42,17 @@ struct Args{ #[arg(short, long, help = "specific targets. should be comma separated.")] targets: Option, + #[arg(short, long, help = "specific targets that should be ignored. comma separated.")] + filter_targets: Option, + #[arg(short, long, help = "echo all found files to the console, regardless of keyword matching. (all files will still be saved to the log file)")] verbose: bool, + + #[arg(short, long, help = "scan only the current host's files")] + local: bool, + + #[arg(short, long, help = "disable network discovery")] + diable_network: bool } #[derive(Clone)] @@ -151,6 +160,8 @@ async fn task_handler(id: usize, current_task: FinderTask, tx: Sender){ "it", "identified", "username", + "admin", + "administrator", ]; let mut file_content = String::new(); for extension in &files_to_read{ @@ -273,6 +284,11 @@ print!{ let mut threads = 10; let mut save = false; let mut computers = Vec::new(); + let mut filter_computers = Vec::new(); + let mut network = true; + let file_filter = vec![ + String::from("ADMIN$") + ]; if args.outfile.is_some(){ outfile = args.outfile.unwrap(); save = true; @@ -280,59 +296,86 @@ print!{ if args.threads.is_some(){ threads = args.threads.unwrap(); } + if args.diable_network{ + network = false; + } if args.targets.is_some(){ println!("gathering the targets you gave me."); let targets = args.targets.unwrap(); if targets.contains(","){ let split_targets: Vec<&str> = targets.split(",").collect(); for target in split_targets{ - computers.push(target.to_string()); + computers.push(target.trim().to_lowercase()); } } else{ computers.push(targets); } } - else{ - println!("no targets given, proceeding with domain computer enumeration..."); - println!("finding computers..."); - let command_string = String::from("net group \"domain computers\" /domain"); - let mut temp_file = fs::File::create("./temp.bat").unwrap(); - write!(temp_file, "{}", command_string).unwrap(); - let computer_res = Command::new(".\\\\temp.bat").output(); - let mut error_string = String::new(); - let mut success_string = String::new(); - fs::remove_file("./temp.bat").unwrap(); - if computer_res.is_ok(){ - let output = computer_res.unwrap(); - if output.stdout.len() > 0{ - success_string = String::from_utf8_lossy(&output.stdout).to_string(); + if args.filter_targets.is_some(){ + println!("gathering the filter you specified!"); + let given_filter = args.filter_targets.unwrap(); + let filters: Vec<&str> = given_filter.split(",").collect(); + for filter in filters{ + filter_computers.push(filter.trim().to_lowercase()); + } + } + let hostname_res = Command::new("hostname").output(); + if hostname_res.is_ok(){ + let hostname_output = hostname_res.unwrap(); + if hostname_output.stdout.len() > 0{ + let hostname_string = String::from_utf8_lossy(&hostname_output.stdout).to_string(); + if args.local{ + computers.push(hostname_string.trim().to_lowercase()); } - else if output.stderr.len() > 0{ - error_string = String::from_utf8_lossy(&output.stderr).to_string(); + else{ + filter_computers.push(hostname_string.trim().to_lowercase()); } } - else{ - error_string = computer_res.err().unwrap().to_string(); - } - if error_string.len() > 0{ - eprintln!("{}", "error getting computers!".red()); - eprintln!("{}", error_string.red()); - exit(1); - } - if success_string.len() > 0{ - for line in success_string.lines(){ - if line.contains("$"){ - let words:Vec<&str> = line.split_whitespace().collect(); - for word in words{ - let mut computer_name = word.to_string(); - computer_name.pop(); - computers.push(computer_name); + if network{ + println!("no targets given, proceeding with domain computer enumeration..."); + println!("finding computers..."); + let command_string = String::from("net group \"domain computers\" /domain"); + let mut temp_file = fs::File::create("./temp.bat").unwrap(); + write!(temp_file, "{}", command_string).unwrap(); + let computer_res = Command::new(".\\\\temp.bat").output(); + let mut error_string = String::new(); + let mut success_string = String::new(); + fs::remove_file("./temp.bat").unwrap(); + if computer_res.is_ok(){ + let output = computer_res.unwrap(); + if output.stdout.len() > 0{ + success_string = String::from_utf8_lossy(&output.stdout).to_string(); + } + else if output.stderr.len() > 0{ + error_string = String::from_utf8_lossy(&output.stderr).to_string(); + } + } + else{ + error_string = computer_res.err().unwrap().to_string(); + } + if error_string.len() > 0{ + eprintln!("{}", "error getting computers!".red()); + eprintln!("{}", error_string.red()); + exit(1); + } + if success_string.len() > 0{ + for line in success_string.lines(){ + if line.contains("$"){ + let words:Vec<&str> = line.split_whitespace().collect(); + for word in words{ + let mut computer_name = word.to_string(); + computer_name.pop(); + computers.push(computer_name.trim().to_lowercase()); + } } } } } } + if filter_computers.len() > 0{ + computers.retain(|x| !filter_computers.iter().any(|y| y==x)); + } let mut tasks = Vec::new(); let mut id_counter = 0; for computer in &computers{ @@ -423,9 +466,11 @@ print!{ } } } - let new_task = FinderTask{id: id_counter, tasktype: TaskType::File, target: finding.path}; - tasks.push(new_task); - id_counter += 1; + if !file_filter.contains(&finding.path){ + let new_task = FinderTask{id: id_counter, tasktype: TaskType::File, target: finding.path}; + tasks.push(new_task); + id_counter += 1; + } } TaskType::File => { let new_task = FinderTask{id: id_counter, tasktype: TaskType::Info, target: finding.path};