changed the parsing logic to use proper iteraters intead of for loops,

and refined the filters and keywords a bit.
This commit is contained in:
2026-07-17 17:14:37 -05:00
parent 256d6e68bc
commit 0ef453427b
+96 -37
View File
@@ -57,7 +57,7 @@ struct Args {
#[arg( #[arg(
long, long,
help = "specific folder paths that should be ignored. comma separated." help = "specific folder paths or file names that should be ignored. comma separated."
)] )]
filter_data: Option<String>, filter_data: Option<String>,
@@ -72,7 +72,7 @@ struct Args {
local: bool, local: bool,
#[arg(short, long, help = "disable network discovery")] #[arg(short, long, help = "disable network discovery")]
diable_network: bool, disable_network: bool,
} }
struct AppState { struct AppState {
@@ -136,37 +136,31 @@ impl FinderTask {
} }
} }
TaskType::File => { TaskType::File => {
let mut sent_lines = Vec::new(); walkdir::WalkDir::new(self.target.clone())
for entry_res in walkdir::WalkDir::new(self.target.clone()) { .into_iter()
if entry_res.is_ok() { .for_each(|e| {
let entry = entry_res.unwrap(); if let Ok(entry) = e {
if self
.filter
.iter()
.any(|f| !entry.path().to_string_lossy().contains(f))
{
let file_path = entry.into_path(); let file_path = entry.into_path();
if file_path.file_name().is_some() { let new_finding = Finding {
let file_path_string = file_path.display().to_string(); path: file_path.display().to_string(),
if !sent_lines.contains(&file_path_string) {
sent_lines.push(file_path_string.clone());
let finding = Finding {
path: file_path_string,
}; };
if !self.findings.iter().any(|f| f.path == new_finding.path) {
if self.verbose { if self.verbose {
println!("file found: {}", finding.path); println!("file found: {}", new_finding.path);
}
if let Some(outfile) = self.outfile.clone() {
if let Ok(mut lock) = outfile.lock() {
if let Err(e) = lock.write(
format!("file found: {}\r\n", finding.path).as_bytes(),
) {
println!("error writing log file! {e}");
}
}
}
self.findings.push(finding);
} }
self.findings.push(new_finding);
} }
} }
} }
});
} }
TaskType::Info => { TaskType::Info => {
if !self.filter.iter().any(|f| self.target.contains(f)) {
let files_to_read = vec![ let files_to_read = vec![
".txt", ".txt",
".ini", ".ini",
@@ -190,33 +184,83 @@ impl FinderTask {
"key", "key",
"credit card", "credit card",
" cc ", " cc ",
"_cc_",
"-cc-",
"ssn", "ssn",
" ssn ",
"_ssn_",
"-ssn-",
"social Security", "social Security",
"tax", "tax",
"i9", "i9",
" it ", " it ",
"_it_",
"-it-",
"identified", "identified",
"username", "username",
"admin", "admin",
"administrator", "administrator",
]; ];
if files_to_read.iter().any(|e| self.target.contains(e)) { let file_path = PathBuf::from(self.target.clone());
if let Ok(file_content) = read_to_string(&self.target) { if file_path.is_file() {
if interesting_info.iter().any(|i| self.target.contains(i)) if file_path.exists() {
|| interesting_info.iter().any(|i| file_content.contains(i)) let mut read = false;
if let Some(filename) = file_path.file_name() {
if files_to_read
.iter()
.any(|r| filename.to_string_lossy().contains(r))
{
if let Ok(file_content) = read_to_string(&file_path) {
read = true;
if interesting_info.iter().any(|i| {
filename.to_string_lossy().contains(i)
|| file_content.contains(i)
}) && !self
.filter
.iter()
.any(|f| file_path.to_string_lossy().contains(f))
{
if !self.findings.iter().any(|f| f.path == self.target)
{ {
if !self.filter.iter().any(|f| self.target.contains(f)) {
println!("keyword match: {}", self.target);
self.findings.push(Finding { self.findings.push(Finding {
path: self.target.clone(), path: self.target.clone(),
}); });
println!("keyword match: {}", self.target);
if let Some(outfile) = self.outfile.clone() { if let Some(outfile) = self.outfile.clone() {
if let Ok(mut file_lock) = outfile.lock() { if let Ok(mut file_lock) = outfile.lock() {
if let Err(e) = file_lock.write( if let Err(e) = file_lock.write(
format!("keyword match: {}\r\n", self.target.clone()) format!(
"keyword match: {}\n",
self.target.clone()
)
.as_bytes(), .as_bytes(),
) { ) {
println!("error writing log file, {e}"); println!("error writing to log {e}");
}
}
}
}
}
}
}
if !read {
if interesting_info
.iter()
.any(|i| filename.to_string_lossy().contains(i))
{
println!("keyword match: {}", self.target);
if let Some(outfile) = self.outfile.clone() {
if let Ok(mut file_lock) = outfile.lock() {
if let Err(e) = file_lock.write(
format!(
"keyword match: {}\n",
self.target.clone()
)
.as_bytes(),
) {
println!("error writing to log {e}");
}
}
} }
} }
} }
@@ -317,7 +361,7 @@ fn main() {
let mut computers = Vec::new(); let mut computers = Vec::new();
let mut filter_computers = Vec::new(); let mut filter_computers = Vec::new();
let mut network = true; let mut network = true;
if args.diable_network { if args.disable_network {
network = false; network = false;
} }
if args.targets.is_some() { if args.targets.is_some() {
@@ -423,7 +467,7 @@ fn main() {
"C$\\Windows.old".to_string(), "C$\\Windows.old".to_string(),
"ADMIN$\\".to_string(), "ADMIN$\\".to_string(),
"ProgramData\\Microsoft".to_string(), "ProgramData\\Microsoft".to_string(),
"\\AppData\\Local\\Microsoft\\Internet Explorer\\brndlog.txt".to_string(), "AppData\\Local\\Microsoft\\Internet Explorer\\brndlog.txt".to_string(),
"desktop.ini".to_string(), "desktop.ini".to_string(),
"AppData\\Local\\Packages\\Microsoft.Windows.Search".to_string(), "AppData\\Local\\Packages\\Microsoft.Windows.Search".to_string(),
"AppData\\Local\\Microsoft\\Windows\\Shell\\DefaultLayouts.xml".to_string(), "AppData\\Local\\Microsoft\\Windows\\Shell\\DefaultLayouts.xml".to_string(),
@@ -436,9 +480,7 @@ fn main() {
"ContentDirectory.xml".to_string(), "ContentDirectory.xml".to_string(),
"avtransport.xml".to_string(), "avtransport.xml".to_string(),
"ThirdPartyNotices.txt".to_string(), "ThirdPartyNotices.txt".to_string(),
"Program Files\\Common Files\\microsoft shared\\ink\\fsdefinitions".to_string(), "Program Files\\Common Files\\microsoft shared".to_string(),
"Program Files\\Common Files\\microsoft shared\\ink\\Content.xml".to_string(),
"Program Files\\Common Files\\microsoft shared\\ink\\Alphabet.xml".to_string(),
"Diagnostics\\Simple\\Simple.Tests.ps1".to_string(), "Diagnostics\\Simple\\Simple.Tests.ps1".to_string(),
"Microsoft.PowerShell.Operation.Validation.Format.ps1xml".to_string(), "Microsoft.PowerShell.Operation.Validation.Format.ps1xml".to_string(),
"Test\\Microsoft.PowerShell.Operation.Validation.Tests.ps1".to_string(), "Test\\Microsoft.PowerShell.Operation.Validation.Tests.ps1".to_string(),
@@ -454,6 +496,23 @@ fn main() {
"Program Files (x86)\\WindowsPowerShell\\Modules\\PackageManagement".to_string(), "Program Files (x86)\\WindowsPowerShell\\Modules\\PackageManagement".to_string(),
"Program Files (x86)\\WindowsPowerShell\\Modules\\PowerShellGet".to_string(), "Program Files (x86)\\WindowsPowerShell\\Modules\\PowerShellGet".to_string(),
"Program Files (x86)\\WindowsPowerShell\\Modules\\Pester".to_string(), "Program Files (x86)\\WindowsPowerShell\\Modules\\Pester".to_string(),
"Program Files\\Internet Explorer".to_string(),
"Program Files\\Windows Defender".to_string(),
"Program Files\\WindowsApps".to_string(),
"Program Files\\WindowsPowerShell\\Modules\\PackageManagement".to_string(),
"Program Files (x86)\\Internet Explorer".to_string(),
"Program Files (x86)\\Microsoft".to_string(),
"ProgramData\\ntuser.pol".to_string(),
"ProgramData\\USOShared".to_string(),
"AppData\\Local\\ConnectedDevicesPlatform".to_string(),
"AppData\\Local\\Microsoft\\Internet Explorer".to_string(),
"ntuser.dat".to_string(),
"ntuser.ini".to_string(),
"Program Files (x86)\\Windows Defender".to_string(),
"AppData\\Local\\Microsoft\\Windows\\WinX".to_string(),
"AppData\\Local\\Microsoft_Corporation".to_string(),
"AppData\\Roaming\\Microsoft\\Internet Explorer".to_string(),
]; ];
if let Some(user_filter) = args.filter_data { if let Some(user_filter) = args.filter_data {
user_filter.split(",").into_iter().for_each(|p| { user_filter.split(",").into_iter().for_each(|p| {