Sucuri Security – Auditing, Malware Scanner and Security Hardening - Version 1.3

Version Description

  • Removed some PHP warnings and code clean up.
  • Added WordPress integrity checks.
  • Added plugin/theme/user checks.
Download this release

Release Info

Developer dd@sucuri.net
Plugin Icon 128x128 Sucuri Security – Auditing, Malware Scanner and Security Hardening
Version 1.3
Comparing to
See all releases

Code changes from version 1.1.6 to 1.3

inc/css/sucuriscan-default-css.css ADDED
@@ -0,0 +1,59 @@
1
+ /* Sucuri Security - SiteCheck Malware Scanner
2
+ * Copyright (C) 2010-2012 Sucuri Security - http://sucuri.net
3
+ * Released under the GPL - see LICENSE file for details.
4
+ */
5
+
6
+ .sucuriscan_header {
7
+ background: #333;
8
+ border-bottom-left-radius:5px;
9
+ border-bottom-right-radius:5px;
10
+ border-top-left-radius:5px;
11
+ border-top-right-radius:5px;
12
+ height: 38px;
13
+ margin: 16px 0 8px;
14
+ min-width: 255px;
15
+ padding: 10px;
16
+ position: relative;
17
+ }
18
+
19
+ .sucuriscan_header img {
20
+ float: left;
21
+ height: 38px;
22
+ width: 101px;
23
+ }
24
+
25
+ .wrap .sucuriscan_header h2 {
26
+ color: #fff;
27
+ float: left;
28
+ margin-left: 10px;
29
+ padding: 3px 0 0;
30
+ text-shadow:#000 0 1px 0;
31
+ }
32
+
33
+ .sucuriscan-maincontent {
34
+ padding: 10px 20px 0 0;
35
+ }
36
+
37
+ #sidebar {
38
+ padding-top: 10px;
39
+ }
40
+
41
+ #sidebar .sucuriscan-sidebar {
42
+ border:1px solid #CCCCCC;
43
+ border-bottom-left-radius:5px;
44
+ border-bottom-right-radius:5px;
45
+ border-top-left-radius:5px;
46
+ border-top-right-radius:5px;
47
+ margin:0 0 10px;
48
+ padding:10px 15px;
49
+ }
50
+
51
+ #sitecleanup.sucuriscan-sidebar {
52
+ background-color:#bbe8f5;
53
+ border-color:#4393ac;
54
+ }
55
+
56
+ #sucuri-latest-posts.sucuriscan-sidebar {
57
+ background-color:#ececec;
58
+ border-color:#999;
59
+ }
inc/images/logo.png ADDED
Binary file
inc/scripts.php ADDED
@@ -0,0 +1,80 @@
1
+ <?php
2
+
3
+ /**
4
+ * Admin JavaScript and Stylesheet registration
5
+ *
6
+ **** This script file was kindly donated to Sucuri by the awesome Brandon Dove - https://twitter.com/brandondove ****
7
+ *
8
+ * Hooks into the admin_enqueue_scripts action to register scripts and styles that
9
+ * are needed throughout the plugin back-end
10
+ */
11
+ add_action( 'admin_enqueue_scripts', 'sucuriscan_admin_script_style_registration', 1 );
12
+ function sucuriscan_admin_script_style_registration() {
13
+
14
+ $default_deps = array( 'jquery' );
15
+
16
+ echo 'tacos';
17
+
18
+ /*
19
+ * REGISTER JAVASCRIPT FILES
20
+ * 01. Authorization
21
+ /****************************************************************************************************************************/
22
+ $scripts = array();
23
+
24
+ // 1. AUTHORIZATION
25
+ $scripts['sucuri-authorization'] = array(
26
+ sucuriscan_JS. SUCURI_URL . 'inc/js/authorization.js',
27
+ $default_deps,
28
+ sucuriscan_VERSION,
29
+ true );
30
+
31
+ // Register all of our scripts for later use
32
+ foreach( $scripts as $slug => $script )
33
+ wp_register_script( $slug, $script[0], $script[1], $script[2], $script[3] );
34
+
35
+
36
+ /*
37
+ * REGISTER CSS FILES
38
+ * 01. Authorization
39
+ /****************************************************************************************************************************/
40
+ $styles = array();
41
+
42
+ // 1. AUTHORIZATION
43
+ $styles['sucuri-setup'] = array(
44
+ sucuriscan_CSS.'setup.css',
45
+ array( 'sucuri-ads-common', 'wp-pointer' ),
46
+ sucuriscan_VERSION,
47
+ 'screen' );
48
+
49
+ // Register all of our styles for later use
50
+ foreach( $styles as $slug => $style )
51
+ wp_register_style( $slug, $style[0], $style[1], $style[2], $style[3] );
52
+ }
53
+
54
+
55
+ /**
56
+ * Public JavaScript and Stylesheet registration
57
+ *
58
+ * Hooks into the wp_enqueue_scripts action to register scripts and styles that
59
+ * are needed on the front end
60
+ */
61
+ add_action( 'wp_enqueue_scripts', 'sucuriscan_public_script_style_registration', 1 );
62
+ function sucuriscan_public_script_style_registration() {
63
+
64
+ /*
65
+ * REGISTER CSS FILES
66
+ * 01. Tracking Filters
67
+ /****************************************************************************************************************************/
68
+ $styles = array();
69
+
70
+ // 1. DEFAULT AD CSS
71
+ $styles['sucuri-default-css'] = array(
72
+ sucuriscan_CSS.'widget-default.css',
73
+ false,
74
+ sucuriscan_VERSION,
75
+ 'screen' );
76
+
77
+ // Register all of our styles for later use
78
+ foreach( $styles as $slug => $style )
79
+ wp_register_style( $slug, $style[0], $style[1], $style[2], $style[3] );
80
+ }
lib/core_integrity.php ADDED
@@ -0,0 +1,242 @@
1
+ <?php
2
+ /* Sucuri Security - WordPress Core Intherity check against the latest version
3
+ * Copyright (C) 2010-2012 Sucuri Security - http://sucuri.net
4
+ * Released under the GPL - see LICENSE file for details.
5
+ */
6
+ if(!defined('SUCURISCAN'))
7
+ {
8
+ return(0);
9
+ }
10
+
11
+ function sucuriscan_core_integrity_wrapper($content, $msg)
12
+ {
13
+ echo '<div class="postbox">';
14
+ echo '<h3>'.$msg.'</h3>';
15
+ echo '<div class="inside">';
16
+ foreach ($content as $key => $value) {
17
+ echo "<p>$key</p>";
18
+ }
19
+ echo '</div>';
20
+ echo '</div>';
21
+ }
22
+
23
+ function read_dir_r($dir = "./", $recursiv = false)
24
+ {
25
+ $skipname = basename(__FILE__);
26
+ $skipname .= ",_sucuribackup,wp-config.php";
27
+
28
+ $files_info = array();
29
+
30
+ $dir_handler = opendir($dir);
31
+
32
+ while(($entry = readdir($dir_handler)) !== false) {
33
+ if ($entry != "." && $entry != "..") {
34
+ $dir = preg_replace("/^(.*)(\/)+#x2F;", "$1", $dir);
35
+ $item = $dir . "/" . $entry;
36
+ if (is_file($item)) {
37
+
38
+ $skip_parts = explode(",", $skipname);
39
+ foreach ($skip_parts as $skip) {
40
+ if (strpos($item,$skip) !== false) {
41
+ continue 2;
42
+ }
43
+ }
44
+
45
+ $md5 = @md5_file($item);
46
+ $time_stamp = @filectime($item);
47
+ $item_name = str_replace(ABSPATH, "./", $item);
48
+ $files_info[$item_name] = array(
49
+ 'md5' => $md5,
50
+ 'time' => $time_stamp
51
+ );
52
+
53
+ }
54
+ elseif (is_dir($item) && $recursiv) {
55
+ $files_info = array_merge( $files_info , read_dir_r($item) );
56
+ }
57
+ }
58
+ }
59
+
60
+ closedir($dir_handler);
61
+ return $files_info;
62
+ }
63
+
64
+ function sucuriwp_core_integrity_check()
65
+ {
66
+
67
+ global $wp_version;
68
+ $cp = 0;
69
+ $updates = get_core_updates();
70
+ if (!is_array($updates))
71
+ {
72
+ $cp = 1;
73
+ }
74
+ else if(empty($updates))
75
+ {
76
+ $cp = 1;
77
+ }
78
+ else if($updates[0]->response == 'latest')
79
+ {
80
+ $cp = 1;
81
+ }
82
+ if(strcmp($wp_version, "3.4.2") < 0)
83
+ {
84
+ $cp = 0;
85
+ }
86
+ $wp_version = htmlspecialchars($wp_version);
87
+
88
+ if($cp == 0)
89
+ {
90
+ echo '<p><img style="position:relative;top:5px" height="22" width="22"'.
91
+ 'src="'.SUCURI_URL.'images/warn.png" /> &nbsp; Your current version ('.$wp_version.') is not the latest. <a class="button-primary" href="update-core.php">Update now!</a> to be able to run the integrity check.</p>';
92
+ }
93
+ else
94
+ {
95
+
96
+ $wp_core_latest_hashes = json_decode(file_get_contents("http://wordpress.sucuri.net/wp_core_latest_hashes.json"), true);
97
+
98
+ $wp_includes_hashes = read_dir_r( ABSPATH . "wp-includes", true);
99
+ $wp_admin_hashes = read_dir_r( ABSPATH . "wp-admin", true);
100
+ $wp_top_hashes = read_dir_r( ABSPATH , false);
101
+
102
+ $wp_core_hashes = array_merge( $wp_includes_hashes , $wp_admin_hashes );
103
+ $wp_core_hashes = array_merge( $wp_core_hashes , $wp_top_hashes );
104
+
105
+ $added = @array_diff_assoc( $wp_core_hashes, $wp_core_latest_hashes ); //files added
106
+ $removed = @array_diff_assoc( $wp_core_latest_hashes, $wp_core_hashes ); //files deleted
107
+ $compcurrent = @array_diff_key( $wp_core_hashes, $added ); //remove all added files from current filelist
108
+ $complog = @array_diff_key( $wp_core_latest_hashes, $removed ); //remove all deleted files from old file list
109
+ $changed = array(); //array of changed files
110
+
111
+ //compare file hashes and mod dates
112
+ foreach ( $compcurrent as $currfile => $currattr) {
113
+
114
+ if ( array_key_exists( $currfile, $complog ) ) {
115
+
116
+ //if attributes differ added to changed files array
117
+ if ( strcmp( $currattr['md5'], $complog[$currfile]['md5'] ) != 0 ) {
118
+ $changed[$currfile]['md5'] = $currattr['md5'];
119
+ }
120
+
121
+ }
122
+
123
+ }
124
+
125
+ //get count of changes
126
+ $addcount = sizeof( $added );
127
+ $removecount = sizeof( $removed );
128
+ $changecount = sizeof( $changed );
129
+
130
+ sucuriscan_core_integrity_wrapper($added, "Core File Added: $addcount");
131
+ sucuriscan_core_integrity_wrapper($removed, "Core File Removed: $removecount");
132
+ sucuriscan_core_integrity_wrapper($changed, "Core File Modified: $changecount");
133
+ }
134
+ }
135
+
136
+ function sucuriwp_list_admins($userlevel = '10') {
137
+
138
+ global $wpdb;
139
+ /*
140
+ 1 = subscriber
141
+ 2 = editor
142
+ 3 = author
143
+ 7 = publisher
144
+ 10 = administrator
145
+ */
146
+ echo '<div class="postbox">';
147
+ echo "<h3>Administrator Users</h3>";
148
+ echo '<div class="inside">';
149
+
150
+ $admins = $wpdb->get_results("SELECT * from $wpdb->usermeta WHERE meta_key = 'wp_user_level' AND meta_value = '$userlevel'");
151
+ foreach ( (array) $admins as $admin ) {
152
+ $admin = get_userdata( $admin->user_id );
153
+ $userlevel = $admin->wp2_user_level;
154
+ $name = $admin->nickname;
155
+ if ( $show_fullname && ($admin->first_name != '' && $admin->last_name != '') ) {
156
+ $name = "$admin->first_name $admin->last_name";
157
+ }
158
+ echo "<p>User: $admin->nickname - Full Name : $name</p>";
159
+ }
160
+ echo '</div>';
161
+ echo '</div>';
162
+
163
+ }
164
+
165
+ function sucuriwp_content_check()
166
+ {
167
+ $wp_content_hashes = read_dir_r( ABSPATH . "wp-content", true);
168
+ $back_3_days = current_time( 'timestamp' ) - (3 * 24 * 3600);
169
+
170
+ echo '<div class="postbox">';
171
+ echo "<h3>wp_content latest modified files</h3>";
172
+ echo '<div class="inside">';
173
+ foreach ( $wp_content_hashes as $key => $value) {
174
+ if ($value['time'] >= $back_3_days ){
175
+ $date = date('d-m-Y H:i:s', $value['time']);
176
+ echo "<p>$key : $date </p>";
177
+ }
178
+ }
179
+ echo '</div>';
180
+ echo '</div>';
181
+ }
182
+
183
+ function sucuriwp_check_plugins()
184
+ {
185
+ do_action("wp_update_plugins"); // force WP to check plugins for updates
186
+ wp_update_plugins();
187
+ $update_plugins = get_site_transient('update_plugins'); // get information of updates
188
+ $plugins_need_update = $update_plugins->response; // plugins that need updating
189
+
190
+ echo '<div class="postbox">';
191
+ echo "<h3>Outdated Plugins</h3>";
192
+ echo '<div class="inside">';
193
+ if (!empty($update_plugins->response)) { // any plugin updates available?
194
+ $plugins_need_update = $update_plugins->response; // plugins that need updating
195
+ $active_plugins = array_flip(get_option('active_plugins')); // find which plugins are active
196
+ $plugins_need_update = array_intersect_key($plugins_need_update, $active_plugins); // only keep plugins that are active
197
+ if(count($plugins_need_update) >= 1) { // any plugins need updating after all the filtering gone on above?
198
+ require_once(ABSPATH . 'wp-admin/includes/plugin-install.php'); // Required for plugin API
199
+ require_once(ABSPATH . WPINC . '/version.php' ); // Required for WP core version
200
+ foreach($plugins_need_update as $key => $data) { // loop through the plugins that need updating
201
+ $plugin_info = get_plugin_data(WP_PLUGIN_DIR . "/" . $key); // get local plugin info
202
+ $info = plugins_api('plugin_information', array('slug' => $data->slug )); // get repository plugin info
203
+ $message = "\n".sprintf(__("Plugin: %s is out of date. Please update from version %s to %s", "wp-updates-notifier"), $plugin_info['Name'], $plugin_info['Version'], $data->new_version)."\n";
204
+ echo "<p>$message</p>";
205
+ }
206
+ }
207
+ else
208
+ {
209
+ echo "<p>All plugins are up-to-date!</p>";
210
+ }
211
+ }
212
+ echo '</div>';
213
+ echo '</div>';
214
+ }
215
+
216
+ function sucuriwp_check_themes()
217
+ {
218
+ do_action("wp_update_themes"); // force WP to check for theme updates
219
+ wp_update_themes();
220
+ $update_themes = get_site_transient('update_themes'); // get information of updates
221
+
222
+ echo '<div class="postbox">';
223
+ echo "<h3>Outdated Themes</h3>";
224
+ echo '<div class="inside">';
225
+ if (!empty($update_themes->response)) { // any theme updates available?
226
+ $themes_need_update = $update_themes->response; // themes that need updating
227
+
228
+ if(count($themes_need_update) >= 1) { // any themes need updating after all the filtering gone on above?
229
+ foreach($themes_need_update as $key => $data) { // loop through the themes that need updating
230
+ $theme_info = get_theme_data(WP_CONTENT_DIR . "/themes/" . $key . "/style.css"); // get theme info
231
+ $message = sprintf(__("Theme: %s is out of date. Please update from version %s to %s", "wp-updates-notifier"), $theme_info['Name'], $theme_info['Version'], $data['new_version'])."\n";
232
+ echo "<p>$message</p>";
233
+ }
234
+ }
235
+ }
236
+ else
237
+ {
238
+ echo "<p>All themes are up-to-date!</p>";
239
+ }
240
+ echo '</div>';
241
+ echo '</div>';
242
+ }
lib/hardening.php ADDED
@@ -0,0 +1,296 @@
1
+ <?php
2
+ /* Sucuri Security - SiteCheck Malware Scanner
3
+ * Copyright (C) 2010-2012 Sucuri Security - http://sucuri.net
4
+ * Released under the GPL - see LICENSE file for details.
5
+ */
6
+ if(!defined('SUCURISCAN'))
7
+ {
8
+ return(0);
9
+ }
10
+
11
+ function sucuriscan_wrapper_open($msg)
12
+ {
13
+ ?>
14
+ <div class="postbox">
15
+ <h3><?php echo $msg; ?></h3>
16
+ <div class="inside">
17
+ <?php
18
+ }
19
+ function sucuriscan_wrapper_close()
20
+ {
21
+ ?>
22
+ </div>
23
+ </div>
24
+ <?php
25
+ }
26
+
27
+ function sucuriscan_harden_error($message)
28
+ {
29
+ return('<div id="message" class="error"><p>'.$message.'</p></div>');
30
+ }
31
+
32
+ function sucuriscan_harden_ok($message)
33
+ {
34
+ return( '<div id="message" class="updated"><p>'.$message.'</p></div>');
35
+ }
36
+
37
+ function sucuriscan_harden_status($status, $type, $messageok, $messagewarn,
38
+ $desc = NULL, $updatemsg = NULL)
39
+ {
40
+ if($desc != NULL)
41
+ {
42
+ echo "<p>$desc</p>";
43
+ }
44
+
45
+ if($status == 1)
46
+ {
47
+ echo '<h4>'.
48
+ '<img style="position:relative;top:5px" height="22" width="22"'.
49
+ 'src="'.SUCURI_URL.'images/ok.png" /> &nbsp; '.
50
+ $messageok.'.</h4>';
51
+
52
+ if($updatemsg != NULL){ echo $updatemsg; }
53
+ }
54
+ else
55
+ {
56
+ echo '<h4>'.
57
+ '<img style="position:relative;top:5px" height="22" width="22"'.
58
+ 'src="'.SUCURI_URL.'images/warn.png" /> &nbsp; '.
59
+ $messagewarn. '.</h4>';
60
+
61
+ if($updatemsg != NULL){ echo $updatemsg; }
62
+
63
+ if($type != NULL)
64
+ {
65
+ echo '<input class="button-primary" type="submit" name="'.$type.'"
66
+ value="Harden it!" />';
67
+ }
68
+ }
69
+
70
+
71
+ }
72
+
73
+ function sucuriscan_harden_version()
74
+ {
75
+ global $wp_version;
76
+ $cp = 0;
77
+ $updates = get_core_updates();
78
+ if (!is_array($updates))
79
+ {
80
+ $cp = 1;
81
+ }
82
+ else if(empty($updates))
83
+ {
84
+ $cp = 1;
85
+ }
86
+ else if($updates[0]->response == 'latest')
87
+ {
88
+ $cp = 1;
89
+ }
90
+ if(strcmp($wp_version, "3.4.2") < 0)
91
+ {
92
+ $cp = 0;
93
+ }
94
+ $wp_version = htmlspecialchars($wp_version);
95
+
96
+
97
+ sucuriscan_wrapper_open("Verify WordPress Version");
98
+
99
+
100
+ sucuriscan_harden_status($cp, NULL,
101
+ "WordPress is updated", "WordPress is not updated",
102
+ NULL);
103
+
104
+ if($cp == 0)
105
+ {
106
+ echo "<p>Your current version ($wp_version) is not current.</p><p><a class='button-primary' href='update-core.php'>Update now!</a></p>";
107
+ }
108
+ else
109
+ {
110
+ echo "<p>Your WordPress installation ($wp_version) is current.</p>";
111
+ }
112
+ sucuriscan_wrapper_close();
113
+ }
114
+
115
+ function sucuri_harden_removegenerator()
116
+ {
117
+ /* Enabled by default with this plugin. */
118
+ $cp = 1;
119
+
120
+ sucuriscan_wrapper_open("Remove WordPress Version");
121
+
122
+ sucuriscan_harden_status($cp, "sucuri_harden_removegenerator",
123
+ "WordPress version properly hidden", NULL,
124
+ "It checks if your WordPress version is being hidden".
125
+ " from being displayed in the generator tag ".
126
+ "(enabled by default with this plugin).");
127
+
128
+ sucuriscan_wrapper_close();
129
+ }
130
+
131
+ function sucuriscan_harden_upload()
132
+ {
133
+ $cp = 1;
134
+ $upmsg = NULL;
135
+ $htaccess_upload = dirname(sucuriscan_dir_filepath())."/.htaccess";
136
+
137
+ if(!is_readable($htaccess_upload))
138
+ {
139
+ $cp = 0;
140
+ }
141
+ else
142
+ {
143
+ $cp = 0;
144
+ $fcontent = file($htaccess_upload);
145
+ foreach($fcontent as $fline)
146
+ {
147
+ if(strpos($fline, "deny from all") !== FALSE)
148
+ {
149
+ $cp = 1;
150
+ break;
151
+ }
152
+ }
153
+ }
154
+
155
+ if(isset($_POST['sucuriscan_harden_upload']) &&
156
+ isset($_POST['wpsucuri-doharden']) &&
157
+ $cp == 0)
158
+ {
159
+ if(file_put_contents("$htaccess_upload",
160
+ "\n<Files *.php>\ndeny from all\n</Files>")===FALSE)
161
+ {
162
+ $upmsg = sucuriscan_harden_error("ERROR: Unable to create .htaccess file.");
163
+ }
164
+ else
165
+ {
166
+ $upmsg = sucuriscan_harden_ok("COMPLETE: Upload directory successfully hardened");
167
+ $cp = 1;
168
+ }
169
+ }
170
+
171
+ sucuriscan_wrapper_open("Protect Uploads Directory");
172
+ sucuriscan_harden_status($cp, "sucuriscan_harden_upload",
173
+ "Upload directory properly hardened",
174
+ "Upload directory not hardened",
175
+ "It checks if your upload directory allows PHP ".
176
+ "execution or if it is browsable.", $upmsg);
177
+ sucuriscan_wrapper_close();
178
+ }
179
+
180
+ function sucuriscan_harden_wpcontent()
181
+ {
182
+ $cp = 1;
183
+ $upmsg = NULL;
184
+ $htaccess_content = ABSPATH."/wp-content/.htaccess";
185
+
186
+ if(!is_readable($htaccess_content))
187
+ {
188
+ $cp = 0;
189
+ }
190
+ else
191
+ {
192
+ $cp = 0;
193
+ $fcontent = file($htaccess_content);
194
+ foreach($fcontent as $fline)
195
+ {
196
+ if(strpos($fline, "deny from all") !== FALSE)
197
+ {
198
+ $cp = 1;
199
+ break;
200
+ }
201
+ }
202
+ }
203
+
204
+ if(isset($_POST['sucuriscan_harden_wpcontent']) &&
205
+ isset($_POST['wpsucuri-doharden']) &&
206
+ $cp == 0)
207
+ {
208
+ if(file_put_contents("$htaccess_content",
209
+ "\n<Files *.php>\ndeny from all\n</Files>")===FALSE)
210
+ {
211
+ $upmsg = sucuriscan_harden_error("ERROR: Unable to create .htaccess file.");
212
+ }
213
+ else
214
+ {
215
+ $upmsg = sucuriscan_harden_ok("COMPLETE: wp-content directory successfully hardened");
216
+ $cp = 1;
217
+ }
218
+ }
219
+
220
+ sucuriscan_wrapper_open("Restrict wp-content Access");
221
+ sucuriscan_harden_status($cp, "sucuriscan_harden_wpcontent",
222
+ "WP-content directory properly hardened",
223
+ "WP-content directory not hardened",
224
+ "This option blocks direct PHP access to any file inside wp-content. <p><strong>WARN: <span class='error-message'>Do not enable this option if ".
225
+ "your site uses TimThumb or similar scripts.</span> If you enable and you need to disable, please remove the .htaccess from wp-content.</strong></p>", $upmsg);
226
+ sucuriscan_wrapper_close();
227
+ }
228
+
229
+ function sucuriscan_harden_wpincludes()
230
+ {
231
+ $cp = 1;
232
+ $upmsg = NULL;
233
+ $htaccess_content = ABSPATH."/wp-includes/.htaccess";
234
+
235
+ if(!is_readable($htaccess_content))
236
+ {
237
+ $cp = 0;
238
+ }
239
+ else
240
+ {
241
+ $cp = 0;
242
+ $fcontent = file($htaccess_content);
243
+ foreach($fcontent as $fline)
244
+ {
245
+ if(strpos($fline, "deny from all") !== FALSE)
246
+ {
247
+ $cp = 1;
248
+ break;
249
+ }
250
+ }
251
+ }
252
+
253
+ if(isset($_POST['sucuriscan_harden_wpincludes']) &&
254
+ isset($_POST['wpsucuri-doharden']) &&
255
+ $cp == 0)
256
+ {
257
+ if(file_put_contents("$htaccess_content",
258
+ "\n<Files *.php>\ndeny from all\n</Files>\n<Files wp-tinymce.php>\nallow from all\n</Files>\n")===FALSE)
259
+ {
260
+ $upmsg = sucuriscan_harden_error("ERROR: Unable to create .htaccess file.");
261
+ }
262
+ else
263
+ {
264
+ $upmsg = sucuriscan_harden_ok("COMPLETE: wp-includes directory successfully hardened.");
265
+ $cp = 1;
266
+ }
267
+ }
268
+
269
+ sucuriscan_wrapper_open("Restrict wp-includes Access");
270
+ sucuriscan_harden_status($cp, "sucuriscan_harden_wpincludes",
271
+ "wp-includes directory properly hardened",
272
+ "wp-includes directory not hardened",
273
+ "This option blocks direct PHP access to any file inside wp-includes. ", $upmsg);
274
+ sucuriscan_wrapper_close();
275
+ }
276
+
277
+ function sucuriscan_harden_phpversion()
278
+ {
279
+ $phpv = phpversion();
280
+
281
+ if(strncmp($phpv, "5.", 2) < 0)
282
+ {
283
+ $cp = 0;
284
+ }
285
+ else
286
+ {
287
+ $cp = 1;
288
+ }
289
+
290
+ sucuriscan_wrapper_open("Verify PHP Version");
291
+ sucuriscan_harden_status($cp, NULL,
292
+ "Using an updated version of PHP (v $phpv)",
293
+ "The version of PHP you are using ($phpv) is not current, not recommended, and/or not supported",
294
+ "This checks if you have the latest version of PHP installed.", NULL);
295
+ sucuriscan_wrapper_close();
296
+ }
lib/sidebar.php ADDED
@@ -0,0 +1,22 @@
1
+ <div class="postbox-container" style="width:25%;min-width:200px;max-width:350px;">
2
+ <div id="sidebar">
3
+ <div id="sitecleanup" class="sucuriscan-sidebar">
4
+ <h2><span class="promo">Is your website infected with malware? Blacklisted by Google?</span></h2>
5
+ <p>Don't know where to start? Get cleared today by <a href="http://sucuri.net/signup">Sucuri Security</a>!
6
+ </p>
7
+ <p>
8
+ <a class="button-primary" href="http://sucuri.net/tour">Read more »</a>
9
+ </p>
10
+ </div>
11
+
12
+ <div id="sucuri-latest-posts" class="sucuriscan-sidebar">
13
+ <h2><span class="promo">Stay updated with WordPress security news. </span></h2>
14
+ <p>Check out the <a href="http://blog.sucuri.net/">Sucuri Blog</a>!
15
+ </p>
16
+ <p>
17
+ <a class="button-primary" href="http://blog.sucuri.net/">Read more »</a>
18
+ </p>
19
+ </div>
20
+
21
+ </div>
22
+ </div>
readme.txt CHANGED
@@ -1,34 +1,94 @@
1
- === Sucuri Sitecheck Malware Scanner ===
2
Contributors: dd@sucuri.net, dremeda
3
Donate Link: http://sitecheck.sucuri.net
4
- Tags: malware,security,scan,spam,virus
5
- Requires at least:3.0
6
- Stable tag:1.1.6
7
- Tested up to: 3.3
8
9
- Get free Sucuri SiteCheck scan results directly in your WordPress dashboard. The best way to know if your site is infected with malware or blacklist by Google, all with the click of a button.
10
11
== Description ==
12
13
- This plugin enables full malware and blacklisting scan capabilities from Sucuri SiteCheck right in your WordPress dashboard. It will check for malware, spam, blacklisting and other security issues like htaccess redirections, hidden eval code, etc. The best thing about it is it's completely free.
14
15
- You can also scan your site at <a href="http://sitecheck.sucuri.net">http://sitecheck.sucuri.net</a>.
16
17
18
== Installation ==
19
20
1. Download the plugin.
21
- 1. Go to the Wordpress Plugin menu and activate it.
22
1. That's it!
23
24
25
== Changelog ==
26
27
= 1.1.6 =
28
* Upgrading for WP 3.3.
29
30
= 1.1.5 =
31
- * Removing PHP warnings / code cleaning.
32
33
= 1.1.3 =
34
* Cleaning up the results.
@@ -40,7 +100,6 @@ You can also scan your site at <a href="http://sitecheck.sucuri.net">http://site
40
= 1.1.1 =
41
* First public release.
42
43
-
44
== Credits ==
45
46
* <a href="http://sucuri.net">Sucuri Security</a>
1
+ === Sucuri Security - SiteCheck Malware Scanner ===
2
Contributors: dd@sucuri.net, dremeda
3
Donate Link: http://sitecheck.sucuri.net
4
+ Tags: malware, security, scan, spam, virus, sucuri, WordPress,
5
+ Requires at least:3.2
6
+ Stable tag:1.3
7
+ Tested up to: 3.6
8
9
+ The Sucuri Security - SiteCheck Malware Scanner plugin enables you to scan your WordPress site using Sucuri SiteCheck right in your dashboard.
10
11
== Description ==
12
13
+ Sucuri SiteCheck will check for malware, spam, blacklisting and other security issues like .htaccess redirects, hidden eval code, etc. The best thing about it is it's completely free.
14
15
+ You can also scan your site at <a href="http://sitecheck.sucuri.net">SiteCheck.Sucuri.net</a>.
16
+
17
+ Sucuri SiteCheck detects various types of malware, SPAM injections, website errors, disabled sites, database connection issues and code anomalies that require special attention to include:
18
+
19
+ * Obfuscated JavaScript injections
20
+ * Cross Site Scripting (XSS)
21
+ * Website Defacements
22
+ * Hidden & Malicious iFrames
23
+ * PHP Mailers
24
+ * Phishing Attempts
25
+ * Malicious Redirects
26
+ * Backdoors (e.g., C99, R57, Webshells)
27
+ * Anomalies
28
+ * Drive-by-Downloads
29
+ * IP Cloaking
30
+ * Social Engineering Attacks
31
+
32
+
33
+ There are a number of blacklisting authorities that monitor for malware, SPAM, and phishing attempts. Sucuri SiteCheck leverages the APIs for these authorities to check your website blacklisting status:
34
+
35
+ * Sucuri
36
+ * Google Safe Browsing
37
+ * Norton
38
+ * AVG
39
+ * Phish Tank (Phishing Specifically)
40
+ * McAfee SiteAdvisor
41
+ * Yandex
42
+
43
+ We augment the SiteCheck Malware Scanner with various. 1-click hardening options. Some of these options do not provide a high level of security, but collectively these options do lower your risk floor:
44
+
45
+ * Verify WordPress Version
46
+ * Protect Uploads Directory
47
+ * Restrict wp-content Access
48
+ * Restrict wp-includes Access
49
+ * Verify PHP Version
50
51
52
== Installation ==
53
54
1. Download the plugin.
55
+ 1. Go to the WordPress Plugin menu and activate it.
56
1. That's it!
57
58
59
== Changelog ==
60
61
+ = 1.3 =
62
+ * Removed some PHP warnings and code clean up.
63
+ * Added WordPress integrity checks.
64
+ * Added plugin/theme/user checks.
65
+
66
+ = 1.2.2 =
67
+ * Tested on WP 3.5.1
68
+
69
+ = 1.2.1 =
70
+ * Tested on WP 3.5-RC4
71
+ * Style changes
72
+
73
+ = 1.2 =
74
+ * Cleared PHP warnings
75
+ * Added /inc directory
76
+ * Added /lib directory
77
+ * Logo added
78
+ * Default stylesheet added
79
+ * Header area added
80
+ * Sidebar area added
81
+ * Restyled 1-click hardening page
82
+ * Removed old malware page
83
+
84
+ = 1.1.7 =
85
+ * Tested on WP 3.5-RC3.
86
+
87
= 1.1.6 =
88
* Upgrading for WP 3.3.
89
90
= 1.1.5 =
91
+ * Removed PHP warnings / code cleaning.
92
93
= 1.1.3 =
94
* Cleaning up the results.
100
= 1.1.1 =
101
* First public release.
102
103
== Credits ==
104
105
* <a href="http://sucuri.net">Sucuri Security</a>
sucuri.php CHANGED
@@ -1,14 +1,16 @@
1
<?php
2
/*
3
- Plugin Name: Sucuri Scanner
4
Plugin URI: http://sitecheck.sucuri.net/
5
- Description: This plugin allows you to scan your website using the Sucuri SiteCheck Malware Scanner on your WordPress site. It will check for malware, spam, blacklisting and other security issues (htaccess redirections, hidden code, etc). Yes, it is free. Similar to the scans provided online at http://sitecheck.sucuri.net
6
- Author: http://sucuri.net
7
- Version: 1.1.6
8
Author URI: http://sucuri.net
9
*/
10
11
-
12
/* No direct access. */
13
if(!function_exists('add_action'))
14
{
@@ -16,66 +18,46 @@ if(!function_exists('add_action'))
16
}
17
18
define('SUCURISCAN','sucuriscan');
19
- define('SUCURISCAN_VERSION','1.1.6');
20
define( 'SUCURI_URL',plugin_dir_url( __FILE__ ));
21
- define( 'SUCURI_IMG',SUCURI_URL.'images/');
22
23
24
25
/* Starting Sucuri Scan side bar. */
26
- function sucuriscan_menu()
27
{
28
- add_menu_page('Sucuri Scanner', 'Sucuri Scanner', 'manage_options',
29
- 'sucuriscan', 'sucuri_scan_page', SUCURI_IMG.'menu-icon.png');
30
add_submenu_page('sucuriscan', 'Sucuri Scanner', 'Sucuri Scanner', 'manage_options',
31
'sucuriscan', 'sucuri_scan_page');
32
33
add_submenu_page('sucuriscan', '1-click Hardening', '1-click Hardening', 'manage_options',
34
'sucuriscan_hardening', 'sucuriscan_hardening_page');
35
36
- add_submenu_page('sucuriscan', 'Malware removal', 'Malware removal', 'manage_options',
37
- 'sucuriscan_removal', 'sucuri_removal_page');
38
- }
39
-
40
-
41
-
42
- function sucuri_removal_page()
43
- {
44
- if(!current_user_can('manage_options'))
45
- {
46
- wp_die(__('You do not have sufficient permissions to access this page.') );
47
- }
48
-
49
-
50
- /* Hardening page. */
51
- echo '<div class="wrap">';
52
- echo '<h2>Sucuri Malware Removal</h2>';
53
-
54
- echo '<h3>Get your site 100% clean and malware/blacklist free.</h3>';
55
-
56
- echo "<hr />";
57
-
58
- echo "<p>If our scanner is identifying any security problems on your site, we can get that
59
- cleaned for you. Just sign up with us here: <a href='http://sucuri.net/signup'>http://sucuri.net/signup</a> and our team will take care of it for you.</p>";
60
- echo "<hr />";
61
- echo "<h3>Get your site cleaned in under 4 hours (3 simple steps)</h3>";
62
- echo "<ol>";
63
- echo "<li>Sign up here: <a href='http://sucuri.net/signup'>http://sucuri.net/signup</a></li>";
64
- echo "<li>Click on malware removal request (inside the support page)</li>";
65
- echo "<li>Done! Go grab a coffee and wait for us to get it done</li>";
66
- echo "</ol>";
67
- ?>
68
- <br /><br />
69
- <b>If you have any questions about these checks or this plugin, contact us at support@sucuri.net or visit <a href="http://sucuri.net">http://sucuri.net</a></b>
70
- <br />
71
-
72
- </div>
73
- <?php
74
}
75
76
-
77
-
78
/* Sucuri malware scan page. */
79
function sucuri_scan_page()
80
{
81
$U_ERROR = NULL;
@@ -84,36 +66,45 @@ function sucuri_scan_page()
84
wp_die(__('You do not have sufficient permissions to access this page.') );
85
}
86
87
-
88
if(isset($_POST['wpsucuri-doscan']))
89
{
90
sucuriscan_print_scan();
91
return(1);
92
}
93
94
-
95
/* Setting's header. */
96
echo '<div class="wrap">';
97
- echo '<h2>Sucuri SiteCheck Malware Scanner</h2>';
98
-
99
100
- echo '<h3>Scan your site for malware using <a href="http://sitecheck.sucuri.net">Sucuri SiteCheck</a> right in your WordPress dashboard. The Sucuri SiteCheck scans will let you know if your site is compromised with malware, blackhat spam, website defacement, or if you are blacklisted.</h3>';
101
- ?>
102
103
- <form action="" method="post">
104
- <input type="hidden" name="wpsucuri-doscan" value="wpsucuri-doscan" />
105
- <input class="button-primary" type="submit" name="wpsucuri_doscanrun" value="Scan this site now!" />
106
- </form>
107
108
- <br /><br />
109
- <strong>If you have any questions about these checks or this plugin, contact us at support@sucuri.net or visit <a href="http://sucuri.net">sucuri.net</a></strong>
110
- <br />
111
- </div>
112
113
- <?php
114
- }
115
116
117
118
function sucuriscan_print_scan()
119
{
@@ -125,11 +116,16 @@ function sucuriscan_print_scan()
125
return;
126
}
127
128
-
129
$res = unserialize($myresults['body']);
130
131
echo '<div class="wrap">';
132
- echo '<h2>Sucuri SiteCheck Malware Scanner</h2>';
133
134
if(!isset($res['MALWARE']['WARN']))
135
{
@@ -165,7 +161,6 @@ function sucuriscan_print_scan()
165
}
166
echo '<i>More details here <a href="http://sitecheck.sucuri.net/scanner/?&scan='.home_url().'">http://sitecheck.sucuri.net/scanner/?&scan='.home_url().'</a></i>';
167
168
-
169
echo "<hr />\n";
170
if(isset($res['BLACKLIST']['WARN']))
171
{
@@ -179,10 +174,12 @@ function sucuriscan_print_scan()
179
'.site_url().'/wp-content/plugins/sucuri-scanner/images/ok.png" /> &nbsp;
180
Site blacklist-free</h3>';
181
}
182
-
183
- foreach($res['BLACKLIST']['INFO'] as $blres)
184
{
185
- echo "<b>CLEAN: </b>".htmlspecialchars($blres[0])." <a href=''>".htmlspecialchars($blres[1])."</a><br />";
186
}
187
if(isset($res['BLACKLIST']['WARN']))
188
{
@@ -192,10 +189,9 @@ function sucuriscan_print_scan()
192
}
193
}
194
195
-
196
echo "<hr />\n";
197
global $wp_version;
198
- if(strcmp($wp_version, "3.3") >= 0)
199
{
200
echo '<h3><img style="position:relative;top:5px" height="22" width="22" src="
201
'.site_url().'/wp-content/plugins/sucuri-scanner/images/ok.png" /> &nbsp;
@@ -208,78 +204,125 @@ function sucuriscan_print_scan()
208
System info (WordPress outdated)</h3>';
209
}
210
211
-
212
echo "<b>Site:</b> ".$res['SCAN']['SITE'][0]." (".$res['SCAN']['IP'][0].")<br />\n";
213
echo "<b>WordPress: </b> $wp_version<br />\n";
214
echo "<b>PHP: </b> ".phpversion()."<br />\n";
215
- foreach($res['SYSTEM']['NOTICE'] as $notres)
216
{
217
- if(is_array($notres))
218
- {
219
- echo htmlspecialchars($notres[0]). " ".htmlspecialchars($notres[1]);
220
- }
221
- else
222
{
223
- echo htmlspecialchars($notres)."<br />\n";
224
}
225
}
226
227
?>
228
- <br /><br />
229
- <b>If you have any questions about these scan results, or this plugin, contact us at support@sucuri.net or visit <a href="http://sucuri.net">http://sucuri.net</a></b>
230
- <br />
231
- </div>
232
<?php
233
}
234
235
236
- /* Sucuri one-click hardening page. */
237
- function sucuriscan_hardening_page()
238
{
239
if(!current_user_can('manage_options'))
240
{
241
wp_die(__('You do not have sufficient permissions to access this page.') );
242
}
243
- include_once("sucuriscan_hardening.php");
244
245
246
247
/* Hardening page. */
248
echo '<div class="wrap">';
249
- echo '<h2>Sucuri 1-Click WordPress Hardening</h2>';
250
-
251
- echo '<h3>Secure your WordPress with a one-click hardening.</h3>';
252
-
253
- echo "<hr />";
254
- sucuriscan_harden_version();
255
- echo "<hr />";
256
- sucuriscan_harden_removegenerator();
257
- echo "<hr />";
258
- sucuriscan_harden_upload();
259
- echo "<hr />";
260
- sucuriscan_harden_dbtables();
261
- echo "<hr />";
262
- sucuriscan_harden_adminuser();
263
- echo "<hr />";
264
- sucuriscan_harden_readme();
265
- echo "<hr />";
266
- sucuriscan_harden_phpversion();
267
- echo "<hr />";
268
?>
269
- <br /><br />
270
- <b>If you have any question about these checks or this plugin, contact us at support@sucuri.net or visit <a href="http://sucuri.net">http://sucuri.net</a></b>
271
- <br />
272
273
- </div>
274
<?php
275
}
276
277
278
279
280
/* Sucuri's admin menu. */
281
add_action('admin_menu', 'sucuriscan_menu');
282
remove_action('wp_head', 'wp_generator');
283
284
-
285
?>
1
<?php
2
/*
3
+ Plugin Name: Sucuri Security - SiteCheck Malware Scanner
4
Plugin URI: http://sitecheck.sucuri.net/
5
+ Description: The <a href="http://sucuri.net">Sucuri Security</a> - SiteCheck Malware Scanner plugin enables you to <strong>scan your WordPress site using <a href="http://sitecheck.sucuri.net">Sucuri SiteCheck</a></strong> right in your WordPress dashboard. SiteCheck will check for malware, spam, blacklisting and other security issues like .htaccess redirects, hidden eval code, etc. The best thing about it is it's completely free.
6
+
7
+ You can also scan your site at <a href="http://sitecheck.sucuri.net">SiteCheck.Sucuri.net</a>.
8
+
9
+ Author: Sucuri Security
10
+ Version: 1.3
11
Author URI: http://sucuri.net
12
*/
13
14
/* No direct access. */
15
if(!function_exists('add_action'))
16
{
18
}
19
20
define('SUCURISCAN','sucuriscan');
21
+ define('SUCURISCAN_VERSION','1.3');
22
define( 'SUCURI_URL',plugin_dir_url( __FILE__ ));
23
24
+ /* Requires files. */
25
+ //require_once(dirname(__FILE__ ) . '/inc/scripts.php');
26
+ add_action( 'admin_enqueue_scripts', 'sucuriscan_admin_script_style_registration', 1 );
27
+ function sucuriscan_admin_script_style_registration() {
28
29
+ echo '<link rel="stylesheet" href="'.SUCURI_URL.'/inc/css/sucuriscan-default-css.css" type="text/css" media="all" />';
30
+
31
+ }
32
+
33
+ /* sucuri_dir_filepath:
34
+ * Returns the system filepath to the relevant user uploads
35
+ * directory for this site. Multisite capable.
36
+ */
37
+ function sucuriscan_dir_filepath($path = '')
38
+ {
39
+ $wp_dir_array = wp_upload_dir();
40
+ $wp_dir_array['basedir'] = untrailingslashit($wp_dir_array['basedir']);
41
+ return($wp_dir_array['basedir']."/sucuri/$path");
42
+ }
43
44
/* Starting Sucuri Scan side bar. */
45
+ function sucuriscan_menu()
46
{
47
+ add_menu_page('Sucuri Free', 'Sucuri Free', 'manage_options',
48
+ 'sucuriscan', 'sucuri_scan_page', SUCURI_URL.'images/menu-icon.png');
49
add_submenu_page('sucuriscan', 'Sucuri Scanner', 'Sucuri Scanner', 'manage_options',
50
'sucuriscan', 'sucuri_scan_page');
51
52
add_submenu_page('sucuriscan', '1-click Hardening', '1-click Hardening', 'manage_options',
53
'sucuriscan_hardening', 'sucuriscan_hardening_page');
54
55
+ add_submenu_page('sucuriscan', 'WordPress Integrity', 'WordPress Integrity', 'manage_options',
56
+ 'sucuriscan_core_integrity', 'sucuriscan_core_integrity_page');
57
}
58
59
/* Sucuri malware scan page. */
60
+
61
function sucuri_scan_page()
62
{
63
$U_ERROR = NULL;
66
wp_die(__('You do not have sufficient permissions to access this page.') );
67
}
68
69
if(isset($_POST['wpsucuri-doscan']))
70
{
71
sucuriscan_print_scan();
72
return(1);
73
}
74
75
/* Setting's header. */
76
echo '<div class="wrap">';
77
+ echo '<h2 id="warnings_hook"></h2>';
78
+ echo '<div class="sucuriscan_header"><img src="'.SUCURI_URL.'/inc/images/logo.png">';
79
+ sucuriscan_pagestop("SiteCheck Scanner");
80
+ echo '</div>';
81
82
+ echo '<div class="postbox-container" style="width:75%;">';
83
+ echo '<div class="sucuriscan-maincontent">';
84
85
+ echo '<div class="postbox">';
86
+ echo '<div class="inside">';
87
+ echo '<h2 align="center">Scan your site for malware using <a href="http://sitecheck.sucuri.net">Sucuri SiteCheck</a> right in your WordPress dashboard.</h2>';
88
+ echo '</div>';
89
+ echo '</div>';
90
+ ?>
91
92
+ <form action="" method="post">
93
+ <input type="hidden" name="wpsucuri-doscan" value="wpsucuri-doscan" />
94
+ <input class="button-primary" type="submit" name="wpsucuri_doscanrun" value="Scan this site now!" />
95
+ </form>
96
97
+ <p><strong>If you have any questions about these checks or this plugin, contact us at support@sucuri.net or visit <a href="http://sucuri.net">sucuri.net</a></strong></p>
98
+
99
+ </div><!-- End sucuriscan-maincontent -->
100
+ </div><!-- End postbox-container -->
101
102
+ <?php include_once("lib/sidebar.php"); ?>
103
104
+ </div><!-- End Wrap -->
105
+
106
+ <?php
107
+ }
108
109
function sucuriscan_print_scan()
110
{
116
return;
117
}
118
119
$res = unserialize($myresults['body']);
120
121
echo '<div class="wrap">';
122
+ echo '<h2 id="warnings_hook"></h2>';
123
+ echo '<div class="sucuriscan_header"><img src="'.SUCURI_URL.'/inc/images/logo.png">';
124
+ sucuriscan_pagestop("Sucuri SiteCheck Malware Scanner");
125
+ echo '</div>';
126
+
127
+ echo '<div class="postbox-container" style="width:75%;">';
128
+ echo '<div class="sucuriscan-maincontent">';
129
130
if(!isset($res['MALWARE']['WARN']))
131
{
161
}
162
echo '<i>More details here <a href="http://sitecheck.sucuri.net/scanner/?&scan='.home_url().'">http://sitecheck.sucuri.net/scanner/?&scan='.home_url().'</a></i>';
163
164
echo "<hr />\n";
165
if(isset($res['BLACKLIST']['WARN']))
166
{
174
'.site_url().'/wp-content/plugins/sucuri-scanner/images/ok.png" /> &nbsp;
175
Site blacklist-free</h3>';
176
}
177
+ if(isset($res['BLACKLIST']['INFO']))
178
{
179
+ foreach($res['BLACKLIST']['INFO'] as $blres)
180
+ {
181
+ echo "<b>CLEAN: </b>".htmlspecialchars($blres[0])." <a href=''>".htmlspecialchars($blres[1])."</a><br />";
182
+ }
183
}
184
if(isset($res['BLACKLIST']['WARN']))
185
{
189
}
190
}
191
192
echo "<hr />\n";
193
global $wp_version;
194
+ if(strcmp($wp_version, "3.5") >= 0)
195
{
196
echo '<h3><img style="position:relative;top:5px" height="22" width="22" src="
197
'.site_url().'/wp-content/plugins/sucuri-scanner/images/ok.png" /> &nbsp;
204
System info (WordPress outdated)</h3>';
205
}
206
207
echo "<b>Site:</b> ".$res['SCAN']['SITE'][0]." (".$res['SCAN']['IP'][0].")<br />\n";
208
echo "<b>WordPress: </b> $wp_version<br />\n";
209
echo "<b>PHP: </b> ".phpversion()."<br />\n";
210
+
211
+ if(isset($res['SYSTEM']['NOTICE']))
212
{
213
+ foreach($res['SYSTEM']['NOTICE'] as $notres)
214
{
215
+ if(is_array($notres))
216
+ {
217
+ echo htmlspecialchars($notres[0]). " ".htmlspecialchars($notres[1]);
218
+ }
219
+ else
220
+ {
221
+ echo htmlspecialchars($notres)."<br />\n";
222
+ }
223
}
224
}
225
226
?>
227
+ <p>If you have any questions about these checks or this plugin, contact us at support@sucuri.net or visit <a href="http://sucuri.net">http://sucuri.net</a></p>
228
+
229
+ </div><!-- End sucuriscan-maincontent -->
230
+ </div><!-- End postbox-container -->
231
+
232
+ <?php include_once("lib/sidebar.php"); ?>
233
+
234
+ </div><!-- End Wrap -->
235
+
236
<?php
237
}
238
239
+ /* Sucuri Header Function */
240
241
+ function sucuriscan_pagestop($sucuri_title = 'Sucuri Plugin')
242
{
243
if(!current_user_can('manage_options'))
244
{
245
wp_die(__('You do not have sufficient permissions to access this page.') );
246
}
247
+ ?>
248
+ <h2><?php echo htmlspecialchars($sucuri_title); ?></h2>
249
+ <br class="clear"/>
250
+ <?php
251
+ }
252
253
+ /* Sucuri one-click hardening page. */
254
+
255
+ function sucuriscan_hardening_page()
256
257
+ {
258
259
/* Hardening page. */
260
+
261
echo '<div class="wrap">';
262
+ echo '<h2 id="warnings_hook"></h2>';
263
+ echo '<div class="sucuriscan_header"><img src="'.SUCURI_URL.'/inc/images/logo.png">';
264
+ sucuriscan_pagestop("Sucuri 1-Click Hardening Options");
265
+ echo '</div>';
266
+
267
+ if(!current_user_can('manage_options'))
268
+ {
269
+ wp_die(__('You do not have sufficient permissions to access this page.') );
270
+ }
271
+
272
+ include_once("sucuriscan_hardening.php");
273
+
274
+ sucuriscan_hardening_lib()
275
+
276
?>
277
278
+ </div><!-- End sucuriscan-maincontent -->
279
+ </div><!-- End postbox-container -->
280
+
281
+ <?php include_once("lib/sidebar.php"); ?>
282
+
283
+ </div><!-- End Wrap -->
284
+
285
<?php
286
}
287
288
+ /* Sucuri WordPress Integrity page. */
289
+
290
+ function sucuriscan_core_integrity_page()
291
+
292
+ {
293
294
+ /* WordPress Integrity page. */
295
296
+ echo '<div class="wrap">';
297
+ echo '<h2 id="warnings_hook"></h2>';
298
+ echo '<div class="sucuriscan_header"><img src="'.SUCURI_URL.'/inc/images/logo.png">';
299
+ sucuriscan_pagestop("Sucuri WordPress Integrity");
300
+ echo '</div>';
301
+
302
+ if(!current_user_can('manage_options'))
303
+ {
304
+ wp_die(__('You do not have sufficient permissions to access this page.') );
305
+ }
306
+
307
+ include_once("sucuriscan_core_integrity.php");
308
+
309
+ sucuriscan_core_integrity_lib()
310
+
311
+ ?>
312
+
313
+ </div><!-- End sucuriscan-maincontent -->
314
+ </div><!-- End postbox-container -->
315
+
316
+ <?php include_once("lib/sidebar.php"); ?>
317
+
318
+ </div><!-- End Wrap -->
319
+
320
+ <?php
321
+ }
322
323
/* Sucuri's admin menu. */
324
+
325
add_action('admin_menu', 'sucuriscan_menu');
326
remove_action('wp_head', 'wp_generator');
327
328
?>
sucuriscan_core_integrity.php ADDED
@@ -0,0 +1,89 @@
1
+ <?php
2
+ /* Sucuri Security - SiteCheck Malware Scanner
3
+ * Copyright (C) 2010-2012 Sucuri Security - http://sucuri.net
4
+ * Released under the GPL - see LICENSE file for details.
5
+ */
6
+
7
+
8
+ if(!defined('SUCURISCAN'))
9
+ {
10
+ return(0);
11
+ }
12
+
13
+ /* Sucuri WordPress Integrity page. */
14
+
15
+ function sucuriscan_core_integrity_function_wrapper($function_name, $description)
16
+ {
17
+ echo '<div class="postbox">';
18
+ echo '<div class="inside">';
19
+ echo '<form action="" method="post">'.
20
+ '<input type="hidden" name="'.$function_name.'nonce" value="'.wp_create_nonce($function_name.'nonce').'" />'.
21
+ '<input type="hidden" name="'.$function_name.'" value="'.$function_name.'" />'.
22
+
23
+ '<p>'.$description.'</p>'.
24
+ '<input class="button-primary" type="submit" name="'.$function_name.'" value="Check">'.
25
+ '</form>';
26
+ echo '</div>';
27
+ echo '</div>';
28
+
29
+ if (isset($_POST[$function_name.'nonce']) && isset($_POST[$function_name])) {
30
+ $function_name();
31
+ }
32
+ }
33
+
34
+ function sucuriscan_core_integrity_lib()
35
+ {
36
+ echo '<h2 id="warnings_hook"></h2>';
37
+ echo '<div class="postbox-container" style="width:75%;">';
38
+ echo '<div class="sucuriscan-maincontent">';
39
+
40
+ echo '<div class="postbox">';
41
+ echo '<div class="inside">';
42
+ echo '<h2 align="center">Sucuri WordPress Integrity Checks</h2>';
43
+ echo '</div>';
44
+ echo '</div>';
45
+
46
+ include_once("lib/core_integrity.php");
47
+
48
+ if(isset($_POST['wpsucuri-core-integrity']))
49
+ {
50
+ if(!wp_verify_nonce($_POST['sucuriscan_core_integritynonce'], 'sucuriscan_core_integritynonce'))
51
+ {
52
+ unset($_POST['wpsucuri-core_integrity']);
53
+ }
54
+ }
55
+
56
+ ?>
57
+
58
+ <div id="poststuff">
59
+
60
+ <?php
61
+
62
+ sucuriscan_core_integrity_function_wrapper(
63
+ 'sucuriwp_core_integrity_check',
64
+ 'Check wp-include, wp-admin, and top directory files against the latest WordPress version.'
65
+ );
66
+ sucuriscan_core_integrity_function_wrapper(
67
+ 'sucuriwp_list_admins',
68
+ 'Check Administrator Users.'
69
+ );
70
+ sucuriscan_core_integrity_function_wrapper(
71
+ 'sucuriwp_content_check',
72
+ 'Check wp-content files modified in the past 3 days.'
73
+ );
74
+ sucuriscan_core_integrity_function_wrapper(
75
+ 'sucuriwp_check_plugins',
76
+ 'Check outdated active plugins in there.'
77
+ );
78
+ sucuriscan_core_integrity_function_wrapper(
79
+ 'sucuriwp_check_themes',
80
+ 'Check outdated themes in there.'
81
+ );
82
+ ?>
83
+
84
+ </div>
85
+
86
+ <p align="center"><strong>If you have any questions about these checks or this plugin, contact us at support@sucuri.net or visit <a href="http://sucuri.net">Sucuri Security</a></strong></p>
87
+
88
+ <?php
89
+ }
sucuriscan_hardening.php CHANGED
@@ -1,334 +1,61 @@
1
<?php
2
- /* Sucuri Security WordPress Plugin
3
- * Copyright (C) 2011 Sucuri Security - http://sucuri.net
4
* Released under the GPL - see LICENSE file for details.
5
*/
6
7
8
if(!defined('SUCURISCAN'))
9
{
10
- exit(0);
11
}
12
13
- if(!function_exists('file_put_contents'))
14
- {
15
- exit(0);
16
- }
17
18
-
19
- if(isset($_POST['wpscansucuri-doharden']) &&
20
- !wp_verify_nonce($_POST['sucuriscan-harden-action'],'sucuriscan-nonce'))
21
{
22
- echo '<div id="message" class="error"><p>Internal error. Please try again.</p></div>';
23
- return;
24
- }
25
26
27
- function sucuriscan_harden_error($message)
28
- {
29
- return('<div id="message" class="error"><p>'.$message.'</p></div>');
30
- }
31
32
-
33
- function sucuriscan_harden_ok($message)
34
- {
35
- return( '<div id="message" class="updated"><p>'.$message.'</p></div>');
36
- }
37
-
38
-
39
- function sucuriscan_harden_status($status, $type, $messageok, $messagewarn,
40
- $desc = NULL, $updatemsg = NULL)
41
- {
42
- if($status == 1)
43
- {
44
- echo '<h3>'.
45
- '<img style="position:relative;top:5px" height="22" width="22"'.
46
- 'src="'.site_url().
47
- '/wp-content/plugins/sucuri-scanner/images/ok.png" /> &nbsp; '.
48
- $messageok.'.</h3>';
49
-
50
- if($updatemsg != NULL){ echo $updatemsg; }
51
- }
52
- else
53
{
54
- echo '<h3>'.
55
- '<img style="position:relative;top:5px" height="22" width="22"'.
56
- 'src="'.site_url().
57
- '/wp-content/plugins/sucuri-scanner/images/warn.png" /> &nbsp; '.
58
- $messagewarn. '.</h3>';
59
-
60
- if($updatemsg != NULL){ echo $updatemsg; }
61
-
62
- if($type != NULL)
63
{
64
- echo '<form action="" method="post">'.
65
- wp_nonce_field('sucuriscan-nonce', 'sucuriscan-harden-action').
66
- '<input type="hidden" name="wpscansucuri-doharden" value="wpscansucuri-doharden" />'.
67
- '<input type="hidden" name="'.$type.'" '.
68
- 'value="'.$type.'" />'.
69
- '<input class="button-primary" type="submit" name="wpscansucuri-dohardenform" value="Harden it!" />'.
70
- '</form><br />';
71
}
72
}
73
- if($desc != NULL)
74
- {
75
- echo "<i>$desc</i>";
76
- }
77
-
78
- }
79
-
80
-
81
- function sucuriscan_harden_version()
82
- {
83
- global $wp_version;
84
- $cp = 0;
85
- $updates = get_core_updates();
86
- if (!is_array($updates))
87
- {
88
- $cp = 1;
89
- }
90
- else if(empty($updates))
91
- {
92
- $cp = 1;
93
- }
94
- else if($updates[0]->response == 'latest')
95
- {
96
- $cp = 1;
97
- }
98
- if(strcmp($wp_version, "3.3") < 0)
99
- {
100
- $cp = 0;
101
- }
102
-
103
-
104
- sucuriscan_harden_status($cp, NULL,
105
- "WordPress is updated", "WordPress is not updated",
106
- NULL);
107
-
108
- if($cp == 0)
109
- {
110
- echo "<i>Your current version ($wp_version) is not current. Please update it <a href='update-core.php'>now!</a></i>";
111
- }
112
- else
113
- {
114
- echo "<i>Your WordPress installation ($wp_version) is current.</i>";
115
- }
116
- }
117
-
118
-
119
- function sucuriscan_harden_removegenerator()
120
- {
121
- /* Enabled by default with this plugin. */
122
- $cp = 1;
123
-
124
- sucuriscan_harden_status($cp, "sucuri_harden_removegenerator",
125
- "WordPress version properly hidden", NULL,
126
- "It checks if your WordPress version is being hidden".
127
- " from being displayed in the generator tag ".
128
- "(enabled by default with this plugin).");
129
- }
130
131
132
133
- function sucuriscan_harden_upload()
134
- {
135
- $cp = 1;
136
- $upmsg = NULL;
137
- if(!is_readable(ABSPATH."/wp-content/uploads/.htaccess"))
138
- {
139
- $cp = 0;
140
- }
141
- else
142
- {
143
- $cp = 0;
144
- $fcontent = file(ABSPATH."/wp-content/uploads/.htaccess");
145
- foreach($fcontent as $fline)
146
- {
147
- if(strpos($fline, "deny from all") !== FALSE)
148
- {
149
- $cp = 1;
150
- break;
151
- }
152
- }
153
- }
154
-
155
- if(isset($_POST['sucuriscan_harden_upload']) && isset($_POST['wpscansucuri-doharden']) &&
156
- $cp == 0)
157
- {
158
- if(file_put_contents(ABSPATH."/wp-content/uploads/.htaccess",
159
- "\n".
160
- "<Files *.php>\ndeny from all\n</Files>")===FALSE)
161
- {
162
- $upmsg = sucuriscan_harden_error("ERROR: Unable to create .htaccess file.");
163
- }
164
- else
165
- {
166
- $upmsg = sucuriscan_harden_ok("Completed. Upload directory successfully secured.");
167
- $cp = 1;
168
- }
169
- }
170
-
171
- sucuriscan_harden_status($cp, "sucuriscan_harden_upload",
172
- "Upload directory properly protected",
173
- "Upload directory not protected",
174
- "It checks if your upload directory allows PHP ".
175
- "execution or if it is browsable.", $upmsg);
176
- }
177
-
178
-
179
-
180
- function sucuriscan_harden_dbtables()
181
- {
182
- global $table_prefix;
183
-
184
-
185
- if($table_prefix == "wp_")
186
- {
187
- $cp = 0;
188
- }
189
- else
190
- {
191
- $cp = 1;
192
- }
193
-
194
- sucuriscan_harden_status($cp, "sucuri_harden_dbtables",
195
- "Database table prefix properly modified",
196
- "Database table set to the default value. Not recommended",
197
- "It checks whether your database table prefix has ".
198
- "been changed from the default 'wp_'.");
199
-
200
- if($cp == 0)
201
- {
202
- echo '<br /><i>*We do not offer the option to automatically change the table prefix, but it will be available soon on a next release.</i>';
203
- }
204
- }
205
-
206
-
207
-
208
- function sucuriscan_harden_adminuser()
209
- {
210
- global $table_prefix;
211
- global $wpdb;
212
- $upmsg = NULL;
213
-
214
- $res = $wpdb->get_results("SELECT user_login from ".
215
- $table_prefix."users where user_login='admin'");
216
-
217
- $cp = 0;
218
- if(count($res) == 0)
219
- {
220
- $cp = 1;
221
- }
222
- if(isset($_POST['sucuriscan_harden_adminuser']) && isset($_POST['wpscansucuri-doharden']) &&
223
- $cp == 0)
224
- {
225
- if(!isset($_POST['sucuriscan_harden_adminusernew']))
226
- {
227
- $upmsg = sucuriscan_harden_error("New admin user name not chosen.");
228
- }
229
- else
230
- {
231
- $_POST['sucuriscan_harden_adminusernew'] = trim($_POST['sucuri_harden_adminusernew']);
232
- $_POST['sucuriscan_harden_adminusernew'] = htmlspecialchars($_POST['sucuri_harden_adminusernew']);
233
-
234
- if(strlen($_POST['sucuriscan_harden_adminusernew']) < 2)
235
- {
236
- $upmsg = sucuriscan_harden_error("New admin user name not chosen.");
237
- }
238
- else if(!preg_match('/^[a-zA-Z0-9_-]+#x2F;',
239
- $_POST['sucuriscan_harden_adminusernew'], $regs,
240
- PREG_OFFSET_CAPTURE, 0))
241
- {
242
- $upmsg = sucuriscan_harden_error("Invalid user name. Only letters and numbers are allowed.");
243
- }
244
- else
245
- {
246
- $res = $wpdb->query("UPDATE ".$table_prefix."users ".
247
- "SET user_login = '".
248
- $_POST['sucuriscan_harden_adminusernew']."'".
249
- "WHERE user_login='admin'");
250
- $cp = 1;
251
- $upmsg = sucuriscan_harden_ok("User name changed to: ".
252
- $_POST['sucuriscan_harden_adminusernew'].
253
- ". You will be now logged out.");
254
- }
255
- }
256
- }
257
-
258
- sucuriscan_harden_status($cp, NULL,
259
- "Default admin user name (admin) not being used",
260
- "Default admin user name (admin) being used. Not recommended",
261
- "It checks whether you have the default 'admin' ".
262
- "account enabled. Security guidelines recommend ".
263
- "creating a new admin user name.", $upmsg);
264
-
265
- if($cp == 0)
266
- {
267
- echo '<br />&nbsp;<br />Choose your new admin name (used to login):';
268
- echo '<form action="" method="post">'.
269
- wp_nonce_field('sucuriscan-nonce', 'sucuriscan-harden-action').
270
- '<input type="hidden" name="wpscansucuri-doharden" value="wpscansucuri-doharden" />'.
271
- '<input type="hidden" name="sucuriscan_harden_adminuser" '.
272
- 'value="sucuriscan_harden_adminuser" />'.
273
- '<input type="text" name="sucuriscan_harden_adminusernew" value="" />'.
274
- '<input type="submit" name="wpsucuri-dohardenform" value="Rename the admin user" />'.
275
- '</form>';
276
- echo '<b>*Make sure you remember your new admin login name! '.
277
- 'Otherwise you will not be able to login back. You will be logged out after changing it!</b>';
278
- }
279
- }
280
-
281
-
282
-
283
- function sucuriscan_harden_readme()
284
- {
285
- $upmsg = NULL;
286
- $cp = 0;
287
- if(!is_readable(ABSPATH."/readme.html"))
288
- {
289
- $cp = 1;
290
- }
291
-
292
- if(isset($_POST['sucuriscan_harden_readme']) &&
293
- isset($_POST['wpscansucuri-doharden']) &&
294
- $cp == 0)
295
- {
296
- if(unlink(ABSPATH."/readme.html") === FALSE)
297
- {
298
- $upmsg = sucuriscan_harden_error("Unable to remove readme file.");
299
- }
300
- else
301
- {
302
- $cp = 1;
303
- $upmsg = sucuriscan_harden_ok("Readme file removed.");
304
- }
305
- }
306
-
307
- sucuriscan_harden_status($cp, "sucuriscan_harden_readme",
308
- "Readme file properly deleted",
309
- "Readme file not deleted and leaking the WordPress version",
310
- "It checks whether you have the readme.html file ".
311
- "available that leaks your WordPress version.", $upmsg);
312
- }
313
314
315
316
- function sucuriscan_harden_phpversion()
317
- {
318
- $phpv = phpversion();
319
320
- if(strncmp($phpv, "5.2", 3) < 0)
321
- {
322
- $cp = 0;
323
- }
324
- else
325
- {
326
- $cp = 1;
327
- }
328
329
- sucuriscan_harden_status($cp, NULL,
330
- "Using an updated version of PHP (v $phpv)",
331
- "The version of PHP you are using ($phpv) is not current. Not recommended and not supported",
332
- "It checks if you have the latest version of PHP installed.", NULL);
333
}
334
- ?>
1
<?php
2
+ /* Sucuri Security - SiteCheck Malware Scanner
3
+ * Copyright (C) 2010-2012 Sucuri Security - http://sucuri.net
4
* Released under the GPL - see LICENSE file for details.
5
*/
6
7
8
if(!defined('SUCURISCAN'))
9
{
10
+ return(0);
11
}
12
13
+ /* Sucuri one-click hardening page. */
14
15
+ function sucuriscan_hardening_lib()
16
{
17
+ echo '<h2 id="warnings_hook"></h2>';
18
+ echo '<div class="postbox-container" style="width:75%;">';
19
+ echo '<div class="sucuriscan-maincontent">';
20
21
+ echo '<div class="postbox">';
22
+ echo '<div class="inside">';
23
+ echo '<h2 align="center">Help secure your WordPress install with <a href="http://sucuri.net/signup">Sucuri</a> 1-Click Hardening Options.</h2>';
24
+ echo '</div>';
25
+ echo '</div>';
26
27
+ include_once("lib/hardening.php");
28
29
+ if(isset($_POST['wpsucuri-doharden']))
30
{
31
+ if(!wp_verify_nonce($_POST['sucuriscan_wphardeningnonce'], 'sucuriscan_wphardeningnonce'))
32
{
33
+ unset($_POST['wpsucuri-doharden']);
34
}
35
}
36
37
+ ?>
38
39
+ <div id="poststuff">
40
41
+ <?php
42
43
+ echo '<form action="" method="post">'.
44
+ '<input type="hidden" name="sucuriscan_wphardeningnonce" value="'.wp_create_nonce('sucuriscan_wphardeningnonce').'" />'.
45
+ '<input type="hidden" name="wpsucuri-doharden" value="wpsucuri-doharden" />'.
46
47
+ sucuriscan_harden_version();
48
+ sucuri_harden_removegenerator();
49
+ sucuriscan_harden_upload();
50
+ sucuriscan_harden_wpcontent();
51
+ sucuriscan_harden_wpincludes();
52
+ sucuriscan_harden_phpversion();
53
+ echo '</form>'
54
+ ?>
55
56
+ <p align="center"><strong>If you have any questions about these checks or this plugin, contact us at support@sucuri.net or visit <a href="http://sucuri.net">Sucuri Security</a></strong></p>
57
58
+ </div>
59
60
+ <?php
61
}