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() {
const _: () = 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() {
const _: () = assert!(
RANSOMWARE_SERVICE_STOP_CLUSTER_THRESHOLD >= 3,
"threshold must be at least 3"
);
}
}