Пример #1
0
 /**
  * @param string $file
  * @return array
  */
 private function dataForFile($file)
 {
     $loader = $this->scanEngine->getKnownFilesLoader();
     $data = array();
     if ($isKnownFile = $loader->isKnownFile($file)) {
         if ($loader->isKnownCoreFile($file)) {
             $data['cType'] = 'core';
         } else {
             if ($loader->isKnownPluginFile($file)) {
                 $data['cType'] = 'plugin';
                 list($itemName, $itemVersion, $cKey) = $loader->getKnownPluginData($file);
                 $data = array_merge($data, array('cName' => $itemName, 'cVersion' => $itemVersion, 'cKey' => $cKey));
             } else {
                 if ($loader->isKnownThemeFile($file)) {
                     $data['cType'] = 'theme';
                     list($itemName, $itemVersion, $cKey) = $loader->getKnownThemeData($file);
                     $data = array_merge($data, array('cName' => $itemName, 'cVersion' => $itemVersion, 'cKey' => $cKey));
                 }
             }
         }
     }
     $data['canDiff'] = $isKnownFile;
     $data['canFix'] = $isKnownFile;
     $data['canDelete'] = !$isKnownFile;
     return $data;
 }
Пример #2
0
 /**
  * @param string $file
  * @return array
  */
 private function dataForFile($file, $fullPath = null)
 {
     $loader = $this->scanEngine->getKnownFilesLoader();
     $data = array();
     if ($isKnownFile = $loader->isKnownFile($file)) {
         if ($loader->isKnownCoreFile($file)) {
             $data['cType'] = 'core';
         } else {
             if ($loader->isKnownPluginFile($file)) {
                 $data['cType'] = 'plugin';
                 list($itemName, $itemVersion, $cKey) = $loader->getKnownPluginData($file);
                 $data = array_merge($data, array('cName' => $itemName, 'cVersion' => $itemVersion, 'cKey' => $cKey));
             } else {
                 if ($loader->isKnownThemeFile($file)) {
                     $data['cType'] = 'theme';
                     list($itemName, $itemVersion, $cKey) = $loader->getKnownThemeData($file);
                     $data = array_merge($data, array('cName' => $itemName, 'cVersion' => $itemVersion, 'cKey' => $cKey));
                 }
             }
         }
     }
     $suppressDelete = false;
     $canRegenerate = false;
     if ($fullPath !== null) {
         $bootstrapPath = wordfence::getWAFBootstrapPath();
         $htaccessPath = get_home_path() . '.htaccess';
         $userIni = ini_get('user_ini.filename');
         $userIniPath = false;
         if ($userIni) {
             $userIniPath = get_home_path() . $userIni;
         }
         if ($fullPath == $htaccessPath) {
             $suppressDelete = true;
         } else {
             if ($userIniPath !== false && $fullPath == $userIniPath) {
                 $suppressDelete = true;
             } else {
                 if ($fullPath == $bootstrapPath) {
                     $suppressDelete = true;
                     $canRegenerate = true;
                 }
             }
         }
     }
     $data['canDiff'] = $isKnownFile;
     $data['canFix'] = $isKnownFile;
     $data['canDelete'] = !$isKnownFile && !$canRegenerate && !$suppressDelete;
     $data['canRegenerate'] = $canRegenerate;
     return $data;
 }
 private function start_scan()
 {
     $information = array();
     if (!class_exists('wordfence') || !class_exists('wfScanEngine')) {
         $information['error'] = 'NO_WORDFENCE';
         return $information;
     }
     if (wfUtils::isScanRunning()) {
         $information['error'] = 'SCAN_RUNNING';
         return $information;
     }
     $err = wfScanEngine::startScan();
     if ($err) {
         $information['error'] = htmlentities($err);
     } else {
         $information['result'] = 'SUCCESS';
     }
     return $information;
 }
Пример #4
0
 /**
  *
  */
 public static function ajax_disableDirectoryListing_callback()
 {
     $issueID = absint($_POST['issueID']);
     $wfIssues = new wfIssues();
     $issue = $wfIssues->getIssueByID($issueID);
     if (!$issue) {
         return array('err' => 1, 'errorMsg' => "We could not find that issue in our database.");
     }
     $wfIssues->deleteIssue($issueID);
     $htaccessPath = wfCache::getHtaccessPath();
     if (!$htaccessPath) {
         return array('err' => 1, 'errorMsg' => "Wordfence could not find your .htaccess file.");
     }
     $fileContents = file_get_contents($htaccessPath);
     if (file_put_contents($htaccessPath, "# Added by Wordfence " . date('r') . "\nOptions -Indexes\n\n" . $fileContents, LOCK_EX)) {
         $uploadPaths = wp_upload_dir();
         if (!wfScanEngine::isDirectoryListingEnabled($uploadPaths['baseurl'])) {
             return array('ok' => 1);
         } else {
             // Revert any changes done to .htaccess
             file_put_contents($htaccessPath, $fileContents, LOCK_EX);
             return array('err' => 1, 'errorMsg' => "Updating the .htaccess did not fix the issue. You may need to add <code>Options -Indexes</code>\nto your httpd.conf if using Apache, or find documentation on how to disable directory listing for your web server.");
         }
     }
     return array('err' => 1, 'errorMsg' => "There was an error writing to your .htaccess file.");
 }
