Exemple #1
0
 public function onAfterInitialise()
 {
     $ip = AtsystemUtilFilter::getIp();
     $continents = $this->cparams->getValue('geoblockcontinents', '');
     $continents = empty($continents) ? array() : explode(',', $continents);
     $countries = $this->cparams->getValue('geoblockcountries', '');
     $countries = empty($countries) ? array() : explode(',', $countries);
     $geoip = new AkeebaGeoipProvider();
     $country = $geoip->getCountryCode($ip);
     $continent = $geoip->getContinent($ip);
     if (empty($country)) {
         $country = '(unknown country)';
     }
     if (empty($continent)) {
         $continent = '(unknown continent)';
     }
     if ($continent && !empty($continents) && in_array($continent, $continents)) {
         $extraInfo = 'Continent : ' . $continent;
         $this->exceptionsHandler->blockRequest('geoblocking', null, $extraInfo);
     }
     if ($country && !empty($countries) && in_array($country, $countries)) {
         $extraInfo = 'Country : ' . $country;
         $this->exceptionsHandler->blockRequest('geoblocking', null, $extraInfo);
     }
 }
 /**
  * Sends an email upon accessing an administrator page other than the login screen
  */
 public function onAfterInitialise()
 {
     $user = JFactory::getUser();
     // Check if the session flag is set (avoid sending thousands of emails!)
     $session = JFactory::getSession();
     $flag = $session->get('waf.loggedin', 0, 'plg_admintools');
     if ($flag == 1) {
         return;
     }
     // Load the component's administrator translation files
     $jlang = JFactory::getLanguage();
     $jlang->load('com_admintools', JPATH_ADMINISTRATOR, 'en-GB', true);
     $jlang->load('com_admintools', JPATH_ADMINISTRATOR, $jlang->getDefault(), true);
     $jlang->load('com_admintools', JPATH_ADMINISTRATOR, null, true);
     // Get the username
     $username = $user->username;
     // Get the site name
     $config = JFactory::getConfig();
     if (version_compare(JVERSION, '3.0', 'ge')) {
         $sitename = $config->get('sitename');
     } else {
         $sitename = $config->getValue('config.sitename');
     }
     // Get the IP address
     $ip = AtsystemUtilFilter::getIp();
     if (strpos($ip, '::') === 0 && strstr($ip, '.') !== false) {
         $ip = substr($ip, strrpos($ip, ':') + 1);
     }
     $country = '';
     $continent = '';
     if (class_exists('AkeebaGeoipProvider')) {
         $geoip = new AkeebaGeoipProvider();
         $country = $geoip->getCountryCode($ip);
         $continent = $geoip->getContinent($ip);
     }
     if (empty($country)) {
         $country = '(unknown country)';
     }
     if (empty($continent)) {
         $continent = '(unknown continent)';
     }
     // Construct the replacement table
     $substitutions = array('[SITENAME]' => $sitename, '[USERNAME]' => $username, '[IP]' => $ip, '[UASTRING]' => $_SERVER['HTTP_USER_AGENT'], '[COUNTRY]' => $country, '[CONTINENT]' => $continent);
     $subject = JText::_('ATOOLS_LBL_WAF_EMAILADMINLOGIN_SUBJECT_21');
     $body = JText::_('ATOOLS_LBL_WAF_EMAILADMINLOGIN_BODY_21');
     foreach ($substitutions as $k => $v) {
         $subject = str_replace($k, $v, $subject);
         $body = str_replace($k, $v, $body);
     }
     // Send the email
     $mailer = JFactory::getMailer();
     $mailfrom = $config->get('mailfrom');
     $fromname = $config->get('fromname');
     $recipients = explode(',', $this->cparams->getValue('emailonadminlogin', ''));
     $recipients = array_map('trim', $recipients);
     foreach ($recipients as $recipient) {
         $mailer->setSender(array($mailfrom, $fromname));
         $mailer->addRecipient($recipient);
         $mailer->setSubject($subject);
         $mailer->setBody($body);
         $mailer->Send();
     }
     // Set the flag to prevent sending more emails
     $session->set('waf.loggedin', 1, 'plg_admintools');
 }
