shSecEnableSecurity) { return ''; } $shQuery = empty($query) ? (empty($_SERVER['QUERY_STRING']) ? '' : $_SERVER['QUERY_STRING']) : $query; // IP checks $ip = ShlSystem_Http::getVisitorIpAddress(); $uAgent = empty($_SERVER['HTTP_USER_AGENT']) ? '' : $_SERVER['HTTP_USER_AGENT']; // ip White/Black listing $shWhiteListedIp = shCheckIPList($ip, $sefConfig->ipWhiteList); if (!$shWhiteListedIp) { if (shCheckIPList($ip, $sefConfig->ipBlackList)) { shDoRestrictedAccess('Blacklisted IP'); } } // UserAgent White/Black listing $whiteListedUAgent = shCheckUAgentList($uAgent, $sefConfig->uAgentWhiteList); if (!$whiteListedUAgent) { if (shCheckUAgentList($uAgent, $sefConfig->uAgentBlackList)) { shDoRestrictedAccess('Blacklisted user agent'); } } if (!$shWhiteListedIp && !$whiteListedUAgent && $fullCheck) { shDoAntiFloodCheck($ip); } // url content checks $halt = 0; while (true) { // allow for multiple url decode $last = $shQuery; $shQuery = urldecode($shQuery); // do our tests $shQuery = str_replace('&', '&', $shQuery); // bad content in query string $c = shCheckConfigVars($shQuery); if ($c) { shDoRestrictedAccess($c . ' in URL'); } $c = shCheckBase64($shQuery); if ($c) { shDoRestrictedAccess($c . ' in URL'); } $c = shCheckScripts($shQuery); if ($c) { shDoRestrictedAccess($c . ' in URL'); } $c = shCheckStandardVars($_GET); if ($c) { shDoRestrictedAccess($c . ' in URL'); } $c = shCheckImgTxtCmd($shQuery); // V x if ($c) { shDoRestrictedAccess($c . ' in URL'); } // Check whether the last decode is equal to the previous one if ($shQuery == $last) { // Break out of the while if the URI is stable. break; } else { if (++$halt > 10) { // Runaway check. URI has been seriously compromised. shDoRestrictedAccess('Multiple level of url encode'); } } } if (!$fullCheck) { return; } // don't check POST and/or Honey pot if second check // check POST variables if ($sefConfig->shSecCheckPOSTData) { $c = shCheckStandardVars($_POST); if ($c) { shDoRestrictedAccess($c . ' in POST'); } foreach ($_POST as $key => $value) { if (!is_array($value)) { shDoPOSTCheck($key, $value); } else { foreach ($value as $subKey => $subValue) { if (!is_array($subValue)) { shDoPOSTCheck($subKey, $subValue); } } } } } // do Project Honey Pot check if (!$shWhiteListedIp && $sefConfig->shSecCheckHoneyPot) { shDoHoneyPotCheck($ip); } } function shDoPOSTCheck($key, $value) { $c = shCheckConfigVars($key . '=' . $value); if ($c) { shDoRestrictedAccess($c . ' in POST'); } $c = shCheckBase64($key . '=' . $value); if ($c) { shDoRestrictedAccess($c . ' in POST'); } $c = shCheckScripts($key . '=' . $value); if ($c) { shDoRestrictedAccess($c . ' in POST'); } $c = shCheckImgTxtCmd($key . '=' . $value); // V x if ($c) { shDoRestrictedAccess($c . ' in POST'); } } function shSendEmailToAdmin($logData) { if (!sh404SEF_SEC_MAIL_ATTACKS_TO_ADMIN) { return; } $mainframe = JFactory::getApplication(); $subject = str_replace('%sh404SEF_404_SITE_NAME%', $mainframe->getCfg('sitename'), sh404SEF_SEC_EMAIL_TO_ADMIN_SUBJECT); $logText = ''; foreach ($logData as $key => $text) { $logText .= "\n" . $key . "\t\t" . ' :: ' . shSecOutput(JString::trim($text)); } $body = str_replace('%sh404SEF_404_SITE_URL%', Sh404sefFactory::getPageInfo()->getDefaultFrontLiveSite(), sh404SEF_SEC_EMAIL_TO_ADMIN_BODY); $body = str_replace('%sh404SEF_404_ATTACK_DETAILS%', $logText, $body); if (!defined('_ISO')) { define('_ISO', 'charset=iso-8859-1'); } jimport('joomla.mail.mail'); JMail::sendMail($mainframe->getCfg('mailfrom'), $mainframe->getCfg('fromname'), $mainframe->getCfg('mailfrom'), $subject, $body); } function shLogToSecFile($logData) { $shNum = 12 * (intval(date('Y')) - 2000) + intval(date('m')); // number current month $fileName = 'sh404sef/sec/log_' . date('Y') . '-' . date('m') . '-' . 'sh404SEF_security_log' . '.' . $shNum . '.log.php'; $options = array( 'text_entry_format' => "{DATE}\t{TIME}\t{CAUSE}\t{C-IP}\t{USER}\t{USER_AGENT}\t{REQUEST_METHOD}\t{REQUEST_URI}\t{COMMENT}", 'text_file' => $fileName ); jimport('joomla.error.log'); JLog::addLogger($options, JLog::INFO, array('sh404sef_sec')); $entry = new JLogEntry(''); foreach ($logData as $key => $value) { $entry->$key = $value; } $entry->category = 'sh404sef_sec'; // and add it JLog::add($entry, JLog::INFO, 'sh404sef_sec'); } function shCleanUpSecLogFiles() { // delete security log files older than param $sefConfig = Sh404sefFactory::getConfig(); if (mt_rand(1, SH404SEF_PAGES_TO_CLEAN_LOGS) != 1) { return; } // probability = 1/SH404SEF_PAGES_TO_CLEAN_LOGS $curMonth = 12 * (intval(date('Y')) - 2000) + intval(date('m')); $logsPath = JFactory::getApplication()->get('log_path', JPATH_ADMINISTRATOR . '/logs'); if ($sefConfig->shSecLogAttacks) { if ($handle = @opendir($logsPath . '/sh404sef/sec')) { while (false !== ($file = readdir($handle))) { $matches = array(); if ($file != '.' && $file != '..' && preg_match('/\.[0-9]*\./', $file, $matches)) { $fileNum = JString::trim($matches[0], '.'); if ($curMonth - $fileNum > $sefConfig->monthsToKeepLogs) { @unlink($logsPath . '/sh404sef/sec/' . $file); ShlSystem_Log::debug('sh404sef', 'Erasing security log file : ' . $logsPath . '/sh404sef/sec/' . $file); } } } closedir($handle); } } } function shDoRestrictedAccess($causeText, $comment = '', $displayEntrance = false) { $sefConfig = Sh404sefFactory::getConfig(); if ($sefConfig->shSecLogAttacks) { // log what's happening $logData = array(); $logData['DATE'] = ShlSystem_Date::getSiteNow('Y-m-d'); $logData['TIME'] = ShlSystem_Date::getSiteNow('H:i:s'); $logData['CAUSE'] = shSecOutput($causeText); $logData['C-IP'] = empty($_SERVER['REMOTE_ADDR']) ? '-' : $_SERVER['REMOTE_ADDR']; if (!empty($logData['C-IP']) && $logData['C-IP'] != 'localhost' && $logData['C-IP'] != '::1') { //$name = getHostByAddr($_SERVER['REMOTE_ADDR']); $name = '-'; } else { $name = '-'; } $logData['NAME'] = $name; $logData['USER_AGENT'] = empty($_SERVER['HTTP_USER_AGENT']) ? '-' : $_SERVER['HTTP_USER_AGENT']; $logData['REQUEST_METHOD'] = $_SERVER['REQUEST_METHOD']; $logData['REQUEST_URI'] = $_SERVER['REQUEST_URI']; $logData['COMMENT'] = $comment; shLogToSecFile($logData); // V x : we can possibly send email to site admin, but not log shSendEmailToAdmin($logData); } // actually restrict access if (!headers_sent()) { header('HTTP/1.0 403 FORBIDDEN'); } echo '

Forbidden access

'; if ($displayEntrance) { ?> shSecEntranceText; ?> >>>>>>




shSecSmellyPotText; ?>>>

(' . $causeText . ')

'; } JFactory::getApplication()->close(403); } function shCheckConfigVars($query) { if (empty($query)) { return ''; } if (preg_match('~mosConfig_[a-zA-Z_]{1,21}=~iu', $query)) { return 'mosConfig_var'; } else { return ''; } } function shCheckBase64($query) { if (empty($query)) { return ''; } if (preg_match('~base64_encode.*\(.*\)~iu', $query)) { return 'Base 64 encoded data'; } else { return ''; } } function shCheckScripts($query) { if (empty($query)) { return ''; } if (preg_match('~(\<).*script[^A-Za-z0-9]*(\>)~iu', $query)) { return '