Пример #5
0
 public function scan($forkObj)
 {
     /** @var wpdb */
     global $wpdb;
     if (!$this->startTime) {
         $this->startTime = microtime(true);
     }
     if (!$this->lastStatusTime) {
         $this->lastStatusTime = microtime(true);
     }
     $db = new wfDB();
     $blogsToScan = wfScanEngine::getBlogsToScan('options');
     foreach ($blogsToScan as $blog) {
         // Check the options table for known shells
         $results = $db->querySelect("SELECT * FROM {$blog['table']} WHERE option_value REGEXP %s", trim(rtrim($this->patterns['dbSigPattern'], 'imsxeADSUXJu'), '/'));
         foreach ($results as $row) {
             preg_match($this->patterns['dbSigPattern'], $row['option_value'], $matches);
             $this->addResult(array('type' => 'database', 'severity' => 1, 'ignoreP' => "{$db->prefix()}option.{$row['option_name']}", 'ignoreC' => md5($row['option_value']), 'shortMsg' => "This option may contain malicious executable code: {$row['option_name']}", 'longMsg' => "This option appears to be inserted by a hacker to perform malicious activity. If you know about this option you can choose to ignore it to exclude it from future scans. The text we found in this file that matches a known malicious file is: <strong style=\"color: #F00;\">\"{$matches[1]}\"</strong>.", 'data' => array('option_name' => $row['option_name'], 'site_id' => $blog['blog_id'], 'canDelete' => true)));
         }
     }
     return $this->results;
 }
Пример #6
0
 public static function preCommentApprovedFilter($approved, $cData)
 {
     if ($approved == 1 && !is_user_logged_in() && wfConfig::get('other_noAnonMemberComments')) {
         $user = get_user_by('email', trim($cData['comment_author_email']));
         if ($user) {
             wfConfig::inc('totalSpamStopped');
             return 0;
             //hold for moderation if the user is not signed in but used a members email
         }
     }
     if (($approved == 1 || $approved == 0) && wfConfig::get('other_scanComments')) {
         $wf = new wfScanEngine();
         try {
             if ($wf->isBadComment($cData['comment_author'], $cData['comment_author_email'], $cData['comment_author_url'], $cData['comment_author_IP'], $cData['comment_content'])) {
                 wfConfig::inc('totalSpamStopped');
                 return 'spam';
             }
         } catch (Exception $e) {
             //This will most likely be an API exception because we can't contact the API, so we ignore it and let the normal comment mechanisms run.
         }
     }
     if (wfConfig::get('isPaid') && ($approved == 1 || $approved == 0) && wfConfig::get('advancedCommentScanning')) {
         self::$commentSpamItems = array();
         preg_replace_callback('/(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})/', 'wordfence::pushCommentSpamIP', $cData['comment_content']);
         $IPs = self::$commentSpamItems;
         self::$commentSpamItems = array();
         preg_replace_callback('/https?:\\/\\/([a-zA-Z0-9\\-]+\\.[a-zA-Z0-9\\-\\.]+[a-zA-Z0-9])/i', 'wordfence::pushCommentSpamHost', $cData['comment_content']);
         $hosts = self::$commentSpamItems;
         self::$commentSpamItems = array();
         try {
             $api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
             $res = $api->call('advanced_comment_scan', array(), array('author' => $cData['comment_author'], 'email' => $cData['comment_author_email'], 'URL' => $cData['comment_author_url'], 'commentIP' => $cData['comment_author_IP'], 'wfIP' => wfUtils::getIP(), 'hosts' => sizeof($hosts) > 0 ? implode(',', $hosts) : '', 'IPs' => sizeof($IPs) > 0 ? implode(',', $IPs) : ''));
             if (is_array($res) && isset($res['spam']) && $res['spam'] == 1) {
                 wfConfig::inc('totalSpamStopped');
                 return 'spam';
             }
         } catch (Exception $e) {
             //API server is probably down
         }
     }
     wfConfig::inc('totalCommentsFiltered');
     return $approved;
 }
