function QCR_ScanFile($l_Filename, $i = 0) { global $g_IframerFragment, $g_Iframer, $g_Redirect, $g_Doorway, $g_EmptyLink, $g_Structure, $g_Counter, $g_HeuristicType, $g_HeuristicDetected, $g_TotalFolder, $g_TotalFiles, $g_WarningPHP, $g_AdwareList, $g_CriticalPHP, $g_Phishing, $g_CriticalJS, $g_UrlIgnoreList, $g_CriticalJSFragment, $g_PHPCodeInside, $g_PHPCodeInsideFragment, $g_NotRead, $g_WarningPHPFragment, $g_WarningPHPSig, $g_BigFiles, $g_RedirectPHPFragment, $g_EmptyLinkSrc, $g_CriticalPHPSig, $g_CriticalPHPFragment, $g_Base64Fragment, $g_UnixExec, $g_PhishingSigFragment, $g_PhishingFragment, $g_PhishingSig, $g_CriticalJSSig, $g_IframerFragment, $g_CMS, $defaults, $g_AdwareListFragment, $g_KnownList, $g_Vulnerable; global $g_CRC; static $_files_and_ignored = 0; $l_CriticalDetected = false; $l_Stat = stat($l_Filename); if (substr($l_Filename, -1) == DIR_SEPARATOR) { // FOLDER $g_Structure['n'][$i] = $l_Filename; $g_TotalFolder++; printProgress($_files_and_ignored, $l_Filename); return; } QCR_Debug('Scan file ' . $l_Filename); printProgress(++$_files_and_ignored, $l_Filename); // FILE if ((MAX_SIZE_TO_SCAN > 0 and $l_Stat['size'] > MAX_SIZE_TO_SCAN) || $l_Stat['size'] < 0) { $g_BigFiles[] = $i; AddResult($l_Filename, $i); } else { $g_TotalFiles++; $l_TSStartScan = microtime(true); if (filetype($l_Filename) == 'file') { $l_Content = @file_get_contents($l_Filename); if (SHORT_PHP_TAG) { // $l_Content = preg_replace('|<\?\s|smiS', '<?php ', $l_Content); } $l_Unwrapped = @php_strip_whitespace($l_Filename); } $l_Ext = strtolower(pathinfo($l_Filename, PATHINFO_EXTENSION)); if ($l_Content == '' && $l_Stat['size'] > 0) { $g_NotRead[] = $i; AddResult('[io] ' . $l_Filename, $i); return; } // ignore itself if (strpos($l_Content, '97ff76a1606109aee90c58f0d335abf3') !== false) { return; } // unix executables if (strpos($l_Content, chr(127) . 'ELF') !== false) { if (!in_array($l_Filename, $g_UnixExec)) { $g_UnixExec[] = $l_Filename; } return; } $g_CRC = _hash_($l_Unwrapped); $l_UnicodeContent = detect_utf_encoding($l_Content); //$l_Unwrapped = $l_Content; // check vulnerability in files $l_CriticalDetected = CheckVulnerability($l_Filename, $i, $l_Content); if ($l_UnicodeContent !== false) { if (function_exists('iconv')) { $l_Unwrapped = iconv($l_UnicodeContent, "CP1251//IGNORE", $l_Unwrapped); // if (function_exists('mb_convert_encoding')) { // $l_Unwrapped = mb_convert_encoding($l_Unwrapped, $l_UnicodeContent, "CP1251"); } else { $g_NotRead[] = $i; AddResult('[ec] ' . $l_Filename, $i); } } $l_Unwrapped = UnwrapObfu($l_Unwrapped); // critical $g_SkipNextCheck = false; if (CriticalPHP($l_Filename, $i, $l_Unwrapped, $l_Pos, $l_SigId)) { $g_CriticalPHP[] = $i; $g_CriticalPHPFragment[] = getFragment($l_Unwrapped, $l_Pos); $g_CriticalPHPSig[] = $l_SigId; $g_SkipNextCheck = true; } else { if (CriticalPHP($l_Filename, $i, $l_Content, $l_Pos, $l_SigId)) { $g_CriticalPHP[] = $i; $g_CriticalPHPFragment[] = getFragment($l_Content, $l_Pos); $g_CriticalPHPSig[] = $l_SigId; $g_SkipNextCheck = true; } } $l_TypeDe = 0; if (!$g_SkipNextCheck && HeuristicChecker($l_Content, $l_TypeDe, $l_Filename)) { $g_HeuristicDetected[] = $i; $g_HeuristicType[] = $l_TypeDe; $l_CriticalDetected = true; } // critical JS if (!$g_SkipNextCheck) { $l_Pos = CriticalJS($l_Filename, $i, $l_Unwrapped, $l_SigId); if ($l_Pos !== false) { $g_CriticalJS[] = $i; $g_CriticalJSFragment[] = getFragment($l_Unwrapped, $l_Pos); $g_CriticalJSSig[] = $l_SigId; $g_SkipNextCheck = true; } } // phishing if (!$g_SkipNextCheck) { $l_Pos = Phishing($l_Filename, $i, $l_Unwrapped, $l_SigId); if ($l_Pos !== false) { $g_Phishing[] = $i; $g_PhishingFragment[] = getFragment($l_Unwrapped, $l_Pos); $g_PhishingSigFragment[] = $l_SigId; $g_SkipNextCheck = true; } } if (!$g_SkipNextCheck) { if (SCAN_ALL_FILES || stripos($l_Filename, 'index.')) { // check iframes if (preg_match_all('|<iframe[^>]+src.+?>|smi', $l_Unwrapped, $l_Found, PREG_SET_ORDER)) { for ($kk = 0; $kk < count($l_Found); $kk++) { $l_Pos = stripos($l_Found[$kk][0], 'http://'); $l_Pos = $l_Pos || stripos($l_Found[$kk][0], 'https://'); $l_Pos = $l_Pos || stripos($l_Found[$kk][0], 'ftp://'); if ($l_Pos !== false && !knowUrl($l_Found[$kk][0])) { $g_Iframer[] = $i; $g_IframerFragment[] = getFragment($l_Found[$kk][0], $l_Pos); $l_CriticalDetected = true; } } } // check empty links if (($defaults['report_mask'] & REPORT_MASK_SPAMLINKS) == REPORT_MASK_SPAMLINKS && preg_match_all('|<a[^>]+href([^>]+?)>(.*?)</a>|smi', $l_Unwrapped, $l_Found, PREG_SET_ORDER)) { for ($kk = 0; $kk < count($l_Found); $kk++) { if (stripos($l_Found[$kk][1], 'http://') !== false && trim(strip_tags($l_Found[$kk][2])) == '') { $l_NeedToAdd = true; if (stripos($l_Found[$kk][1], $defaults['site_url']) !== false || knowUrl($l_Found[$kk][1])) { $l_NeedToAdd = false; } if ($l_NeedToAdd && count($g_EmptyLink) < MAX_EXT_LINKS) { $g_EmptyLink[] = $i; $g_EmptyLinkSrc[$i][] = substr($l_Found[$kk][0], 0, MAX_PREVIEW_LEN); $l_CriticalDetected = true; } } } } } // check for PHP code inside any type of file if (stripos($l_Ext, 'ph') === false) { $l_Pos = QCR_SearchPHP($l_Content); if ($l_Pos !== false) { $g_PHPCodeInside[] = $i; $g_PHPCodeInsideFragment[] = getFragment($l_Unwrapped, $l_Pos); $l_CriticalDetected = true; } } // htaccess if (stripos($l_Filename, '.htaccess')) { if (stripos($l_Content, 'index.php?name=$1') !== false || stripos($l_Content, 'index.php?m=1') !== false) { $g_SuspDir[] = $i; } $l_HTAContent = preg_replace('|^\\s*#.+$|m', '', $l_Content); $l_Pos = stripos($l_Content, 'auto_prepend_file'); if ($l_Pos !== false) { $g_Redirect[] = $i; $g_RedirectPHPFragment[] = getFragment($l_Content, $l_Pos); $l_CriticalDetected = true; } $l_Pos = stripos($l_Content, 'auto_append_file'); if ($l_Pos !== false) { $g_Redirect[] = $i; $g_RedirectPHPFragment[] = getFragment($l_Content, $l_Pos); $l_CriticalDetected = true; } $l_Pos = stripos($l_Content, '^(%2d|-)[^=]+$'); if ($l_Pos !== false) { $g_Redirect[] = $i; $g_RedirectPHPFragment[] = getFragment($l_Content, $l_Pos); $l_CriticalDetected = true; } if (!$l_CriticalDetected) { $l_Pos = stripos($l_Content, '%{HTTP_USER_AGENT}'); if ($l_Pos !== false) { $g_Redirect[] = $i; $g_RedirectPHPFragment[] = getFragment($l_Content, $l_Pos); $l_CriticalDetected = true; } } if (!$l_CriticalDetected) { if (preg_match_all("|RewriteRule\\s+.+?\\s+http://(.+?)/.+\\s+\\[.*R=\\d+.*\\]|smi", $l_HTAContent, $l_Found, PREG_SET_ORDER)) { $l_Host = str_replace('www.', '', $_SERVER['HTTP_HOST']); for ($j = 0; $j < sizeof($l_Found); $j++) { $l_Found[$j][1] = str_replace('www.', '', $l_Found[$j][1]); if ($l_Found[$j][1] != $l_Host) { $g_Redirect[] = $i; $l_CriticalDetected = true; break; } } } } unset($l_HTAContent); } // warnings $l_Pos = ''; if (WarningPHP($l_Filename, $l_Unwrapped, $l_Pos, $l_SigId)) { $l_Prio = 1; if (strpos($l_Filename, '.ph') !== false) { $l_Prio = 0; } $g_WarningPHP[$l_Prio][] = $i; $g_WarningPHPFragment[$l_Prio][] = getFragment($l_Unwrapped, $l_Pos); $g_WarningPHPSig[] = $l_SigId; $l_CriticalDetected = true; } // adware if (Adware($l_Filename, $l_Unwrapped, $l_Pos)) { $g_AdwareList[] = $i; $g_AdwareListFragment[] = getFragment($l_Unwrapped, $l_Pos); $l_CriticalDetected = true; } // articles if (stripos($l_Filename, 'article_index')) { $g_AdwareList[] = $i; $l_CriticalDetected = true; } } } // end of if (!$g_SkipNextCheck) { unset($l_Unwrapped); unset($l_Content); //printProgress(++$_files_and_ignored, $l_Filename); $l_TSEndScan = microtime(true); if ($l_TSEndScan - $l_TSStartScan >= 0.5) { usleep(SCAN_DELAY * 1000); } if ($g_SkipNextCheck || $l_CriticalDetected) { AddResult($l_Filename, $i); } }
function CriticalPHP($l_FN, $l_Index, $l_Content, &$l_Pos, &$l_SigId) { global $g_ExceptFlex, $gXX_FlexDBShe, $gX_FlexDBShe, $g_FlexDBShe, $gX_DBShe, $g_DBShe, $g_Base64, $g_Base64Fragment, $g_CriticalFiles, $g_CriticalEntries; // H24LKHLKJHKLHJGJG4567869869GGHJ // need check file (by extension) ? $l_SkipCheck = SMART_SCAN; if ($l_SkipCheck) { foreach ($g_CriticalFiles as $l_Ext) { if (strpos($l_FN, $l_Ext) !== false) { $l_SkipCheck = false; break; } } } // need check file (by signatures) ? if ($l_SkipCheck && preg_match('~' . $g_CriticalEntries . '~smiS', $l_Content, $l_Found)) { $l_SkipCheck = false; } if (strpos($l_FN, '.php.') !== false) { $g_Base64[] = $l_Index; $g_Base64Fragment[] = '".php."'; $l_Pos = 0; if (DEBUG_MODE) { echo "CRIT 7: {$l_FN} matched [{$l_Item}] in {$l_Pos}\n"; } AddResult($l_FN, $l_Index); } // if not critical - skip it if ($l_SkipCheck && SMART_SCAN) { if (DEBUG_MODE) { echo "Skipped file, not critical.\n"; } return false; } foreach ($g_FlexDBShe as $l_Item) { if (preg_match('#(' . $l_Item . ')#smiS', $l_Content, $l_Found, PREG_OFFSET_CAPTURE)) { if (!CheckException($l_Content, $l_Found)) { $l_Pos = $l_Found[0][1]; $l_SigId = myCheckSum($l_Item); if (DEBUG_MODE) { echo "CRIT 1: {$l_FN} matched [{$l_Item}] in {$l_Pos}\n"; } return true; } } } if (AI_EXPERT > 1) { foreach ($gXX_FlexDBShe as $l_Item) { if (preg_match('#(' . $l_Item . ')#smiS', $l_Content, $l_Found, PREG_OFFSET_CAPTURE)) { if (!CheckException($l_Content, $l_Found)) { $l_Pos = $l_Found[0][1]; $l_SigId = myCheckSum($l_Item); if (DEBUG_MODE) { echo "CRIT 2: {$l_FN} matched [{$l_Item}] in {$l_Pos}\n"; } return true; } } } } if (AI_EXPERT > 0) { foreach ($gX_FlexDBShe as $l_Item) { if (preg_match('#(' . $l_Item . ')#smiS', $l_Content, $l_Found, PREG_OFFSET_CAPTURE)) { if (!CheckException($l_Content, $l_Found)) { $l_Pos = $l_Found[0][1]; $l_SigId = myCheckSum($l_Item); if (DEBUG_MODE) { echo "CRIT 3: {$l_FN} matched [{$l_Item}] in {$l_Pos}\n"; } return true; } } } } $l_Content_lo = strtolower($l_Content); foreach ($g_DBShe as $l_Item) { $l_Pos = strpos($l_Content_lo, $l_Item); if ($l_Pos !== false) { $l_SigId = myCheckSum($l_Item); if (DEBUG_MODE) { echo "CRIT 4: {$l_FN} matched [{$l_Item}] in {$l_Pos}\n"; } return true; } } if (AI_EXPERT) { foreach ($gX_DBShe as $l_Item) { $l_Pos = strpos($l_Content_lo, $l_Item); if ($l_Pos !== false) { $l_SigId = myCheckSum($l_Item); if (DEBUG_MODE) { echo "CRIT 5: {$l_FN} matched [{$l_Item}] in {$l_Pos}\n"; } return true; } } if (strpos($l_FN, '.ph') !== false && AI_EXPERT > 1) { // for php only $g_Specials = array(');#'); foreach ($g_Specials as $l_Item) { $l_Pos = stripos($l_Content, $l_Item); if ($l_Pos !== false) { $l_SigId = myCheckSum($l_Item); return true; } } } } if (strpos($l_Content, 'GIF89') === 0 && strpos($l_FN, '.php') !== false) { $l_Pos = 0; if (DEBUG_MODE) { echo "CRIT 6: {$l_FN} matched [{$l_Item}] in {$l_Pos}\n"; } return true; } // detect uploaders / droppers if (AI_EXPERT > 1) { $l_Found = null; if (filesize($l_FN) < 1024 && strpos($l_FN, '.ph') !== false && (($l_Pos = strpos($l_Content, 'multipart/form-data')) > 0 || ($l_Pos = strpos($l_Content, '$_FILE[') > 0) || ($l_Pos = strpos($l_Content, 'move_uploaded_file')) > 0 || preg_match('|\\bcopy\\s*\\(|smi', $l_Content, $l_Found, PREG_OFFSET_CAPTURE))) { if ($l_Found != null) { $l_Pos = $l_Found[0][1]; } if (DEBUG_MODE) { echo "CRIT 7: {$l_FN} matched [{$l_Item}] in {$l_Pos}\n"; } return true; } } // count number of base64_decode entries $l_Count = substr_count($l_Content, 'base64_decode'); if ($l_Count > 10) { $g_Base64[] = $l_Index; $g_Base64Fragment[] = getFragment($l_Content, stripos($l_Content, 'base64_decode')); if (DEBUG_MODE) { echo "CRIT 10: {$l_FN} matched\n"; } AddResult($l_FN, $l_Index); } return false; }