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
+142 -83
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,87 +136,131 @@ 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 {
let file_path = entry.into_path(); if self
if file_path.file_name().is_some() { .filter
let file_path_string = file_path.display().to_string(); .iter()
if !sent_lines.contains(&file_path_string) { .any(|f| !entry.path().to_string_lossy().contains(f))
sent_lines.push(file_path_string.clone()); {
let finding = Finding { let file_path = entry.into_path();
path: file_path_string, let new_finding = Finding {
path: file_path.display().to_string(),
}; };
if self.verbose { if !self.findings.iter().any(|f| f.path == new_finding.path) {
println!("file found: {}", finding.path); if self.verbose {
println!("file found: {}", new_finding.path);
}
self.findings.push(new_finding);
} }
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(), }
) { TaskType::Info => {
println!("error writing log file! {e}"); if !self.filter.iter().any(|f| self.target.contains(f)) {
let files_to_read = vec![
".txt",
".ini",
".xml",
".json",
".config",
".conf",
".bat",
".cmd",
".sql",
".ps1",
".py",
".vbscript",
];
let interesting_info = vec![
"password",
"pass",
"user",
"api",
"key",
"credit card",
" cc ",
"_cc_",
"-cc-",
"ssn",
" ssn ",
"_ssn_",
"-ssn-",
"social Security",
"tax",
"i9",
" it ",
"_it_",
"-it-",
"identified",
"username",
"admin",
"administrator",
];
let file_path = PathBuf::from(self.target.clone());
if file_path.is_file() {
if file_path.exists() {
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)
{
self.findings.push(Finding {
path: self.target.clone(),
});
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}");
}
}
}
}
} }
} }
} }
self.findings.push(finding); if !read {
} if interesting_info
} .iter()
} .any(|i| filename.to_string_lossy().contains(i))
} {
} println!("keyword match: {}", self.target);
TaskType::Info => { if let Some(outfile) = self.outfile.clone() {
let files_to_read = vec![ if let Ok(mut file_lock) = outfile.lock() {
".txt", if let Err(e) = file_lock.write(
".ini", format!(
".xml", "keyword match: {}\n",
".json", self.target.clone()
".config", )
".conf", .as_bytes(),
".bat", ) {
".cmd", println!("error writing to log {e}");
".sql", }
".ps1", }
".py",
".vbscript",
];
let interesting_info = vec![
"password",
"pass",
"user",
"api",
"key",
"credit card",
"cc",
"ssn",
"social Security",
"tax",
"i9",
"it",
"identified",
"username",
"admin",
"administrator",
];
if files_to_read.iter().any(|e| self.target.contains(e)) {
if let Ok(file_content) = read_to_string(&self.target) {
if interesting_info.iter().any(|i| self.target.contains(i))
|| interesting_info.iter().any(|i| file_content.contains(i))
{
if !self.filter.iter().any(|f| self.target.contains(f)) {
println!("keyword match: {}", self.target);
self.findings.push(Finding {
path: self.target.clone(),
});
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: {}\r\n", self.target.clone())
.as_bytes(),
) {
println!("error writing log file, {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| {