Пример #7
0
 public static function wfScanMain()
 {
     self::$peakMemAtStart = memory_get_peak_usage();
     $db = new wfDB();
     if ($db->errorMsg) {
         self::errorExit("Could not connect to database to start scan: " . $db->errorMsg);
     }
     if (!wordfence::wfSchemaExists()) {
         self::errorExit("Looks like the Wordfence database tables have been deleted. You can fix this by de-activating and re-activating the Wordfence plugin from your Plugins menu.");
     }
     if (isset($_GET['test']) && $_GET['test'] == '1') {
         echo "WFCRONTESTOK:" . wfConfig::get('cronTestID');
         self::status(4, 'info', "Cron test received and message printed");
         exit;
     }
     /* ----------Starting cronkey check -------- */
     self::status(4, 'info', "Scan engine received request.");
     self::status(4, 'info', "Checking cronkey");
     if (!$_GET['cronKey']) {
         self::status(4, 'error', "Wordfence scan script accessed directly, or WF did not receive a cronkey.");
         echo "If you see this message it means Wordfence is working correctly. You should not access this URL directly. It is part of the Wordfence security plugin and is designed for internal use only.";
         exit;
     }
     self::status(4, 'info', "Fetching stored cronkey for comparison.");
     $currentCronKey = wfConfig::get('currentCronKey', false);
     wfConfig::set('currentCronKey', '');
     if (!$currentCronKey) {
         wordfence::status(4, 'error', "Wordfence could not find a saved cron key to start the scan so assuming it started and exiting.");
         exit;
     }
     self::status(4, 'info', "Exploding stored cronkey");
     $savedKey = explode(',', $currentCronKey);
     if (time() - $savedKey[0] > 86400) {
         self::errorExit("The key used to start a scan expired. The value is: " . $savedKey[0] . " and split is: " . $currentCronKey . " and time is: " . time());
     }
     //keys only last 60 seconds and are used within milliseconds of creation
     self::status(4, 'info', "Checking saved cronkey against cronkey param");
     if ($savedKey[1] != $_GET['cronKey']) {
         self::errorExit("Wordfence could not start a scan because the cron key does not match the saved key.");
     }
     /* --------- end cronkey check ---------- */
     self::status(4, 'info', "Becoming admin for scan");
     self::becomeAdmin();
     self::status(4, 'info', "Done become admin");
     $isFork = $_GET['isFork'] == '1' ? true : false;
     if (!$isFork) {
         self::status(4, 'info', "Checking if scan is already running");
         if (!wfUtils::getScanLock()) {
             self::errorExit("There is already a scan running.");
         }
     }
     self::status(4, 'info', "Requesting max memory");
     wfUtils::requestMaxMemory();
     self::status(4, 'info', "Setting up error handling environment");
     set_error_handler('wfScan::error_handler', E_ALL);
     register_shutdown_function('wfScan::shutdown');
     if (!self::$debugMode) {
         ob_start('wfScan::obHandler');
     }
     @error_reporting(E_ALL);
     wfUtils::iniSet('display_errors', 'On');
     self::status(4, 'info', "Setting up scanRunning and starting scan");
     $scan = false;
     if ($isFork) {
         $scan = wfConfig::get_ser('wfsd_engine', false, true);
         if ($scan) {
             self::status(4, 'info', "Got a true deserialized value back from 'wfsd_engine' with type: " . gettype($scan));
             wfConfig::set('wfsd_engine', '', true);
         } else {
             self::status(2, 'error', "Scan can't continue - stored data not found after a fork. Got type: " . gettype($scan));
             wfConfig::set('wfsd_engine', '', true);
             exit;
         }
     } else {
         wordfence::statusPrep();
         //Re-initializes all status counters
         $scan = new wfScanEngine();
     }
     try {
         $scan->go();
     } catch (Exception $e) {
         wfUtils::clearScanLock();
         self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
         self::status(10, 'info', "SUM_KILLED:Previous scan terminated with an error. See below.");
         exit;
     }
     wfUtils::clearScanLock();
     self::logPeakMemory();
     self::status(2, 'info', "Wordfence used " . sprintf('%.2f', (wfConfig::get('wfPeakMemory') - self::$peakMemAtStart) / 1024 / 1024) . "MB of memory for scan. Server peak memory usage was: " . sprintf('%.2f', wfConfig::get('wfPeakMemory') / 1024 / 1024) . "MB");
 }
Пример #8
0
 public static function preCommentApprovedFilter($approved, $cData)
 {
     if ($approved == 1 && !is_user_logged_in() && wfConfig::get('other_noAnonMemberComments')) {
         $user = get_user_by('email', trim($cData['comment_author_email']));
         if ($user) {
             return 0;
             //hold for moderation if the user is not signed in but used a members email
         }
     }
     if (($approved == 1 || $approved == 0) && wfConfig::get('other_scanComments')) {
         $wf = new wfScanEngine();
         try {
             if ($wf->isBadComment($cData['comment_author'], $cData['comment_author_email'], $cData['comment_author_url'], $cData['comment_author_IP'], $cData['comment_content'])) {
                 return 'spam';
             }
         } catch (Exception $e) {
             //This will most likely be an API exception because we can't contact the API, so we ignore it and let the normal comment mechanisms run.
         }
     }
     return $approved;
 }