Example #1
0
/**
 * List all files inside wp-content that have been modified in the last days.
 *
 * @return void
 */
function sucuriscan_modified_files()
{
    $valid_day_ranges = array(1, 3, 7, 30, 60);
    $template_variables = array('ModifiedFiles.List' => '', 'ModifiedFiles.SelectOptions' => '', 'ModifiedFiles.NoFilesVisibility' => 'visible', 'ModifiedFiles.DisabledVisibility' => 'hidden', 'ModifiedFiles.Days' => 0);
    // Find files modified in the last days.
    $back_days = SucuriScanRequest::post(':last_days', '[0-9]+');
    if ($back_days !== false) {
        if ($back_days <= 0) {
            $back_days = 1;
        } elseif ($back_days >= 60) {
            $back_days = 60;
        }
    } else {
        $back_days = 7;
    }
    // Fix data type for the back days variable.
    $back_days = intval($back_days);
    $template_variables['ModifiedFiles.Days'] = $back_days;
    // Generate the options for the select field of the page form.
    foreach ($valid_day_ranges as $day) {
        $selected_option = $back_days == $day ? 'selected="selected"' : '';
        $template_variables['ModifiedFiles.SelectOptions'] .= sprintf('<option value="%d" %s>%d</option>', $day, $selected_option, $day);
    }
    // The scanner for modified files can be disabled from the settings page.
    if (SucuriScanOption::is_enabled(':scan_modfiles')) {
        // Search modified files among the project's files.
        $content_hashes = sucuriscan_get_integrity_tree(WP_CONTENT_DIR, true);
        if (!empty($content_hashes)) {
            $back_days = current_time('timestamp') - $back_days * 86400;
            $counter = 0;
            foreach ($content_hashes as $file_path => $file_info) {
                if (isset($file_info['modified_at']) && $file_info['modified_at'] >= $back_days) {
                    $css_class = $counter % 2 == 0 ? '' : 'alternate';
                    $mod_date = SucuriScan::datetime($file_info['modified_at']);
                    $template_variables['ModifiedFiles.List'] .= SucuriScanTemplate::get_snippet('integrity-modifiedfiles', array('ModifiedFiles.CssClass' => $css_class, 'ModifiedFiles.CheckSum' => $file_info['checksum'], 'ModifiedFiles.FilePath' => SucuriScan::escape($file_path), 'ModifiedFiles.DateTime' => $mod_date, 'ModifiedFiles.FileSize' => $file_info['filesize'], 'ModifiedFiles.FileSizeHuman' => SucuriScan::human_filesize($file_info['filesize']), 'ModifiedFiles.FileSizeNumber' => number_format($file_info['filesize'])));
                    $counter += 1;
                }
            }
            if ($counter > 0) {
                $template_variables['ModifiedFiles.NoFilesVisibility'] = 'hidden';
            }
        }
    } else {
        $template_variables['ModifiedFiles.DisabledVisibility'] = 'visible';
    }
    return SucuriScanTemplate::get_section('integrity-modifiedfiles', $template_variables);
}
Example #2
0
/**
 * Check whether the core WordPress files where modified, removed or if any file
 * was added to the core folders. This function returns an associative array with
 * these keys:
 *
 * <ul>
 *   <li>modified: Files with a different checksum according to the official WordPress archives,</li>
 *   <li>stable: Files with the same checksums than the official files,</li>
 *   <li>removed: Official files which are not present in the local project,</li>
 *   <li>added: Files present in the local project but not in the official WordPress packages.</li>
 * </ul>
 *
 * @param  integer $version Valid version number of the WordPress project.
 * @return array            Associative array with these keys: modified, stable, removed, added.
 */
function sucuriscan_check_core_integrity($version = 0)
{
    $latest_hashes = SucuriScanAPI::getOfficialChecksums($version);
    $base_content_dir = defined('WP_CONTENT_DIR') ? basename(rtrim(WP_CONTENT_DIR, '/')) : '';
    if (!$latest_hashes) {
        return false;
    }
    $output = array('added' => array(), 'removed' => array(), 'modified' => array(), 'stable' => array());
    // Get current filesystem tree.
    $wp_top_hashes = sucuriscan_get_integrity_tree(ABSPATH, false);
    $wp_admin_hashes = sucuriscan_get_integrity_tree(ABSPATH . 'wp-admin', true);
    $wp_includes_hashes = sucuriscan_get_integrity_tree(ABSPATH . 'wp-includes', true);
    $wp_core_hashes = array_merge($wp_top_hashes, $wp_admin_hashes, $wp_includes_hashes);
    // Compare remote and local checksums and search removed files.
    foreach ($latest_hashes as $file_path => $remote_checksum) {
        if (sucuriscan_ignore_integrity_filepath($file_path)) {
            continue;
        }
        $full_filepath = sprintf('%s/%s', ABSPATH, $file_path);
        // Patch for custom content directory path.
        if (!file_exists($full_filepath) && strpos($file_path, 'wp-content') !== false && defined('WP_CONTENT_DIR')) {
            $file_path = str_replace('wp-content', $base_content_dir, $file_path);
            $dir_content_dir = dirname(rtrim(WP_CONTENT_DIR, '/'));
            $full_filepath = sprintf('%s/%s', $dir_content_dir, $file_path);
        }
        // Check whether the official file exists or not.
        if (file_exists($full_filepath)) {
            $local_checksum = @md5_file($full_filepath);
            if ($local_checksum !== false && $local_checksum === $remote_checksum) {
                $output['stable'][] = array('filepath' => $file_path, 'is_fixable' => false, 'modified_at' => 0);
            } else {
                $modified_at = @filemtime($full_filepath);
                $is_fixable = (bool) is_writable($full_filepath);
                $output['modified'][] = array('filepath' => $file_path, 'is_fixable' => $is_fixable, 'modified_at' => $modified_at);
            }
        } else {
            $is_fixable = is_writable(dirname($full_filepath));
            $output['removed'][] = array('filepath' => $file_path, 'is_fixable' => $is_fixable, 'modified_at' => 0);
        }
    }
    // Search added files (files not common in a normal wordpress installation).
    foreach ($wp_core_hashes as $file_path => $extra_info) {
        $file_path = str_replace(DIRECTORY_SEPARATOR, '/', $file_path);
        $file_path = @preg_replace('/^\\.\\/(.*)/', '$1', $file_path);
        if (sucuriscan_ignore_integrity_filepath($file_path)) {
            continue;
        }
        if (!array_key_exists($file_path, $latest_hashes)) {
            $full_filepath = ABSPATH . '/' . $file_path;
            $modified_at = @filemtime($full_filepath);
            $is_fixable = (bool) is_writable($full_filepath);
            $output['added'][] = array('filepath' => $file_path, 'is_fixable' => $is_fixable, 'modified_at' => $modified_at);
        }
    }
    return $output;
}