#include "ve_detection.h" #include #include #include #include using std::cout; using std::endl; namespace SandboxEvasion { // return first: html information // return second: debug information std::pair VEDetection::GenerateReportEntry(const std::string &name, const json_tiny &j, bool detected) const { std::ostringstream ostream_debug; std::ostringstream ostream_html; std::string desc = j.get(Config::cg2s[Config::ConfigGlobal::DESCRIPTION], ""); std::string wtd = j.get(Config::cg2s[Config::ConfigGlobal::COUNTERMEASURES], ""); std::string dtype = j.get(Config::cg2s[Config::ConfigGlobal::TYPE], ""); if (dtype == "") dtype = Config::cgt2s[Config::ConfigGlobalType::CUSTOM]; std::string scr = j.get(Config::cg2s[Config::ConfigGlobal::SCORE], ""); ostream_debug << name << "> " << desc << ": " << detected << std::endl; // add entry to report if (p_report) { p_report->add_entry({ name, dtype, desc, detected ? "YES" : "NO", wtd, scr }); } // if file interface is enabled, then use it if (file_interface) { bool b = file_interface_save(module_name, name, detected); } if (dns_interface) { bool b = dns_interface_save(module_name, name, detected); } return std::pair(ostream_html.str(), ostream_debug.str()); } void VEDetection::CheckAll() { CheckAllCustom(); CheckAllRegistry(); CheckAllFilesExist(); CheckAllDevicesExists(); CheckAllProcessRunning(); CheckAllMacVendors(); CheckAllAdaptersName(); CheckAllFirmwareTables(); CheckAllDirectoryObjects(); CheckAllCpuid(); CheckAllWindows(); CheckAllSharedFolders(); CheckAllDiskNames(); CheckAllDriveModels(); CheckAllLoadedModules(); CheckAllFilePathPatterns(); CheckAllUserNames(); CheckAllComputerNames(); CheckAllHostNames(); CheckAllDisplayAdapters(); if (p_report) { p_report->flush(module_name); } } void VEDetection::AddReportModule(Report *_report) { p_report = _report; } void VEDetection::SetFileInterfaceModule(bool _fim) { file_interface = _fim; } void VEDetection::SetDNSInterfaceModule(bool _dns) { dns_interface = _dns; } void VEDetection::CheckAllRegistry() const { std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::REGISTRY]); CheckAllRegistryKeyExists(jl); CheckAllRegistryKeyValueContains(jl); CheckAllRegistryEnumKeys(jl); CheckAllRegistryEnumValues(jl); } void VEDetection::CheckAllRegistryKeyExists(const std::list> &jl) const { bool detected; std::pair report; json_tiny jt; std::list keys; // iterate through all registry exists detections for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; if (jt.get(Config::ca2s[Config::ConfigArgs::CHECK], "") == Config::carct2s[Config::ConfigArgsRegCheckType::EXISTS]) { keys = jt.get_entries(Config::ca2s[Config::ConfigArgs::KEY]); for (auto &k : keys) { detected = CheckRegKeyExists(jt.get(Config::ca2s[Config::ConfigArgs::HKEY], ""), k ); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } } void VEDetection::CheckAllRegistryKeyValueContains(const std::list> &jl) const { bool detected; std::pair report; json_tiny jt; std::list vn; std::list vd; // iterate through all registry keys contains specific values for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; if (jt.get(Config::ca2s[Config::ConfigArgs::CHECK], "") == Config::carct2s[Config::ConfigArgsRegCheckType::CONTAINS]) { vn = jt.get_entries(Config::ca2s[Config::ConfigArgs::VALUE_NAME]); vd = jt.get_entries(Config::ca2s[Config::ConfigArgs::VALUE_DATA]); for (auto &_vd : vd) { detected = false; for (auto &_vn : vn) { detected = CheckRegKeyValueContains( jt.get(Config::ca2s[Config::ConfigArgs::HKEY], ""), jt.get(Config::ca2s[Config::ConfigArgs::KEY], ""), _vn, _vd, jt.get(Config::ca2s[Config::ConfigArgs::RECURSIVE], "") == Config::cge2s[Config::ConfigGlobalEnabled::YES]); if (detected) break; } if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } } void VEDetection::CheckAllRegistryEnumKeys(const std::list>& jl) const { bool detected; std::pair report; json_tiny jt; std::list subkeys; // iterate through all registry keys contains specific values for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; if (jt.get(Config::ca2s[Config::ConfigArgs::CHECK], "") == Config::carct2s[Config::ConfigArgsRegCheckType::ENUM_KEYS]) { subkeys = jt.get_entries(Config::ca2s[Config::ConfigArgs::SUBKEY]); for (auto &sk : subkeys) { detected = CheckRegKeyEnumKeys( jt.get(Config::ca2s[Config::ConfigArgs::HKEY], ""), jt.get(Config::ca2s[Config::ConfigArgs::KEY], ""), sk); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } } void VEDetection::CheckAllRegistryEnumValues(const std::list>& jl) const { bool detected; std::pair report; json_tiny jt; std::list values; // iterate through all registry keys contains specific values for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; if (jt.get(Config::ca2s[Config::ConfigArgs::CHECK], "") == Config::carct2s[Config::ConfigArgsRegCheckType::ENUM_VALUES]) { values = jt.get_entries(Config::ca2s[Config::ConfigArgs::VALUE_NAME]); for (auto &v : values) { detected = CheckRegKeyEnumValues( jt.get(Config::ca2s[Config::ConfigArgs::HKEY], ""), jt.get(Config::ca2s[Config::ConfigArgs::KEY], ""), v); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } } void VEDetection::CheckAllFilesExist() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::FILE]); json_tiny jt; std::list fnames; // check for the presence of all files for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; fnames = jt.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); for (auto &fn : fnames) { detected = CheckFileExists(fn); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllDevicesExists() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::DEVICE]); json_tiny jt; std::list devicenames; // check for the presence of devices for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; devicenames = jt.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); for (auto &dn : devicenames) { detected = CheckDeviceExists(dn); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllProcessRunning() const { bool detected; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::PROCESS]); std::list runningProcesses; // check for the presence of processes for each (auto &o in jl) { if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; const json_tiny &arguments = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (runningProcesses.empty() && !get_running_process_list(runningProcesses)) { log_message(LogMessageLevel::ERR, module_name, "get_running_process_set() failed", RED); return; } for (auto pn : arguments.get_entries(Config::ca2s[Config::ConfigArgs::NAME])) { std::wstring wprocToCheck(pn.begin(), pn.end()); //std::transform(wprocToCheck.begin(), wprocToCheck.end(), wprocToCheck.begin(), towlower); detected = std::find_if(runningProcesses.begin(), runningProcesses.end(), [wprocToCheck](const std::wstring &w) { return !StrCmpIW(wprocToCheck.c_str(), w.c_str()); }) != runningProcesses.end(); if (detected) break; } const auto &report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } // check for max processes number jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::MAX_PROCS_NUMBER]); for (const auto &o : jl) { if (!IsEnabled(o.first, conf.get(o.first + "." + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; const json_tiny &arguments = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); const int maxProcesses = arguments.get(Config::ca2s[Config::ConfigArgs::NUMBER], 499); if (runningProcesses.empty() && !get_running_process_list(runningProcesses)) { log_message(LogMessageLevel::ERR, module_name, "get_running_process_set() failed", RED); return; } detected = static_cast(runningProcesses.size()) > maxProcesses; const auto &report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } // check for process with name longer than predefined one jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::PROC_WITH_LONG_NAME]); for (const auto &o : jl) { if (!IsEnabled(o.first, conf.get(o.first + "." + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; const json_tiny &arguments = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); const int maxProcessLen = arguments.get(Config::ca2s[Config::ConfigArgs::NUMBER], 65); detected = std::find_if(runningProcesses.begin(), runningProcesses.end(), [maxProcessLen](const std::wstring &w) { return w.length() >= maxProcessLen; }) != runningProcesses.end(); const auto &report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllMacVendors() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::MAC]); json_tiny jt; std::list macaddrs; // check for the presence of devices for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; macaddrs = jt.get_entries(Config::ca2s[Config::ConfigArgs::VENDOR]); for (auto &mac : macaddrs) { detected = CheckMacVendor(mac); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllAdaptersName() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::ADAPTER]); json_tiny jt; std::list adapters; // check for the presence of devices for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; adapters = jt.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); for (auto &adp : adapters) { detected = CheckAdapterName(adp); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllFirmwareTables() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::FIRMWARE]); json_tiny jt; std::list firmwares; // check for the presence of all files for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; firmwares = jt.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); for (auto &f : firmwares) { if (jt.get(Config::ca2s[Config::ConfigArgs::CHECK], "") == Config::cafct2s[Config::ConfigArgsFirmwareCheckType::FIRMBIOS]) detected = CheckFirmwareTableFIRM(f); else if (jt.get(Config::ca2s[Config::ConfigArgs::CHECK], "") == Config::cafct2s[Config::ConfigArgsFirmwareCheckType::RSMBBIOS]) detected = CheckFirmwareTableRSMB(f); else detected = false; if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllDirectoryObjects() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::OBJECT]); json_tiny jt; std::list dirobjects; // check for the presence of specific directory objects for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; dirobjects = jt.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); for (auto &dir : dirobjects) { detected = CheckDirectoryObject(jt.get(Config::ca2s[Config::ConfigArgs::DIRECTORY], ""), dir); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllCpuid() const { bool detected = false; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::CPUID_H]); json_tiny jt; std::list vendors; // check for the presence of specific directory objects for (const auto &o : jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; vendors = jt.get_entries(Config::ca2s[Config::ConfigArgs::VENDOR]); for (const auto &v : vendors) { detected = CheckCpuHypervisorId(v); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } detected = false; jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::CPUID_V]); if (!jl.empty()) { std::string vendor; if (GetCpuVendorId(vendor)) { for (const auto &o : jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; vendors = jt.get_entries(Config::ca2s[Config::ConfigArgs::VENDOR]); for (const auto &v : vendors) { detected = vendor.find(v) != vendor.npos; if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } } } void VEDetection::CheckAllWindows() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::WINDOW]); json_tiny jt; std::list windows; // check for the presence of specific directory objects for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; windows = jt.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); for (auto &w : windows) { if (jt.get(Config::ca2s[Config::ConfigArgs::CHECK], "") == Config::cawct2s[Config::ConfigArgsWindowCheckType::CLASS]) detected = CheckWindowClassName(w); else if (jt.get(Config::ca2s[Config::ConfigArgs::CHECK], "") == Config::cawct2s[Config::ConfigArgsWindowCheckType::WINDOW]) detected = CheckWindowWindowName(w); else detected = false; if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllSharedFolders() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::SHARED]); json_tiny jt; std::list shared_folders; // check for the presence of specific directory objects for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; shared_folders = jt.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); for (auto &sf : shared_folders) { detected = CheckSharedFolder(sf); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllDiskNames() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::DISK]); json_tiny jt; std::list disk_names; // check for the presence of specific directory objects for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; disk_names = jt.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); for (auto &dn : disk_names) { detected = CheckDiskName(dn); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllDriveModels() const { bool detected; std::pair report; std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::DRIVE_MODEL]); json_tiny jt; std::list drive_models; // check for the presence of specific directory objects for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + std::string(".") + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; drive_models = jt.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); for (auto &dm : drive_models) { detected = CheckDriveModel(dm); if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllLoadedModules() const { const auto& jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::HAS_LOADED_MOD]); if (jl.empty()) return; for (const auto &o : jl) { if (!IsEnabled(o.first, conf.get(o.first + "." + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; const json_tiny& arguments = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); const auto &moduleNames = arguments.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); bool detected = false; for (const auto &moduleName : moduleNames) { detected = is_module_loaded(moduleName); if (detected) break; } const auto &report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllFilePathPatterns() const { const auto& jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::EXE_PATH_PATTERN]); if (jl.empty()) return; std::wstring wFullPath; if (!get_module_wfilename(wFullPath)) return; for (const auto &o : jl) { if (!IsEnabled(o.first, conf.get(o.first + "." + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; const json_tiny& arguments = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); const auto &patterns = arguments.get_entries(Config::ca2s[Config::ConfigArgs::PATTERN]); bool detected = false; for (const auto &pattern : patterns) { try { std::wstring wpattern; wpattern.assign(pattern.begin(), pattern.end()); std::wregex re(wpattern, std::regex::icase); detected = std::regex_match(wFullPath, re); if (detected) break; } catch (const std::regex_error &e) { log_message(LogMessageLevel::ERR, module_name, "regex error: " + std::string(e.what()), RED); } catch (...) { log_message(LogMessageLevel::ERR, module_name, "unknown error occurred", RED); } } const auto &report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllUserNames() const { const auto& jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::USER_NAME]); if (jl.empty()) return; for (const auto &o : jl) { if (!IsEnabled(o.first, conf.get(o.first + "." + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; const json_tiny& arguments = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); const auto &userNames = arguments.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); bool detected = false; for (const auto &userName : userNames) { detected = is_user_name_match(userName); if (detected) break; } const auto &report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllComputerNames() const { const auto& jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::COMPUTER_NAME]); if (jl.empty()) return; for (const auto &o : jl) { if (!IsEnabled(o.first, conf.get(o.first + "." + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; const json_tiny& arguments = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); const auto &computerNames = arguments.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); bool detected = false; for (const auto &computerName : computerNames) { detected = is_computer_name_match(computerName); if (detected) break; } const auto &report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllHostNames() const { const auto& jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::HOST_NAME]); if (jl.empty()) return; for (const auto &o : jl) { if (!IsEnabled(o.first, conf.get(o.first + "." + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; const json_tiny& arguments = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); const auto &hostNames = arguments.get_entries(Config::ca2s[Config::ConfigArgs::NAME]); bool detected = false; for (const auto &hostName : hostNames) { detected = is_computer_name_match(hostName); if (detected) break; } const auto &report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } void VEDetection::CheckAllDisplayAdapters() const { std::list> jl = conf.get_objects(Config::cg2s[Config::ConfigGlobal::TYPE], Config::cgt2s[Config::ConfigGlobalType::DISPLAY_ADAPTER]); bool detected; std::pair report; json_tiny jt; std::list vn; std::list vd; for each (auto &o in jl) { jt = o.second.get(Config::cg2s[Config::ConfigGlobal::ARGUMENTS], pt::ptree()); if (!IsEnabled(o.first, conf.get(o.first + "." + Config::cg2s[Config::ConfigGlobal::ENABLED], ""))) continue; vn = jt.get_entries(Config::ca2s[Config::ConfigArgs::VALUE_NAME]); vd = jt.get_entries(Config::ca2s[Config::ConfigArgs::VALUE_DATA]); for (auto &vd_entry : vd) { detected = false; for (auto &vn_entry : vn) { detected = CheckDisplayAdapterSettings(vn_entry, vd_entry); if (detected) break; } if (detected) break; } report = GenerateReportEntry(o.first, o.second, detected); log_message(LogMessageLevel::INFO, module_name, report.second, detected ? RED : GREEN); } } bool VEDetection::CheckRegKeyExists(const std::string &key_root, const std::string &key) const { HKEY hRootKey = get_hkey(key_root); if (hRootKey == reinterpret_cast(INVALID_HKEY)) return false; return check_regkey_exists(hRootKey, key); } bool VEDetection::CheckRegKeyValueContains(const std::string &key_root, const std::string &key, const std::string &subkey, const std::string &value, bool rec) const { HKEY hRootKey = get_hkey(key_root); if (hRootKey == reinterpret_cast(INVALID_HKEY)) return false; return check_regkey_subkey_value(hRootKey, key, subkey, value, rec); } bool VEDetection::CheckRegKeyEnumKeys(const std::string & key_root, const std::string & key, const std::string & subkey) const { HKEY hRootKey = get_hkey(key_root); if (hRootKey == reinterpret_cast(INVALID_HKEY)) return false; return check_regkey_enum_keys(hRootKey, key, subkey); } bool VEDetection::CheckRegKeyEnumValues(const std::string & key_root, const std::string & key, const std::string & value) const { HKEY hRootKey = get_hkey(key_root); if (hRootKey == reinterpret_cast(INVALID_HKEY)) return false; return check_regkey_enum_values(hRootKey, key, value); } bool VEDetection::CheckDisplayAdapterSettings(const std::string &value_name, const std::string &value_data) const { std::map settings; if (!get_display_adapter_settings(settings)) return false; auto value_name_lower_case = make_lowercase(value_name); auto value_data_lower_case = make_lowercase(value_data); for (auto &val : settings) { if (value_name_lower_case == make_lowercase(val.first) && value_data_lower_case == make_lowercase(val.second)) return true; } return false; } bool VEDetection::CheckFileExists(const file_name_t &file_name) const { return check_file_exists(file_name); } bool VEDetection::CheckDeviceExists(const file_name_t &dev_name) const { return check_device_exists(dev_name); } bool VEDetection::CheckProcessIsRunning(const process_name_t &proc_name) const { return check_process_is_running(proc_name); } bool VEDetection::CheckMacVendor(const std::string &ven_id) const { return check_mac_vendor(ven_id); } bool VEDetection::CheckAdapterName(const std::string &adapter_name) const { return check_adapter_name(adapter_name); } bool VEDetection::CheckFirmwareTableFIRM(const std::string &vendor) const { CHAR *sfti; DWORD data_size; bool found; sfti = reinterpret_cast(get_firmware_table(&data_size, FIRM, 0xC0000)); if (!sfti) return false; found = !!scan_mem(sfti, data_size, const_cast(vendor.c_str()), vendor.length()); LocalFree(sfti); return found; } bool VEDetection::CheckFirmwareTableRSMB(const std::string &vendor) const { CHAR *sfti; DWORD data_size; bool found; sfti = reinterpret_cast(get_firmware_table(&data_size, RSMB, 0x0)); if (!sfti) return false; found = !!scan_mem(sfti, data_size, const_cast(vendor.c_str()), vendor.length()); LocalFree(sfti); return found; } bool VEDetection::CheckDirectoryObject(const std::string &directory, const std::string &object) const { std::wstring directory_w; std::wstring object_w; directory_w.assign(directory.begin(), directory.end()); object_w.assign(object.begin(), object.end()); return !!check_system_objects(directory_w, object_w); } bool VEDetection::CheckCpuHypervisorId(const std::string &cpuid_s) const { char cpuid_[sizeof(DWORD) * 3] = {}; size_t s = cpuid_s.length() > _countof(cpuid_) ? _countof(cpuid_) : cpuid_s.length(); get_cpu_hypevisor_id(cpuid_); return !strncmp(cpuid_, cpuid_s.c_str(), s); } bool VEDetection::GetCpuVendorId(std::string &cpuid_s) const { char cpuid_[sizeof(DWORD) * 3 + 1] = {}; get_cpu_vendor_id(cpuid_); cpuid_s = cpuid_; return !cpuid_s.empty(); } bool VEDetection::CheckWindowClassName(const std::string &cname) const { return !!FindWindowA(cname.c_str(), NULL); } /* * Code taken from: https://github.com/a0rtega/pafish */ bool VEDetection::CheckSharedFolder(const std::string &name) const { char provider[0x1000]; DWORD provider_size = _countof(provider); if (WNetGetProviderNameA(WNNC_NET_RDR2SAMPLE, provider, &provider_size) != NO_ERROR) return false; return !!StrStrIA(provider, name.c_str()); } bool VEDetection::CheckDiskName(const std::string &name) const { std::list disks; if (!get_drive_print_names(disks)) return false; for (auto &d : disks) { if (StrStrIA(d.c_str(), name.c_str())) return true; } return false; } bool VEDetection::CheckDriveModel(const std::string &drive_model) const { std::list drive_models; if (!get_drive_models(drive_models)) return false; for (auto &dm : drive_models) { if (StrStrIA(dm.c_str(), drive_model.c_str())) return true; } return false; } bool VEDetection::CheckWindowWindowName(const std::string &wname) const { return !!FindWindowA(NULL, wname.c_str()); } bool VEDetection::IsEnabled(const std::string &detection_name, const std::string &enabled) const { return detection_name != "" && enabled == Config::cge2s[Config::ConfigGlobalEnabled::YES]; } } // SandboxEvasion