diff --git a/src/scanner/classes/Auth.inc.php b/src/scanner/classes/Auth.inc.php index f2b53da..d829ef5 100644 --- a/src/scanner/classes/Auth.inc.php +++ b/src/scanner/classes/Auth.inc.php @@ -75,7 +75,7 @@ private function tryToAuthenticate() $passwordHashFromCookie = $_COOKIE['antimalware_password_hash']; return ($passwordHashFromCookie === $passwordHash); } elseif (!empty($_POST['password'])) { - $passwordHashFromPost = hash('sha256', $_POST['password']); + $passwordHashFromPost = $this->getHash($_POST['password']); if ($passwordHashFromPost === $passwordHash) { $this->setPasswordHashCookie($passwordHash); return true; @@ -88,12 +88,21 @@ private function tryToAuthenticate() private function setNewPassword($password) { if (!file_exists($this->passwordHashFilepath)) { - $passwordHash = hash('sha256', $password); + $passwordHash = $this->getHash($password); file_put_contents2($this->passwordHashFilepath, "\n" . $passwordHash); $this->setPasswordHashCookie($passwordHash); } } + private function getHash($text) + { + if (function_exists('hash')) { + return hash('sha256', $text); + } else { + return sha1($text); + } + } + public function auth() { $result = false; diff --git a/src/scanner/classes/FileInfo.inc.php b/src/scanner/classes/FileInfo.inc.php index ae85142..2ab90cc 100644 --- a/src/scanner/classes/FileInfo.inc.php +++ b/src/scanner/classes/FileInfo.inc.php @@ -40,7 +40,7 @@ public function getInfoByName($filePath) $this->size = filesize($filePath); if ($this->size <= $this->MAX_FILE_SIZE_FOR_HASHING) { - $this->md5 = hash_file('md5', $filePath); + $this->md5 = function_exists('hash_file') ? hash_file('md5', $filePath) : md5_file($filePath); } } } @@ -69,6 +69,18 @@ public function __toString() $data = array($this->name, $this->size, $this->ctime, $this->mtime, $this->owner, $this->group, $this->access, $this->md5); return implode(';', $data); } + + public function info() + { + $str = ''; + $fields = array('md5', 'size', 'ctime', 'mtime', 'owner', 'group', 'access'); + + foreach ($fields as $field) { + $str .= ';' . $field . '=' . $this->$field; + } + + return $str; + } } diff --git a/src/scanner/classes/FileList.inc.php b/src/scanner/classes/FileList.inc.php index bfcf049..afe91e1 100644 --- a/src/scanner/classes/FileList.inc.php +++ b/src/scanner/classes/FileList.inc.php @@ -56,14 +56,14 @@ private function fileExecutor($filePath, $type, $actionType) { if ($actionType === $this->ACTION_PROCESS) { $fileinfo = new FileInfo($filePath); - $fileinfoNode = $fileinfo->getXMLNode(); + //$fileinfoNode = $fileinfo->getXMLNode(); if ($this->GENERATE_FILE_QUEUE && is_file($fileinfo->absoluteName)) { - $queue_entry = $fileinfo->absoluteName . ' ' . $fileinfo->md5 . PHP_EOL; + $queue_entry = $fileinfo->absoluteName . ' ' . $fileinfo->info() . PHP_EOL; file_put_contents2($this->tmpQueueFilename, $queue_entry, 'a'); } - $this->dom->documentElement->appendChild($this->dom->importNode($fileinfoNode, true)); + //$this->dom->documentElement->appendChild($this->dom->importNode($fileinfoNode, true)); $this->filesFound++; } else if ($actionType === $this->ACTION_SKIP) { // TODO: Do something with skipped item @@ -73,7 +73,7 @@ private function fileExecutor($filePath, $type, $actionType) public function getXMLFilelist() { - $result = implode('', file($this->AJAX_TMP_FILE)); + $result = ''; $this->cleanUp(); return $result; diff --git a/src/scanner/classes/MalwareDetector.inc.php b/src/scanner/classes/MalwareDetector.inc.php index 3afea64..929285c 100644 --- a/src/scanner/classes/MalwareDetector.inc.php +++ b/src/scanner/classes/MalwareDetector.inc.php @@ -137,7 +137,7 @@ function detectMalware($filePath, &$foundFragment, &$pos, $startTime, $timeout, } } - $content = implode('', file($filePath)); + $content = file_get_contents($filePath); $fileToBeScannedSignatureList = array( 'openMemory(); + $xml->setIndent(true); + $xml->startDocument('1.0', 'utf-8'); + $xml->startElement('website_info'); - $xmlLogFilename = $this->XML_LOG_FILENAME; - $xml = $this->parseXml($xmlLogFilename); - $xpath = new DOMXpath($xml); + $dom = $this->parseXml($this->XML_LOG_FILENAME); - if (!is_file($this->MALWARE_LOG_FILENAME)) { - die(basename(__FILE__) . ': cannot open ' . $this->MALWARE_LOG_FILENAME . ' during repacking'); - } + $xml->writeRaw($dom->saveXML($dom->getElementsByTagName('server_environment')->item(0))); + $xml->writeRaw($dom->saveXML($dom->getElementsByTagName('cms_list')->item(0))); - $lines = file($this->MALWARE_LOG_FILENAME); + $xml->startElement('files'); - foreach ($lines as $lineNum => $line) { - #Example /home/www/badcode.tk/web_root/robots.txt.dist;detected=;pos=-1;snippet= - $data = explode(';', $line); - $filePath = $data[0]; - $detected = substr($data[1], strlen('detected=')); - if ($detected) { - $pos = substr($data[2], strlen('pos=')); - $snippet = trim(substr($data[3], strlen('snippet='))); + file_put_contents2($this->XML_LOG_FILENAME, $xml->flush()); - #Getting current element in DOM - $relativePath = str_replace($_SERVER['DOCUMENT_ROOT'], '.', $filePath); - $filePathNode = $xpath->query('/website_info/files/file/path[text()="' . $relativePath . '"]')->item(0); - $fileinfoNode = $filePathNode->parentNode; + $file = new SplFileObject($this->MALWARE_LOG_FILENAME); + $file->setFlags(SplFileObject::DROP_NEW_LINE); - if (!$fileinfoNode) { - die("XML path error filePath={$filePath} relativePath={$relativePath} projectRootDir={$projectRootDir} docRoot={$_SERVER['DOCUMENT_ROOT']}"); - } + $buffer = ''; - #Adding detection info to DOM - if ($fileinfoNode) { - $fileinfoNode->setAttribute('detected', $detected); - $fileinfoNode->setAttribute('snippet', $snippet); - $fileinfoNode->setAttribute('pos', $pos); - } + foreach ($file as $line) { + #Example /home/www/badcode.tk/web_root/robots.txt.dist ;md5=6e2807094b485c6fdf1fda4862bac22d;size=497;ctime=1436097435;mtime=1320843774;owner=lol;group=users;access=0755;detected=;pos=-1;snippet= + if (empty($line)) continue; + + $p = strrpos($line, ' '); + $filePath = substr($line, 0, $p); + $fileInfo = substr($line, $p + 1); + + preg_match_all('@;(\w+)=([^;]*)@', $fileInfo, $matches); + + $data = array_combine($matches[1], $matches[2]); + $data['path'] = str_replace($_SERVER['DOCUMENT_ROOT'], '.', $filePath); + + $xml->startElement('file'); + + if ($data['detected']) { + $xml->writeAttribute('detected', $data['detected']); + $xml->writeAttribute('snippet', $data['snippet']); + $xml->writeAttribute('pos', $data['pos']); + } + + $fields = array('path', 'size', 'ctime', 'mtime', 'owner', 'group', 'access', 'md5'); + + foreach ($fields as $field) { + $xml->writeElement($field, $data[$field]); + } + + $xml->endElement(); + + $buffer .= $xml->flush(); + + if (32000 < strlen($buffer)) { + file_put_contents2($this->XML_LOG_FILENAME, $buffer, 'a'); + $buffer = ''; } } - $xml->save($xmlLogFilename); + $xml->endElement(); + $xml->endDocument(); - return $xml->saveXML(); + $buffer .= $xml->flush(); + + file_put_contents2($this->XML_LOG_FILENAME, $buffer, 'a'); } function buildQuarantineArchive() @@ -339,9 +360,12 @@ function malwareScanRound() $fh = fopen($this->QUEUE_FILENAME, 'r'); $offset = 0; + $numFilesScanned = 0; if (file_exists($this->QUEUE_OFFSET_FILENAME)) { - $offset = (int)file_get_contents($this->QUEUE_OFFSET_FILENAME); + $o = explode(' ', file_get_contents($this->QUEUE_OFFSET_FILENAME)); + $offset = (int) $o[0]; + $numFilesScanned = (int) $o[1]; fseek($fh, $offset); } @@ -351,9 +375,8 @@ function malwareScanRound() } $queueText = fread($fh, filesize($this->QUEUE_FILENAME) - $offset); - $queueLines = explode("\n", $queueText); - - $numFilesScanned = 0; + $queueLines = explode(PHP_EOL, $queueText, -1); + $numFilesLeft = count($queueLines); if (count($queueLines) < 1) { fclose($fh); @@ -370,15 +393,17 @@ function malwareScanRound() $offset += strlen($line) + 1; - $fileinfo = explode(' ', $line); + $p = strrpos($line, ' '); - $filePath = $fileinfo[0]; - $fileHash = $fileinfo[1]; + $filePath = substr($line, 0, $p); + $fileInfo = substr($line, $p + 1); $snippet = ''; $fileExtension = pathinfo(basename($filePath), PATHINFO_EXTENSION); $res = $this->detectMalware($filePath, $snippet, $pos, $this->SCRIPT_START, $this->MAX_EXECUTION_DURATION, $fileExtension); + $numFilesScanned++; + $numFilesLeft--; switch ($res) { case 'no_need_to_check': break; @@ -387,12 +412,11 @@ function malwareScanRound() case 'skipped': break; case 'timeout': - file_put_contents2($this->QUEUE_OFFSET_FILENAME, $offset); + file_put_contents2($this->QUEUE_OFFSET_FILENAME, $offset . ' ' . $numFilesScanned); $this->throwTimeout($filePath); break; default: - $numFilesScanned++; - $content = $filePath . ';detected=' . $res . ';pos=' . $pos . ';snippet=' . base64_encode($snippet) . PHP_EOL; + $content = $filePath . ' ' . $fileInfo . ';detected=' . $res . ';pos=' . $pos . ';snippet=' . base64_encode($snippet) . PHP_EOL; file_put_contents2($this->MALWARE_LOG_FILENAME, $content, 'a'); if ($res) { @@ -401,14 +425,14 @@ function malwareScanRound() } } - file_put_contents2($this->QUEUE_OFFSET_FILENAME, $offset); + file_put_contents2($this->QUEUE_OFFSET_FILENAME, $offset . ' ' . $numFilesScanned); fclose($fh); if (count($queueLines) <= 1) { return $this->finishMalwareScan(); } - $data = array('filesScannedThisTime' => $numFilesScanned, 'filesLeft' => count($queueLines), 'lastFile' => $filePath); + $data = array('filesScannedThisTime' => $numFilesScanned, 'filesLeft' => $numFilesLeft, 'lastFile' => $filePath); $result = json_encode(array('type' => 'getSignatureScanResult', 'status' => 'inProcess', 'data' => $data, 'phpError' => $php_errormsg)); return $result; diff --git a/src/scanner/static/js/common.js b/src/scanner/static/js/common.js index b18072b..e6cc447 100644 --- a/src/scanner/static/js/common.js +++ b/src/scanner/static/js/common.js @@ -85,12 +85,11 @@ $(document).ready(function(){ if (response.status == 'inProcess') { lastScannedFile = response.data.lastFile; - numberFilesScannedThisTime = parseInt(response.data.filesScannedThisTime) + numberFilesScanned = parseInt(response.data.filesScannedThisTime) numberFilesLeft = parseInt(response.data.filesLeft) - numberFilesScanned += numberFilesScannedThisTime; if (!numberFilesToScan) { - numberFilesToScan = numberFilesLeft + numberFilesScannedThisTime; + numberFilesToScan = numberFilesLeft + numberFilesScanned; } signatureScanProgress = numberFilesScanned * 100 / numberFilesToScan;