function __construct() { global $projectRootDir, $projectTmpDir; if (!function_exists('escapedHexToHex') || !function_exists('escapedOctDec')) { die('escapedHexToHex or escapedOctDec is missing'); } $this->SIGNATURE_FILENAME = $projectRootDir . '/static/signatures/malware_db.xml'; $this->QUEUE_FILENAME = $projectTmpDir . '/scan_queue.manul.tmp.txt'; $this->QUEUE_OFFSET_FILENAME = $projectTmpDir . '/queue_offset.manul.tmp.txt'; $this->MALWARE_LOG_FILENAME = $projectTmpDir . '/malware_log.manul.tmp.txt'; $this->MALWARE_QUARANTINE_FILENAME = $projectTmpDir . '/malware_quarantine.manul.tmp.txt'; $this->MALWARE_QUARANTINE_FILEPATH_FILEPATH = $projectTmpDir . '/malware_quarantine_filepath.tmp.txt'; $this->XML_LOG_FILENAME = $projectTmpDir . '/scan_log.xml'; $this->SCRIPT_START = time(); $this->MAX_FILESIZE = 1 * 1024 * 1024; // 1MB $this->MAX_PREVIEW_LENGTH = 80; // characters $this->MAX_EXECUTION_DURATION = 20; $validator = new XmlValidator(); if (!$validator->validate(implode('', file($this->SIGNATURE_FILENAME)), $projectRootDir . '/static/xsd/malware_db.xsd')) { die(basename(__FILE__) . PS_ERR_MALWARE_DB_BROKEN); } $this->signatures = new DOMDocument(); $this->signatures->load($this->SIGNATURE_FILENAME); }
private function startExecutor() { $view = new View(); $healer = new Healer(); if (!empty($_POST) && !empty($_POST['recipe'])) { $xmlRecipe = $_POST['recipe']; $validator = new XmlValidator(); global $projectRootDir; if (get_magic_quotes_gpc()) { $xmlRecipe = stripslashes($xmlRecipe); } //TODO: implement proper XXE prevention or switch to JSON instead if (strpos(strtoupper($xmlRecipe), '<!ENTITY') !== false) { die('XXE detected'); } if (!$validator->validate($xmlRecipe, $projectRootDir . '/static/xsd/recipe.xsd')) { die(PS_ERR_BROKEN_XML_FILE); } $executeList = ''; $itemTemplate = new Template('executor_item.tpl'); $quarantineFiles = array(); $deleteFiles = array(); $healer->prepareList($xmlRecipe, $quarantineFiles, $deleteFiles); for ($i = 0; $i < count($deleteFiles); $i++) { $itemTemplate->prepare(); $itemTemplate->set('PREFIX', 'd'); $itemTemplate->set('NUM', $i); $itemTemplate->set('ACTION', PS_RECIPE_ACTION_DEL); $itemTemplate->set('FILENAME', $this->getShortFilename($deleteFiles[$i])); $itemTemplate->set('FILENAME_B64', base64_encode($deleteFiles[$i])); $executeList .= $itemTemplate->get(); } for ($i = 0; $i < count($quarantineFiles); $i++) { $itemTemplate->prepare(); $itemTemplate->set('PREFIX', 'q'); $itemTemplate->set('NUM', $i); $itemTemplate->set('ACTION', PS_RECIPE_ACTION_QUARANTINE); $itemTemplate->set('FILENAME', $this->getShortFilename($quarantineFiles[$i])); $itemTemplate->set('FILENAME_B64', base64_encode($quarantineFiles[$i])); $executeList .= $itemTemplate->get(); } define('PS_EXECUTE_LIST', $executeList); define('PS_EXECUTE_TOTAL_D', count($deleteFiles)); define('PS_EXECUTE_TOTAL_Q', count($quarantineFiles)); $view->display('executor_changes.tpl'); } else { if (isset($_POST['a']) && $_POST['a'] === 'apply') { $deleteTotal = (int) $_POST['total_d']; $quarantineTotal = (int) $_POST['total_q']; $deleteFiles = array(); $quarantineFiles = array(); for ($i = 0; $i < $deleteTotal; $i++) { if (!empty($_POST['d_' . $i]) && $_POST['d_' . $i] === 'on') { $deleteFiles[] = base64_decode($_POST['fn_d_' . $i]); } } for ($i = 0; $i < $quarantineTotal; $i++) { if (!empty($_POST['q_' . $i]) && $_POST['q_' . $i] === 'on') { $quarantineFiles[] = base64_decode($_POST['fn_q_' . $i]); } } $numQuarantined = 0; define('PS_EXECUTOR_LOG', $healer->executeXmlRecipe($deleteFiles, $quarantineFiles, $numQuarantined)); $quarantineUrl = $_SERVER['PHP_SELF'] . '?controller=download&f=quarantine'; define('PS_QUARANTINE_URL', $quarantineUrl); $view->display('executor_done.tpl'); } else { if (isset($_REQUEST['a']) && $_REQUEST['a'] == 'selfDelete') { global $projectRootDir, $projectTmpDir; if ($projectTmpDir == sys_get_temp_dir()) { @unlink($projectTmpDir . '/scan_log.xml'); array_map('unlink', glob($projectTmpDir . '/*.manul.tmp.txt')); array_map('unlink', glob($projectTmpDir . '/*.manul.tmp')); array_map('unlink', glob($projectTmpDir . '/config.php')); } $deleteResult = $healer->deleteDir($projectRootDir); if ($deleteResult) { print json_encode(array('result' => 'ok')); } else { print json_encode(array('result' => 'error', 'details' => $deleteResult)); } } else { $view->display('executor.tpl'); } } } }