pub const RANSOM_NOTE_FILENAMES: &[&str] = &[
"_readme.txt",
"Restore-My-Files.txt",
"LockBit_README.txt",
"LockBit-README.txt",
"LockBit3.0.hta",
"LockBit_Green_README.txt",
"!!!READ_ME_EDWARD.txt",
"RECOVER-FILES.txt",
"GET-IT-BACK-FILES.txt",
"HOW_TO_GET_YOUR_FILES_BACK.txt",
"README_RANSOMHUB.txt",
"RANSOMHUB.txt",
"CONTI_README.txt",
"HOW_TO_DECRYPT.txt",
"hive.README.txt",
"HOW-DECRYPT.txt",
"Decryption README.txt",
"GDCB-DECRYPT.txt",
"KRAB-DECRYPT.txt",
"GandCrab.html",
"ClopReadMe.txt",
"!Cl0pReadMe.txt",
"C!0p.txt",
"RyukReadMe.txt",
"RYUK_README.txt",
"DarkSide.README.txt",
"info.hta",
"Phobos.README.txt",
"HOW_TO_RECOVER_DATA.html",
"How_To_Recover_Encrypted_Files.html",
"Recovery_Instructions.html",
"HOW_TO_RECOVER_ENCRYPTED_DATA.html",
"DECRYPT-FILES.txt",
"MAZE-DECRYPT.txt",
"DECRYPT-FILES.html",
"readme2unlock.txt",
"DOPPEL-README.txt",
"@Please_Read_Me@.txt",
"@WanaDecryptor@.txt",
"!WannaCry!.txt",
"#README_MATRIX#.rtf",
"!readme_matrix_decryption.rtf",
"#Decrypt_files_readme#.rtf",
"FILES ENCRYPTED.txt",
"RETURN FILES.txt",
"DECRYPT_NOTE.txt",
"DECRYPT_INFORMATION.html",
"HERMES_README.txt",
"HELP_DECRYPT_YOUR_FILES.html",
"HELP_TO_DECRYPT.html",
"_Locky_recover_instructions.txt",
"HELP_instructions.html",
"DECRYPT_INSTRUCTION.html",
"HOW_TO_RESTORE_FILES.txt",
"CryptoLocker.txt",
"CryptoLocker.html",
"HELP_TO_DECRYPT_YOUR_FILES.txt",
"HOWTO_RESTORE_FILES.txt",
"!Decrypt-All-Files.txt",
"README1.txt",
"README_crypted.txt",
"GET_YOUR_FILES_BACK.txt",
"AvosLocker.txt",
"Instructions.txt",
"HELP_SECURITY_EVENT.html",
"HELP_SECURITY_EVENT.txt",
"README_TO_DECRYPT.html",
"README-QUANTUM.txt",
"Look at this instruction.txt",
"BianLian.txt",
"README.TXT",
"ROYAL_README.txt",
"ReadMe.txt",
"IMPORTANT NOTICE.txt",
"How To Restore Your Files.txt",
"akira_readme.txt",
"AKIRA_RECOVERY.txt",
"CriticalBreachDetected.pdf",
"INC-README.txt",
"INC_README.txt",
"Contact_for_Unlock.txt",
"README-IMPORTANT.txt",
"QILIN-README.txt",
"DragonForce_README.txt",
"README.BlackSuit.txt",
"BlackSuit_README.txt",
"AllYFilesAE.txt",
"RESTORE_FILES.txt",
"KARMA-README.txt",
"Yanluowang_readme.txt",
"README_FOR_DECRYPT.txt",
"RAGNAR_LOCKER_README.txt",
"read_me_unlock.txt",
"FIVEHANDS.README.txt",
"_how_to_decrypt.txt",
"how_to_decrypt.txt",
"NEVADA_README.txt",
"!!! ALL YOUR FILES ARE ENCRYPTED !!!.TXT",
"Zeppelin.txt",
"Pysa.README.txt",
"Monti_README.txt",
"HOW-TO-DECRYPT.txt",
"HOW_TO_RESTORE_YOUR_FILES.txt",
"CrossLock_readme.txt",
"RA_Help.txt",
"instructions.txt",
"!! CUBA !!.txt",
"NOKOYAWA_readme.txt",
"Rorschach_Note.txt",
"!HowToDecrypt.txt",
"avaddon_readme.html",
"PROMETHEUS_README.txt",
"grief_readme.txt",
"RecoveryManual.html",
"!-MountLocker-recover_instructions.txt",
"Restore_My_Files.txt",
"!Readme.txt",
"~readme.txt",
"DearCry.txt",
"Read_Me.html",
"ATOMIKSILO_README.txt",
"Knight_README.txt",
"Pandora.txt",
"MindWare.readme.txt",
"FILES_ENCRYPTED.txt",
"HOW-TO-DECRYPT-FILES.txt",
"readme.txt",
"README.txt",
"READ_ME.txt",
"READ-ME.txt",
"!readme.txt",
"RESTORE_INSTRUCTIONS.txt",
"DECRYPT_INSTRUCTION.txt",
"HELP_DECRYPT.html",
"HELP_DECRYPT.txt",
"HELP_YOUR_FILES.txt",
"IMPORTANT.txt",
"IMPORTANT_README.txt",
"YOUR_FILES_ARE_ENCRYPTED.txt",
"HOW_RECOVER_FILES.txt",
"DECRYPT_YOUR_FILES.html",
"HOW_TO_UNLOCK.txt",
];
pub const RANSOMWARE_KILL_PROCESSES: &[&str] = &[
"sql.exe", "sqlserv.exe", "sqlbrowser.exe", "sqlwriter.exe", "sqlagent.exe",
"sqlservr.exe", "oracle.exe", "ocssd.exe", "dbsnmp.exe", "dbeng50.exe",
"mysqld.exe", "mysqld-nt.exe", "mysqld-opt.exe", "postgres.exe",
"excel.exe", "infopath.exe", "msaccess.exe", "mspub.exe", "onenote.exe",
"outlook.exe", "powerpnt.exe", "winword.exe", "wordpad.exe", "notepad.exe",
"thunderbird.exe", "thebat.exe", "tbirdconfig.exe", "steam.exe", "firefox.exe",
"veeam.exe", "veeamguestindexer.exe", "veeamtransportsvc.exe",
"veeamdeploymentsvc.exe", "veeammountservice.exe",
"sophos.exe", "savadminservice.exe", "savservice.exe", "sedservice.exe",
"mbamtray.exe", "mbam.exe",
"msmpeng.exe", "nissrv.exe", "securityhealthservice.exe",
"sentinelagent.exe", "sentinelhelperservice.exe", "sentinelservicehost.exe",
"csfalconservice.exe", "crowdstrike.exe",
"elastic-agent.exe",
"ekrn.exe", "egui.exe",
"avgnt.exe", "avguard.exe",
"avp.exe", "kavfsslp.exe", "klnagent.exe",
"mfemms.exe", "masvc.exe", "macmnsvc.exe", "mcshield.exe",
"tmlisten.exe", "pccntmon.exe", "ntrtscan.exe", "tmccsf.exe",
"backup.exe", "backupexecagentaccelerator.exe", "backupexecagentbrowser.exe",
"backupexecdevicemediaservice.exe", "backupexecjobengine.exe",
"backupexecmanagementservice.exe", "backupexecrpcservice.exe",
"backupexecvssprovider.exe", "bedbg.exe", "benetns.exe", "beserver.exe",
"pvlsvr.exe", "raw_agent_svc.exe", "cagservice.exe",
"sage.exe", "qbw32.exe", "qbdbmgr.exe", "qbdbmgrn.exe", "qbcfmonitorservice.exe",
"synctime.exe", "agntsvc.exe", "isqlplussvc.exe", "xfssvccon.exe",
"mydesktopservice.exe", "mydesktopqos.exe", "ocautoupds.exe", "encsvc.exe",
"ocomm.exe", "sqbcoreservice.exe", "ds_agent.exe", "zoolz.exe",
"httpd.exe", "nginx.exe", "node.exe", "java.exe",
"hitmanpro.alert.exe", "googleupdate.exe",
];
pub const RANSOMWARE_KILL_CLUSTER_THRESHOLD: usize = 5;
pub const RANSOMWARE_KILL_WINDOW_NS: i64 = 60_000_000_000;
pub const RANSOMWARE_STOP_SERVICES: &[&str] = &[
"vss",
"sqlserveragent", "mssqlserver", "sqlbrowser", "sqlwriter",
"reportserver", "sqlanywhere", "sqladhlp", "sqltelemetry",
"mssqlserveradhelper", "mssqlserveradhelper100", "mssqlserverolapservice",
"veeambackupsvc", "veeamcatalogsvc", "veeamtransportsvc", "veeammountsvc",
"veeamdeploysvc", "veeamnfssvc", "veeamrestsvc", "veeamcloudsvc",
"veeamdistributionsvc", "veeamenterprisemanagersvc", "veeamdeploymentservice",
"veeambrokerssvc",
"gxvss", "gxblr", "gxfwd", "gxcvd", "gxcimgr",
"backupexecagentaccelerator", "backupexecagentbrowser",
"backupexecdevicemediaservice", "backupexecjobengine",
"backupexecmanagementservice", "backupexecrpcservice", "backupexecvssprovider",
"acrsch2svc", "acronisagent",
"sophosagent", "sophosautoupdateservice", "savadminservice", "savservice",
"sophosclean", "sophoshealth", "sophosmcsagent", "sophosmcsclient",
"sophosmessagerouter", "sophossafestore", "sophossystemprotectionservice",
"msexchangeis", "msexchangetransport", "msexchangeadtopology",
"msexchangedelivery", "msexchangefrontendtransport", "msexchangerepl",
"msexchangesa", "msexchangeservicehost", "msexchangees", "msexchangemta",
"msexchangeantispamupdate", "msexchangefastsearch", "msexchangehm",
"msexchangeum", "msexchangeumcr",
"mfemms", "mfefire", "mfevtp", "mcshield", "mctaskmanager",
"kavfs", "kavfsgt", "kavfsslp", "klnagent",
"mbamservice",
"qbcfmonitorservice", "qbidpservice", "qbvss",
"w3svc", "iisadmin", "smtpsvc", "imap4svc", "pop3svc",
"wbengine", "sdrsvc", "pdvfsservice",
"ehttpsrv", "epsecurityservice", "epupdateservice", "erasrv", "esgshkernel",
"healthservice",
"ntrtscan", "tmccsf", "tmlisten",
"msmpsvc",
];
pub const RANSOMWARE_SERVICE_STOP_CLUSTER_THRESHOLD: usize = 3;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ransom_note_filenames_not_empty() {
assert!(
!RANSOM_NOTE_FILENAMES.is_empty(),
"RANSOM_NOTE_FILENAMES must contain entries"
);
}
#[test]
fn ransom_note_filenames_covers_stop_djvu() {
assert!(
RANSOM_NOTE_FILENAMES.contains(&"_readme.txt"),
"STOP/DJVU _readme.txt must be covered"
);
}
#[test]
fn ransom_note_filenames_covers_lockbit() {
assert!(
RANSOM_NOTE_FILENAMES.contains(&"LockBit_README.txt"),
"LockBit note must be covered"
);
}
#[test]
fn ransom_note_filenames_covers_wannacry() {
assert!(
RANSOM_NOTE_FILENAMES.contains(&"@Please_Read_Me@.txt"),
"WannaCry note must be covered"
);
}
#[test]
fn ransom_note_filenames_covers_akira() {
assert!(
RANSOM_NOTE_FILENAMES.contains(&"akira_readme.txt"),
"Akira note must be covered"
);
}
#[test]
fn ransom_note_filenames_covers_qwcrypt() {
assert!(
RANSOM_NOTE_FILENAMES.contains(&"FILES_ENCRYPTED.txt"),
"QWCrypt/RedCurl note must be covered"
);
}
#[test]
fn ransom_note_filenames_covers_hive() {
assert!(
RANSOM_NOTE_FILENAMES.contains(&"HOW_TO_DECRYPT.txt"),
"Hive note must be covered"
);
}
#[test]
fn ransom_note_filenames_covers_cryptolocker() {
assert!(
RANSOM_NOTE_FILENAMES.contains(&"DECRYPT_INSTRUCTION.html"),
"CryptoLocker note must be covered"
);
}
#[test]
fn ransom_note_filenames_no_duplicates() {
let mut sorted = RANSOM_NOTE_FILENAMES.to_vec();
sorted.sort_unstable();
let original_len = sorted.len();
sorted.dedup();
assert_eq!(
sorted.len(),
original_len,
"RANSOM_NOTE_FILENAMES contains duplicate entries"
);
}
#[test]
fn ransom_note_filenames_no_path_separators() {
for name in RANSOM_NOTE_FILENAMES {
assert!(
!name.contains('\\') && !name.contains('/'),
"Entry '{name}' contains a path separator — basenames only"
);
}
}
#[test]
fn ransom_note_filenames_has_substantial_coverage() {
assert!(
RANSOM_NOTE_FILENAMES.len() >= 50,
"Expected at least 50 ransom note filenames for meaningful coverage, got {}",
RANSOM_NOTE_FILENAMES.len()
);
}
#[test]
fn kill_processes_includes_sql_server() {
assert!(
RANSOMWARE_KILL_PROCESSES.iter().any(|p| p.contains("sql")),
"must include SQL server process names"
);
}
#[test]
fn kill_processes_includes_veeam() {
assert!(
RANSOMWARE_KILL_PROCESSES.iter().any(|p| p.contains("veeam")),
"must include Veeam process names"
);
}
#[test]
fn kill_processes_includes_av_product() {
assert!(
RANSOMWARE_KILL_PROCESSES
.iter()
.any(|p| p.contains("sophos") || p.contains("mcshield") || p.contains("msmpeng")),
"must include at least one AV process"
);
}
#[test]
fn kill_processes_all_lowercase() {
for name in RANSOMWARE_KILL_PROCESSES {
assert_eq!(
*name,
name.to_lowercase(),
"all kill-list process names must be lowercase, got '{name}'"
);
}
}
#[test]
fn kill_processes_no_path_separators() {
for name in RANSOMWARE_KILL_PROCESSES {
assert!(
!name.contains('\\') && !name.contains('/'),
"'{name}' must be a basename only"
);
}
}
#[test]
fn kill_cluster_threshold_is_at_least_3() {
assert!(
RANSOMWARE_KILL_CLUSTER_THRESHOLD >= 3,
"threshold must be at least 3 to avoid trivial false positives"
);
}
#[test]
fn kill_window_is_60_seconds() {
assert_eq!(
RANSOMWARE_KILL_WINDOW_NS,
60_000_000_000,
"window must be exactly 60 seconds in nanoseconds"
);
}
#[test]
fn stop_services_includes_veeam() {
assert!(
RANSOMWARE_STOP_SERVICES
.iter()
.any(|s| s.contains("veeam")),
"must include Veeam backup services"
);
}
#[test]
fn stop_services_includes_commvault_cluster() {
let commvault = &["gxvss", "gxblr", "gxfwd", "gxcvd", "gxcimgr"];
for svc in commvault {
assert!(
RANSOMWARE_STOP_SERVICES.contains(svc),
"Commvault '{svc}' must be in stop-list (cited in CISA AA23-075A)"
);
}
}
#[test]
fn stop_services_all_lowercase() {
for svc in RANSOMWARE_STOP_SERVICES {
assert_eq!(
*svc,
svc.to_lowercase(),
"all stop-list service names must be lowercase, got '{svc}'"
);
}
}
#[test]
fn service_stop_threshold_is_at_least_3() {
assert!(
RANSOMWARE_SERVICE_STOP_CLUSTER_THRESHOLD >= 3,
"threshold must be at least 3"
);
}
}