Exemple #3
0
 /**
  * Checks if an IP address should be automatically banned for raising too many security exceptions over a predefined
  * time period.
  *
  * @param   string $reason The reason of the ban
  *
  * @return  void
  */
 public function autoBan($reason = 'other')
 {
     // We need to be able to get our own IP, right?
     if (!function_exists('inet_pton')) {
         return;
     }
     // Get the IP
     $ip = AtsystemUtilFilter::getIp();
     // No point continuing if we can't get an address, right?
     if (empty($ip) || $ip == '0.0.0.0') {
         return;
     }
     // Check for repeat offenses
     $db = JFactory::getDBO();
     $strikes = $this->cparams->getValue('tsrstrikes', 3);
     $numfreq = $this->cparams->getValue('tsrnumfreq', 1);
     $frequency = $this->cparams->getValue('tsrfrequency', 'hour');
     $mindatestamp = 0;
     switch ($frequency) {
         case 'second':
             break;
         case 'minute':
             $numfreq *= 60;
             break;
         case 'hour':
             $numfreq *= 3600;
             break;
         case 'day':
             $numfreq *= 86400;
             break;
         case 'ever':
             $mindatestamp = 946706400;
             // January 1st, 2000
             break;
     }
     JLoader::import('joomla.utilities.date');
     $jNow = new JDate();
     if ($mindatestamp == 0) {
         $mindatestamp = $jNow->toUnix() - $numfreq;
     }
     $jMinDate = new JDate($mindatestamp);
     $minDate = $jMinDate->toSql();
     $sql = $db->getQuery(true)->select('COUNT(*)')->from($db->qn('#__admintools_log'))->where($db->qn('logdate') . ' >= ' . $db->q($minDate))->where($db->qn('ip') . ' = ' . $db->q($ip));
     $db->setQuery($sql);
     try {
         $numOffenses = $db->loadResult();
     } catch (Exception $e) {
         $numOffenses = 0;
     }
     if ($numOffenses < $strikes) {
         return;
     }
     // Block the IP
     $myIP = @inet_pton($ip);
     if ($myIP === false) {
         return;
     }
     $myIP = inet_ntop($myIP);
     $until = $jNow->toUnix();
     $numfreq = $this->cparams->getValue('tsrbannum', 1);
     $frequency = $this->cparams->getValue('tsrbanfrequency', 'hour');
     switch ($frequency) {
         case 'second':
             $until += $numfreq;
             break;
         case 'minute':
             $numfreq *= 60;
             $until += $numfreq;
             break;
         case 'hour':
             $numfreq *= 3600;
             $until += $numfreq;
             break;
         case 'day':
             $numfreq *= 86400;
             $until += $numfreq;
             break;
         case 'ever':
             $until = 2145938400;
             // January 1st, 2038 (mind you, UNIX epoch runs out on January 19, 2038!)
             break;
     }
     JLoader::import('joomla.utilities.date');
     $jMinDate = new JDate($until);
     $minDate = $jMinDate->toSql();
     $record = (object) array('ip' => $myIP, 'reason' => $reason, 'until' => $minDate);
     // If I'm here it means that we have to ban the user. Let's see if this is a simple autoban or
     // we have to issue a permaban as a result of several attacks
     if ($this->cparams->getValue('permaban', 0)) {
         // Ok I have to check the number of autoban
         $query = $db->getQuery(true)->select('COUNT(*)')->from($db->qn('#__admintools_ipautobanhistory'))->where($db->qn('ip') . ' = ' . $db->q($myIP));
         try {
             $bans = $db->setQuery($query)->loadResult();
         } catch (Exception $e) {
             $bans = 0;
         }
         $limit = (int) $this->cparams->getValue('permabannum', 0);
         if ($limit && $bans >= $limit) {
             $block = (object) array('ip' => $myIP, 'description' => 'IP automatically blocked after being banned automatically ' . $bans . ' times');
             $db->insertObject('#__admintools_ipblock', $block);
         }
     }
     $db->insertObject('#__admintools_ipautoban', $record);
     // Send an optional email
     if ($this->cparams->getValue('emailafteripautoban', '')) {
         // Load the component's administrator translation files
         $jlang = JFactory::getLanguage();
         $jlang->load('com_admintools', JPATH_ADMINISTRATOR, 'en-GB', true);
         $jlang->load('com_admintools', JPATH_ADMINISTRATOR, $jlang->getDefault(), true);
         $jlang->load('com_admintools', JPATH_ADMINISTRATOR, null, true);
         // Get the site name
         $config = JFactory::getConfig();
         $sitename = $config->get('sitename');
         $country = '';
         $continent = '';
         if (class_exists('AkeebaGeoipProvider')) {
             $geoip = new AkeebaGeoipProvider();
             $country = $geoip->getCountryCode($ip);
             $continent = $geoip->getContinent($ip);
         }
         if (empty($country)) {
             $country = '(unknown country)';
         }
         if (empty($continent)) {
             $continent = '(unknown continent)';
         }
         $uri = JURI::getInstance();
         $url = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port', 'path', 'query', 'fragment'));
         $ip_link = $this->cparams->getValue('iplookupscheme', 'http') . '://' . $this->cparams->getValue('iplookup', 'ip-lookup.net/index.php?ip={ip}');
         $ip_link = str_replace('{ip}', $ip, $ip_link);
         $substitutions = array('[SITENAME]' => $sitename, '[REASON]' => JText::_('COM_ADMINTOOLS_EMAILTEMPLATE_REASON_IPAUTOBAN'), '[DATE]' => gmdate('Y-m-d H:i:s') . " GMT", '[URL]' => $url, '[USER]' => '', '[IP]' => $ip, '[LOOKUP]' => '<a href="' . $ip_link . '">IP Lookup</a>', '[COUNTRY]' => $country, '[CONTINENT]' => $continent, '[UA]' => $_SERVER['HTTP_USER_AGENT'], '[UNTIL]' => $minDate);
         // Load the component's administrator translation files
         $jlang = JFactory::getLanguage();
         $jlang->load('com_admintools', JPATH_ADMINISTRATOR, 'en-GB', true);
         $jlang->load('com_admintools', JPATH_ADMINISTRATOR, $jlang->getDefault(), true);
         $jlang->load('com_admintools', JPATH_ADMINISTRATOR, null, true);
         // Let's get the most suitable email template
         $template = $this->getEmailTemplate('ipautoban');
         // Got no template, the user didn't published any email template, or the template doesn't want us to
         // send a notification email. Anyway, let's stop here.
         if (!$template) {
             return;
         } else {
             $subject = $template[0];
             $body = $template[1];
         }
         foreach ($substitutions as $k => $v) {
             $subject = str_replace($k, $v, $subject);
             $body = str_replace($k, $v, $body);
         }
         // Send the email
         $mailer = JFactory::getMailer();
         $mailfrom = $config->get('mailfrom');
         $fromname = $config->get('fromname');
         $mailer->isHtml(true);
         $mailer->setSender(array($mailfrom, $fromname));
         $mailer->addRecipient($this->cparams->getValue('emailafteripautoban', ''));
         $mailer->setSubject($subject);
         $mailer->setBody($body);
         $mailer->Send();
     }
 }
 /**
  * Logs security exceptions
  *
  * @param string $reason                   Block reason code
  * @param string $extraLogInformation      Extra information to be written to the text log file
  * @param string $extraLogTableInformation Extra information to be written to the extradata field of the log table (useful for JSON format)
  *
  * @return bool
  */
 public function logBreaches($reason, $extraLogInformation = '', $extraLogTableInformation = '')
 {
     $reasons_nolog = $this->cparams->getValue('reasons_nolog', 'geoblocking');
     $reasons_noemail = $this->cparams->getValue('reasons_noemail', 'geoblocking');
     $whitelist_domains = $this->cparams->getValue('whitelist_domains', '.googlebot.com,.search.msn.com');
     $reasons_nolog = explode(',', $reasons_nolog);
     $reasons_noemail = explode(',', $reasons_noemail);
     $whitelist_domains = explode(',', $whitelist_domains);
     // === SANITY CHECK - BEGIN ===
     // Get our IP address
     $ip = AtsystemUtilFilter::getIp();
     if (strpos($ip, '::') === 0 && strstr($ip, '.') !== false) {
         $ip = substr($ip, strrpos($ip, ':') + 1);
     }
     // No point continuing if we can't get an address, right?
     if (empty($ip) || $ip == '0.0.0.0') {
         return false;
     }
     // Make sure it's not an IP in the safe list
     $safeIPs = $this->cparams->getValue('neverblockips', '');
     if (!empty($safeIPs)) {
         $safeIPs = explode(',', $safeIPs);
         if (!empty($safeIPs)) {
             if (AtsystemUtilFilter::IPinList($safeIPs)) {
                 return false;
             }
         }
     }
     // Make sure we don't have a list in the administrator white list
     if ($this->cparams->getValue('ipwl', 0) == 1) {
         $db = JFactory::getDBO();
         $sql = $db->getQuery(true)->select($db->qn('ip'))->from($db->qn('#__admintools_adminiplist'));
         $db->setQuery($sql);
         try {
             if (version_compare(JVERSION, '3.0', 'ge')) {
                 $ipTable = $db->loadColumn();
             } else {
                 $ipTable = $db->loadResultArray();
             }
         } catch (Exception $e) {
             $ipTable = null;
         }
         if (!empty($ipTable)) {
             if (AtsystemUtilFilter::IPinList($ipTable)) {
                 return false;
             }
         }
     }
     // Make sure this IP doesn't resolve to a whitelisted domain
     if (!empty($whitelist_domains)) {
         $remote_domain = @gethostbyaddr($ip);
         if (!empty($remote_domain)) {
             foreach ($whitelist_domains as $domain) {
                 $domain = trim($domain);
                 if (strrpos($remote_domain, $domain) !== false) {
                     return true;
                 }
             }
         }
     }
     // === SANITY CHECK - END ===
     // DO I have any kind of log? Let's get some extra info
     if ($this->cparams->getValue('logbreaches', 0) && !in_array($reason, $reasons_nolog) || $this->cparams->getValue('emailbreaches', '') && !in_array($reason, $reasons_noemail)) {
         $uri = JURI::getInstance();
         $url = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port', 'path', 'query', 'fragment'));
         JLoader::import('joomla.utilities.date');
         $date = new JDate();
         $user = JFactory::getUser();
         if ($user->guest) {
             $username = '******';
         } else {
             $username = $user->username . ' (' . $user->name . ' <' . $user->email . '>)';
         }
         $country = '';
         $continent = '';
         if (class_exists('AkeebaGeoipProvider')) {
             $geoip = new AkeebaGeoipProvider();
             $country = $geoip->getCountryCode($ip);
             $continent = $geoip->getContinent($ip);
         }
         if (empty($country)) {
             $country = '(unknown country)';
         }
         if (empty($continent)) {
             $continent = '(unknown continent)';
         }
     }
     if ($this->cparams->getValue('logbreaches', 0) && !in_array($reason, $reasons_nolog)) {
         // Logging to file
         $config = JFactory::getConfig();
         if (version_compare(JVERSION, '3.0', 'ge')) {
             $logpath = $config->get('log_path');
         } else {
             $logpath = $config->getValue('log_path');
         }
         $fname = $logpath . DIRECTORY_SEPARATOR . 'admintools_breaches.log';
         // -- Check the file size. If it's over 1Mb, archive and start a new log.
         if (@file_exists($fname)) {
             $fsize = filesize($fname);
             if ($fsize > 1048756) {
                 if (@file_exists($fname . '.1')) {
                     unlink($fname . '.1');
                 }
                 @copy($fname, $fname . '.1');
                 @unlink($fname);
             }
         }
         // -- Log the exception
         $fp = @fopen($fname, 'at');
         if ($fp !== false) {
             fwrite($fp, str_repeat('-', 79) . "\n");
             fwrite($fp, "Blocking reason: " . $reason . "\n" . str_repeat('-', 79) . "\n");
             fwrite($fp, 'Date/time : ' . gmdate('Y-m-d H:i:s') . " GMT\n");
             fwrite($fp, 'URL       : ' . $url . "\n");
             fwrite($fp, 'User      : '******'IP        : ' . $ip . "\n");
             fwrite($fp, 'Country   : ' . $country . "\n");
             fwrite($fp, 'Continent : ' . $continent . "\n");
             fwrite($fp, 'UA        : ' . $_SERVER['HTTP_USER_AGENT'] . "\n");
             if (!empty($extraLogInformation)) {
                 fwrite($fp, $extraLogInformation . "\n");
             }
             fwrite($fp, "\n\n");
             fclose($fp);
         }
         // ...and write a record to the log table
         $db = JFactory::getDBO();
         $logEntry = (object) array('logdate' => $date->toSql(), 'ip' => $ip, 'url' => $url, 'reason' => $reason, 'extradata' => $extraLogTableInformation);
         try {
             $db->insertObject('#__admintools_log', $logEntry);
         } catch (Exception $e) {
             // Do nothing if the query fails
         }
     }
     $emailbreaches = $this->cparams->getValue('emailbreaches', '');
     if (!empty($emailbreaches) && !in_array($reason, $reasons_noemail)) {
         // Load the component's administrator translation files
         $jlang = JFactory::getLanguage();
         $jlang->load('com_admintools', JPATH_ADMINISTRATOR, 'en-GB', true);
         $jlang->load('com_admintools', JPATH_ADMINISTRATOR, $jlang->getDefault(), true);
         $jlang->load('com_admintools', JPATH_ADMINISTRATOR, null, true);
         // Get the site name
         $config = JFactory::getConfig();
         if (version_compare(JVERSION, '3.0', 'ge')) {
             $sitename = $config->get('sitename');
         } else {
             $sitename = $config->getValue('config.sitename');
         }
         // Create a link to lookup the IP
         $ip_link = $this->cparams->getValue('iplookupscheme', 'http') . '://' . $this->cparams->getValue('iplookup', 'ip-lookup.net/index.php?ip={ip}');
         $ip_link = str_replace('{ip}', $ip, $ip_link);
         // Get the reason in human readable format
         $txtReason = JText::_('ATOOLS_LBL_REASON_' . strtoupper($reason));
         // Get extra information
         if ($extraLogTableInformation) {
             list($logReason, ) = explode('|', $extraLogTableInformation);
             $txtReason .= " ({$logReason})";
         }
         // Send the email
         $mailer = JFactory::getMailer();
         if (version_compare(JVERSION, '3.0', 'ge')) {
             $mailfrom = $config->get('mailfrom');
             $fromname = $config->get('fromname');
         } else {
             $mailfrom = $config->getValue('config.mailfrom');
             $fromname = $config->getValue('config.fromname');
         }
         // Let's get the most suitable email template
         $template = $this->getEmailTemplate($reason);
         // Got no template, the user didn't published any email template, or the template doesn't want us to
         // send a notification email. Anyway, let's stop here
         if (!$template) {
             return true;
         } else {
             $subject = $template[0];
             $body = $template[1];
         }
         $tokens = array('[SITENAME]' => $sitename, '[REASON]' => $txtReason, '[DATE]' => gmdate('Y-m-d H:i:s') . " GMT", '[URL]' => $url, '[USER]' => $username, '[IP]' => $ip, '[LOOKUP]' => '<a href="' . $ip_link . '">IP Lookup</a>', '[COUNTRY]' => $country, '[CONTINENT]' => $continent, '[UA]' => $_SERVER['HTTP_USER_AGENT']);
         $subject = str_replace(array_keys($tokens), array_values($tokens), $subject);
         $body = str_replace(array_keys($tokens), array_values($tokens), $body);
         $recipients = explode(',', $emailbreaches);
         $recipients = array_map('trim', $recipients);
         foreach ($recipients as $recipient) {
             $mailer->isHtml(true);
             $mailer->setSender(array($mailfrom, $fromname));
             $mailer->addRecipient($recipient);
             $mailer->setSubject($subject);
             $mailer->setBody($body);
             $mailer->Send();
         }
     }
     return true;
 }