Version Description
- Added post-hack options (reset all passwords).
- Added last-login.
- Added more hardening and the option to revert any hardening done.
Download this release
Release Info
Developer | yorman |
Plugin | Sucuri Security – Auditing, Malware Scanner and Security Hardening |
Version | 1.4 |
Comparing to | |
See all releases |
Code changes from version 1.3 to 1.4
- inc/css/sucuriscan-default-css.css +8 -4
- inc/tpl/sucuri-wp-lastlogins.html.tpl +48 -0
- inc/tpl/sucuri-wp-lastlogins.snippet.tpl +9 -0
- inc/tpl/sucuri-wp-posthack.html.tpl +93 -0
- inc/tpl/sucuri-wp-resetpassword.snippet.tpl +8 -0
- inc/tpl/sucuri-wp-sidebar.html.tpl +22 -0
- lib/core_integrity.php +25 -5
- lib/hardening.php +118 -53
- readme.txt +18 -4
- sucuri.php +379 -9
- sucuriscan_core_integrity.php +6 -6
inc/css/sucuriscan-default-css.css
CHANGED
@@ -2,14 +2,14 @@
|
|
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;
|
@@ -27,7 +27,7 @@
|
|
27 |
float: left;
|
28 |
margin-left: 10px;
|
29 |
padding: 3px 0 0;
|
30 |
-
text-shadow:#000 0 1px 0;
|
31 |
}
|
32 |
|
33 |
.sucuriscan-maincontent {
|
@@ -56,4 +56,8 @@
|
|
56 |
#sucuri-latest-posts.sucuriscan-sidebar {
|
57 |
background-color:#ececec;
|
58 |
border-color:#999;
|
59 |
-
}
|
|
|
|
|
|
|
|
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;
|
27 |
float: left;
|
28 |
margin-left: 10px;
|
29 |
padding: 3px 0 0;
|
30 |
+
text-shadow:#000 0 1px 0;
|
31 |
}
|
32 |
|
33 |
.sucuriscan-maincontent {
|
56 |
#sucuri-latest-posts.sucuriscan-sidebar {
|
57 |
background-color:#ececec;
|
58 |
border-color:#999;
|
59 |
+
}
|
60 |
+
|
61 |
+
.sucuriscan-maincontent a.lastlogins-showall{
|
62 |
+
margin: 10px auto 0 auto;
|
63 |
+
}
|
inc/tpl/sucuri-wp-lastlogins.html.tpl
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wrap">
|
2 |
+
<h2 id="warnings_hook"></h2>
|
3 |
+
<div class="sucuriscan_header"><img src="%%SUCURI.SucuriURL%%/inc/images/logo.png">
|
4 |
+
<h2>Sucuri Security WordPress Plugin</h2>
|
5 |
+
</div>
|
6 |
+
|
7 |
+
<div class="postbox-container" style="width:75%;">
|
8 |
+
<div class="sucuriscan-maincontent">
|
9 |
+
<div class="postbox">
|
10 |
+
<div class="inside">
|
11 |
+
<h2 align="center">Sucuri Plugin Last-Logins</h2>
|
12 |
+
</div>
|
13 |
+
</div>
|
14 |
+
|
15 |
+
<div id="poststuff">
|
16 |
+
<div class="postbox">
|
17 |
+
<h3>Post-Hack - User logins (latest 10, newest to oldest)</h3>
|
18 |
+
<div class="inside">
|
19 |
+
<table class="wp-list-table widefat">
|
20 |
+
<thead>
|
21 |
+
<tr>
|
22 |
+
<th class="manage-column column-cb check-column">
|
23 |
+
<label class="screen-reader-text" for="cb-select-all-1">Select All</label>
|
24 |
+
<input id="cb-select-all-1" type="checkbox">
|
25 |
+
</th>
|
26 |
+
<th class="manage-column">Username</th>
|
27 |
+
<th class="manage-column">Email</th>
|
28 |
+
<th class="manage-column">IP Address</th>
|
29 |
+
<th class="manage-column">Date/Time</th>
|
30 |
+
</tr>
|
31 |
+
</thead>
|
32 |
+
|
33 |
+
<tbody>
|
34 |
+
%%SUCURI.UserList%%
|
35 |
+
</tbody>
|
36 |
+
</table>
|
37 |
+
|
38 |
+
<a href="%%SUCURI.CurrentURL%%&limit=0" class="button button-primary lastlogins-showall" style="%%SUCURI.UserList.ShowAll%%">Show all results</a>
|
39 |
+
</div>
|
40 |
+
</div>
|
41 |
+
</div><!-- End poststuff -->
|
42 |
+
|
43 |
+
</div><!-- End sucuriscan-maincontent -->
|
44 |
+
</div><!-- End postbox-container -->
|
45 |
+
|
46 |
+
%%SUCURI.SucuriWPSidebar%%
|
47 |
+
|
48 |
+
</div><!-- End wrap -->
|
inc/tpl/sucuri-wp-lastlogins.snippet.tpl
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<th class="check-column">
|
3 |
+
<input type="checkbox" name="user_ids[]" value="%%SUCURI.UserList.UserId%%" />
|
4 |
+
</th>
|
5 |
+
<td>%%SUCURI.UserList.Username%%</td>
|
6 |
+
<td><a href="mailto:%%SUCURI.UserList.Email%%">%%SUCURI.UserList.Email%%</a></td>
|
7 |
+
<td>%%SUCURI.UserList.RemoteAddr%%</td>
|
8 |
+
<td>%%SUCURI.UserList.Datetime%%</td>
|
9 |
+
</tr>
|
inc/tpl/sucuri-wp-posthack.html.tpl
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wrap">
|
2 |
+
<h2 id="warnings_hook"></h2>
|
3 |
+
<div class="sucuriscan_header"><img src="%%SUCURI.SucuriURL%%/inc/images/logo.png">
|
4 |
+
<h2>Sucuri Security WordPress Plugin</h2>
|
5 |
+
</div>
|
6 |
+
|
7 |
+
<div class="postbox-container" style="width:75%;">
|
8 |
+
<div class="sucuriscan-maincontent">
|
9 |
+
<div class="postbox">
|
10 |
+
<div class="inside">
|
11 |
+
<h2 align="center">Sucuri Plugin Post-Hack</h2>
|
12 |
+
</div>
|
13 |
+
</div>
|
14 |
+
|
15 |
+
<div id="poststuff">
|
16 |
+
<div class="postbox">
|
17 |
+
<h3>Post-Hack - Update WP-Config Keys</h3>
|
18 |
+
<div class="inside">
|
19 |
+
<form method="post">
|
20 |
+
<input type="hidden" name="sucuri_posthack_nonce" value="%%SUCURI.PosthackNonce%%" />
|
21 |
+
<input type="hidden" name="sucuri_posthack_action" value="update_wpconfig" />
|
22 |
+
|
23 |
+
<p>
|
24 |
+
Use this button to update the security keys stored in the <code>wp-config.php</code>
|
25 |
+
file, we will use the official Wordpress Secret-Key API Generator. After the
|
26 |
+
update your current session will be closed and you'll need to login again.
|
27 |
+
</p>
|
28 |
+
|
29 |
+
<p>
|
30 |
+
<input type="hidden" name="sucuri_update_wpconfig" value="0" />
|
31 |
+
<input type="checkbox" name="sucuri_update_wpconfig" value="1" />
|
32 |
+
<label for="sucuri_update_wpconfig">I understand that this operation can not be reverted.</label>
|
33 |
+
</p>
|
34 |
+
|
35 |
+
<input type="submit" value="Update WP-Config Keys" class="button button-primary" />
|
36 |
+
</form>
|
37 |
+
|
38 |
+
<div style="%%SUCURI.WPConfigUpdate.Display%%" class="sucuri_update_wpconfig_process">
|
39 |
+
<textarea>%%SUCURI.WPConfigUpdate.NewConfig%%</textarea>
|
40 |
+
</div>
|
41 |
+
</div>
|
42 |
+
</div>
|
43 |
+
|
44 |
+
<div class="postbox">
|
45 |
+
<h3>Post-Hack - Reset user password</h3>
|
46 |
+
<div class="inside">
|
47 |
+
<form method="post">
|
48 |
+
<input type="hidden" name="sucuri_posthack_nonce" value="%%SUCURI.PosthackNonce%%" />
|
49 |
+
<input type="hidden" name="sucuri_posthack_action" value="reset_password" />
|
50 |
+
|
51 |
+
<p>
|
52 |
+
Use this button to reset the current password for some specific users or for all
|
53 |
+
of them. We will send an email to each of those users adivising the password change
|
54 |
+
that includes the new password automatically generated by Wordpress. After the
|
55 |
+
password reset your current session will be closed and you'll need to login again.
|
56 |
+
</p>
|
57 |
+
|
58 |
+
<table class="wp-list-table widefat">
|
59 |
+
<thead>
|
60 |
+
<tr>
|
61 |
+
<th class="manage-column column-cb check-column">
|
62 |
+
<label class="screen-reader-text" for="cb-select-all-1">Select All</label>
|
63 |
+
<input id="cb-select-all-1" type="checkbox">
|
64 |
+
</th>
|
65 |
+
<th class="manage-column column-name">Username</th>
|
66 |
+
<th class="manage-column column-description">Display name</th>
|
67 |
+
<th class="manage-column column-description">Email address</th>
|
68 |
+
</tr>
|
69 |
+
</thead>
|
70 |
+
|
71 |
+
<tbody>
|
72 |
+
%%SUCURI.ResetPassword.UserList%%
|
73 |
+
</tbody>
|
74 |
+
</table>
|
75 |
+
|
76 |
+
<p>
|
77 |
+
<input type="hidden" name="sucuri_reset_password" value="0" />
|
78 |
+
<input type="checkbox" name="sucuri_reset_password" value="1" />
|
79 |
+
<label for="sucuri_reset_password">I understand that this operation can not be reverted.</label>
|
80 |
+
</p>
|
81 |
+
|
82 |
+
<input type="submit" value="Reset User Password" class="button button-primary" />
|
83 |
+
</form>
|
84 |
+
</div>
|
85 |
+
</div>
|
86 |
+
</div><!-- End poststuff -->
|
87 |
+
|
88 |
+
</div><!-- End sucuriscan-maincontent -->
|
89 |
+
</div><!-- End postbox-container -->
|
90 |
+
|
91 |
+
%%SUCURI.SucuriWPSidebar%%
|
92 |
+
|
93 |
+
</div><!-- End wrap -->
|
inc/tpl/sucuri-wp-resetpassword.snippet.tpl
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<th class="check-column">
|
3 |
+
<input type="checkbox" name="user_ids[]" value="%%SUCURI.ResetPassword.UserId%%" />
|
4 |
+
</th>
|
5 |
+
<td>%%SUCURI.ResetPassword.Username%%</td>
|
6 |
+
<td>%%SUCURI.ResetPassword.Displayname%%</td>
|
7 |
+
<td><a href="mailto:%%SUCURI.ResetPassword.Email%%">%%SUCURI.ResetPassword.Email%%</a></td>
|
8 |
+
</tr>
|
inc/tpl/sucuri-wp-sidebar.html.tpl
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>
|
lib/core_integrity.php
CHANGED
@@ -65,6 +65,9 @@ function sucuriwp_core_integrity_check()
|
|
65 |
{
|
66 |
|
67 |
global $wp_version;
|
|
|
|
|
|
|
68 |
$cp = 0;
|
69 |
$updates = get_core_updates();
|
70 |
if (!is_array($updates))
|
@@ -104,32 +107,49 @@ function sucuriwp_core_integrity_check()
|
|
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 |
-
$
|
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
|
117 |
if ( strcmp( $currattr['md5'], $complog[$currfile]['md5'] ) != 0 ) {
|
118 |
-
$
|
119 |
}
|
120 |
|
121 |
}
|
122 |
|
123 |
}
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
//get count of changes
|
126 |
$addcount = sizeof( $added );
|
127 |
$removecount = sizeof( $removed );
|
128 |
-
$changecount = sizeof( $
|
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($
|
133 |
}
|
134 |
}
|
135 |
|
65 |
{
|
66 |
|
67 |
global $wp_version;
|
68 |
+
|
69 |
+
$curlang = get_bloginfo("language");
|
70 |
+
|
71 |
$cp = 0;
|
72 |
$updates = get_core_updates();
|
73 |
if (!is_array($updates))
|
107 |
|
108 |
$added = @array_diff_assoc( $wp_core_hashes, $wp_core_latest_hashes ); //files added
|
109 |
$removed = @array_diff_assoc( $wp_core_latest_hashes, $wp_core_hashes ); //files deleted
|
110 |
+
unset($removed['wp_version']); //ignore wp_version key
|
111 |
$compcurrent = @array_diff_key( $wp_core_hashes, $added ); //remove all added files from current filelist
|
112 |
$complog = @array_diff_key( $wp_core_latest_hashes, $removed ); //remove all deleted files from old file list
|
113 |
+
$modified = array(); //array of modified files
|
114 |
|
115 |
//compare file hashes and mod dates
|
116 |
foreach ( $compcurrent as $currfile => $currattr) {
|
117 |
|
118 |
if ( array_key_exists( $currfile, $complog ) ) {
|
119 |
|
120 |
+
//if attributes differ added to modified files array
|
121 |
if ( strcmp( $currattr['md5'], $complog[$currfile]['md5'] ) != 0 ) {
|
122 |
+
$modified[$currfile]['md5'] = $currattr['md5'];
|
123 |
}
|
124 |
|
125 |
}
|
126 |
|
127 |
}
|
128 |
|
129 |
+
//ignore some junk files
|
130 |
+
if($curlang != "en_US")
|
131 |
+
{
|
132 |
+
//ignore added files
|
133 |
+
unset($added['./licencia.txt']);
|
134 |
+
|
135 |
+
//ignore removed files
|
136 |
+
unset($removed['./license.txt']);
|
137 |
+
|
138 |
+
//ignore modified files
|
139 |
+
unset($modified['./wp-includes/version.php']);
|
140 |
+
unset($modified['./wp-admin/setup-config.php']);
|
141 |
+
unset($modified['./readme.html']);
|
142 |
+
unset($modified['./wp-config-sample.php']);
|
143 |
+
}
|
144 |
+
|
145 |
//get count of changes
|
146 |
$addcount = sizeof( $added );
|
147 |
$removecount = sizeof( $removed );
|
148 |
+
$changecount = sizeof( $modified );
|
149 |
|
150 |
sucuriscan_core_integrity_wrapper($added, "Core File Added: $addcount");
|
151 |
sucuriscan_core_integrity_wrapper($removed, "Core File Removed: $removecount");
|
152 |
+
sucuriscan_core_integrity_wrapper($modified, "Core File Modified: $changecount");
|
153 |
}
|
154 |
}
|
155 |
|
lib/hardening.php
CHANGED
@@ -34,7 +34,7 @@ function sucuriscan_harden_ok($message)
|
|
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)
|
@@ -45,16 +45,22 @@ function sucuriscan_harden_status($status, $type, $messageok, $messagewarn,
|
|
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" /> '.
|
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" /> '.
|
59 |
$messagewarn. '.</h4>';
|
60 |
|
@@ -62,7 +68,7 @@ function sucuriscan_harden_status($status, $type, $messageok, $messagewarn,
|
|
62 |
|
63 |
if($type != NULL)
|
64 |
{
|
65 |
-
echo '<input class="button-primary" type="submit" name="'.$type.'"
|
66 |
value="Harden it!" />';
|
67 |
}
|
68 |
}
|
@@ -97,7 +103,7 @@ function sucuriscan_harden_version()
|
|
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 |
|
@@ -116,10 +122,10 @@ 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,
|
123 |
"WordPress version properly hidden", NULL,
|
124 |
"It checks if your WordPress version is being hidden".
|
125 |
" from being displayed in the generator tag ".
|
@@ -152,45 +158,64 @@ function sucuriscan_harden_upload()
|
|
152 |
}
|
153 |
}
|
154 |
|
155 |
-
if(isset($_POST['
|
156 |
-
|
157 |
-
$cp == 0)
|
158 |
-
{
|
159 |
-
if(file_put_contents("$htaccess_upload",
|
160 |
-
"\n<Files *.php>\ndeny from all\n</Files>")===FALSE)
|
161 |
{
|
162 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
}
|
164 |
-
|
165 |
-
{
|
166 |
-
$
|
167 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
$
|
185 |
|
186 |
-
if(!is_readable($
|
187 |
{
|
188 |
$cp = 0;
|
189 |
}
|
190 |
else
|
191 |
{
|
192 |
$cp = 0;
|
193 |
-
$fcontent = file($
|
194 |
foreach($fcontent as $fline)
|
195 |
{
|
196 |
if(strpos($fline, "deny from all") !== FALSE)
|
@@ -201,45 +226,64 @@ function sucuriscan_harden_wpcontent()
|
|
201 |
}
|
202 |
}
|
203 |
|
204 |
-
if(isset($_POST['
|
205 |
-
|
206 |
-
$cp == 0)
|
207 |
-
{
|
208 |
-
if(file_put_contents("$htaccess_content",
|
209 |
-
"\n<Files *.php>\ndeny from all\n</Files>")===FALSE)
|
210 |
{
|
211 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
}
|
213 |
-
|
214 |
-
{
|
215 |
-
$
|
216 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
$
|
234 |
|
235 |
-
if(!is_readable($
|
236 |
{
|
237 |
$cp = 0;
|
238 |
}
|
239 |
else
|
240 |
{
|
241 |
$cp = 0;
|
242 |
-
$fcontent = file($
|
243 |
foreach($fcontent as $fline)
|
244 |
{
|
245 |
if(strpos($fline, "deny from all") !== FALSE)
|
@@ -250,29 +294,50 @@ function sucuriscan_harden_wpincludes()
|
|
250 |
}
|
251 |
}
|
252 |
|
253 |
-
if(isset($_POST['
|
254 |
-
|
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 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
}
|
262 |
-
|
263 |
-
{
|
264 |
-
$
|
265 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
{
|
@@ -288,7 +353,7 @@ function sucuriscan_harden_phpversion()
|
|
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);
|
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)
|
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" /> '.
|
50 |
$messageok.'.</h4>';
|
51 |
|
52 |
if($updatemsg != NULL){ echo $updatemsg; }
|
53 |
+
|
54 |
+
if($type != NULL)
|
55 |
+
{
|
56 |
+
echo "<input type='submit' name='{$type}_unharden' value='Revert hardening' class='button-secondary' />";
|
57 |
+
echo '<br /><br />';
|
58 |
+
}
|
59 |
}
|
60 |
else
|
61 |
{
|
62 |
echo '<h4>'.
|
63 |
+
'<img style="position:relative;top:5px" height="22" width="22"'.
|
64 |
'src="'.SUCURI_URL.'images/warn.png" /> '.
|
65 |
$messagewarn. '.</h4>';
|
66 |
|
68 |
|
69 |
if($type != NULL)
|
70 |
{
|
71 |
+
echo '<input class="button-primary" type="submit" name="'.$type.'"
|
72 |
value="Harden it!" />';
|
73 |
}
|
74 |
}
|
103 |
sucuriscan_wrapper_open("Verify WordPress Version");
|
104 |
|
105 |
|
106 |
+
sucuriscan_harden_status($cp, NULL,
|
107 |
"WordPress is updated", "WordPress is not updated",
|
108 |
NULL);
|
109 |
|
122 |
{
|
123 |
/* Enabled by default with this plugin. */
|
124 |
$cp = 1;
|
125 |
+
|
126 |
sucuriscan_wrapper_open("Remove WordPress Version");
|
127 |
|
128 |
+
sucuriscan_harden_status($cp, NULL,
|
129 |
"WordPress version properly hidden", NULL,
|
130 |
"It checks if your WordPress version is being hidden".
|
131 |
" from being displayed in the generator tag ".
|
158 |
}
|
159 |
}
|
160 |
|
161 |
+
if( isset($_POST['wpsucuri-doharden']) ){
|
162 |
+
if( isset($_POST['sucuriscan_harden_upload']) && $cp == 0 )
|
|
|
|
|
|
|
|
|
163 |
{
|
164 |
+
if(file_put_contents($htaccess_upload,
|
165 |
+
"\n<Files *.php>\ndeny from all\n</Files>")===FALSE)
|
166 |
+
{
|
167 |
+
$upmsg = sucuriscan_harden_error("ERROR: Unable to create .htaccess file.");
|
168 |
+
}
|
169 |
+
else
|
170 |
+
{
|
171 |
+
$upmsg = sucuriscan_harden_ok("COMPLETE: Upload directory successfully hardened");
|
172 |
+
$cp = 1;
|
173 |
+
}
|
174 |
}
|
175 |
+
|
176 |
+
elseif( isset($_POST['sucuriscan_harden_upload_unharden']) ){
|
177 |
+
$htaccess_upload_writable = ( file_exists($htaccess_upload) && is_writable($htaccess_upload) ) ? TRUE : FALSE;
|
178 |
+
$htaccess_content = $htaccess_upload_writable ? file_get_contents($htaccess_upload) : '';
|
179 |
+
|
180 |
+
if( $htaccess_upload_writable ){
|
181 |
+
$cp = 0;
|
182 |
+
if( preg_match('/<Files \*\.php>\ndeny from all\n<\/Files>/', $htaccess_content, $match) ){
|
183 |
+
$htaccess_content = str_replace("<Files *.php>\ndeny from all\n</Files>", '', $htaccess_content);
|
184 |
+
file_put_contents($htaccess_upload, $htaccess_content, LOCK_EX);
|
185 |
+
}
|
186 |
+
sucuri_admin_notice('updated', '<strong>OK.</strong> WP-Content Uploads directory protection reverted.');
|
187 |
+
}else{
|
188 |
+
$harden_process = '<strong>Error.</strong> The <code>wp-content/uploads/.htaccess</code> does
|
189 |
+
not exists or is not writable, you will need to remove the following code manually there:
|
190 |
+
<code><Files *.php>deny from all</Files></code>';
|
191 |
+
sucuri_admin_notice('error', $harden_process);
|
192 |
+
}
|
193 |
}
|
194 |
}
|
195 |
|
196 |
sucuriscan_wrapper_open("Protect Uploads Directory");
|
197 |
+
sucuriscan_harden_status($cp, "sucuriscan_harden_upload",
|
198 |
"Upload directory properly hardened",
|
199 |
"Upload directory not hardened",
|
200 |
"It checks if your upload directory allows PHP ".
|
201 |
"execution or if it is browsable.", $upmsg);
|
202 |
sucuriscan_wrapper_close();
|
203 |
+
}
|
204 |
|
205 |
function sucuriscan_harden_wpcontent()
|
206 |
{
|
207 |
$cp = 1;
|
208 |
$upmsg = NULL;
|
209 |
+
$htaccess_upload = ABSPATH."/wp-content/.htaccess";
|
210 |
|
211 |
+
if(!is_readable($htaccess_upload))
|
212 |
{
|
213 |
$cp = 0;
|
214 |
}
|
215 |
else
|
216 |
{
|
217 |
$cp = 0;
|
218 |
+
$fcontent = file($htaccess_upload);
|
219 |
foreach($fcontent as $fline)
|
220 |
{
|
221 |
if(strpos($fline, "deny from all") !== FALSE)
|
226 |
}
|
227 |
}
|
228 |
|
229 |
+
if( isset($_POST['wpsucuri-doharden']) ){
|
230 |
+
if( isset($_POST['sucuriscan_harden_wpcontent']) && $cp == 0 )
|
|
|
|
|
|
|
|
|
231 |
{
|
232 |
+
if(file_put_contents($htaccess_upload,
|
233 |
+
"\n<Files *.php>\ndeny from all\n</Files>")===FALSE)
|
234 |
+
{
|
235 |
+
$upmsg = sucuriscan_harden_error("ERROR: Unable to create .htaccess file.");
|
236 |
+
}
|
237 |
+
else
|
238 |
+
{
|
239 |
+
$upmsg = sucuriscan_harden_ok("COMPLETE: wp-content directory successfully hardened");
|
240 |
+
$cp = 1;
|
241 |
+
}
|
242 |
}
|
243 |
+
|
244 |
+
elseif( isset($_POST['sucuriscan_harden_wpcontent_unharden']) ){
|
245 |
+
$htaccess_upload_writable = ( file_exists($htaccess_upload) && is_writable($htaccess_upload) ) ? TRUE : FALSE;
|
246 |
+
$htaccess_content = $htaccess_upload_writable ? file_get_contents($htaccess_upload) : '';
|
247 |
+
|
248 |
+
if( $htaccess_upload_writable ){
|
249 |
+
$cp = 0;
|
250 |
+
if( preg_match('/<Files \*\.php>\ndeny from all\n<\/Files>/', $htaccess_content, $match) ){
|
251 |
+
$htaccess_content = str_replace("<Files *.php>\ndeny from all\n</Files>", '', $htaccess_content);
|
252 |
+
file_put_contents($htaccess_upload, $htaccess_content, LOCK_EX);
|
253 |
+
}
|
254 |
+
sucuri_admin_notice('updated', '<strong>OK.</strong> WP-Content directory protection reverted.');
|
255 |
+
}else{
|
256 |
+
$harden_process = '<strong>Error.</strong> The <code>wp-content/.htaccess</code> does
|
257 |
+
not exists or is not writable, you will need to remove the following code manually there:
|
258 |
+
<code><Files *.php>deny from all</Files></code>';
|
259 |
+
sucuri_admin_notice('error', $harden_process);
|
260 |
+
}
|
261 |
}
|
262 |
}
|
263 |
|
264 |
sucuriscan_wrapper_open("Restrict wp-content Access");
|
265 |
+
sucuriscan_harden_status($cp, "sucuriscan_harden_wpcontent",
|
266 |
"WP-content directory properly hardened",
|
267 |
"WP-content directory not hardened",
|
268 |
"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 ".
|
269 |
"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);
|
270 |
sucuriscan_wrapper_close();
|
271 |
+
}
|
272 |
|
273 |
function sucuriscan_harden_wpincludes()
|
274 |
{
|
275 |
$cp = 1;
|
276 |
$upmsg = NULL;
|
277 |
+
$htaccess_upload = ABSPATH."/wp-includes/.htaccess";
|
278 |
|
279 |
+
if(!is_readable($htaccess_upload))
|
280 |
{
|
281 |
$cp = 0;
|
282 |
}
|
283 |
else
|
284 |
{
|
285 |
$cp = 0;
|
286 |
+
$fcontent = file($htaccess_upload);
|
287 |
foreach($fcontent as $fline)
|
288 |
{
|
289 |
if(strpos($fline, "deny from all") !== FALSE)
|
294 |
}
|
295 |
}
|
296 |
|
297 |
+
if( isset($_POST['wpsucuri-doharden']) ){
|
298 |
+
if( isset($_POST['sucuriscan_harden_wpincludes']) && $cp == 0 )
|
|
|
|
|
|
|
|
|
299 |
{
|
300 |
+
if(file_put_contents($htaccess_upload,
|
301 |
+
"\n<Files *.php>\ndeny from all\n</Files>\n<Files wp-tinymce.php>\nallow from all\n</Files>\n")===FALSE)
|
302 |
+
{
|
303 |
+
$upmsg = sucuriscan_harden_error("ERROR: Unable to create .htaccess file.");
|
304 |
+
}
|
305 |
+
else
|
306 |
+
{
|
307 |
+
$upmsg = sucuriscan_harden_ok("COMPLETE: wp-includes directory successfully hardened.");
|
308 |
+
$cp = 1;
|
309 |
+
}
|
310 |
}
|
311 |
+
|
312 |
+
elseif( isset($_POST['sucuriscan_harden_wpincludes_unharden']) ){
|
313 |
+
$htaccess_upload_writable = ( file_exists($htaccess_upload) && is_writable($htaccess_upload) ) ? TRUE : FALSE;
|
314 |
+
$htaccess_content = $htaccess_upload_writable ? file_get_contents($htaccess_upload) : '';
|
315 |
+
|
316 |
+
if( $htaccess_upload_writable ){
|
317 |
+
$cp = 0;
|
318 |
+
if( preg_match_all('/<Files (\*|wp-tinymce|ms-files)\.php>\n(deny|allow) from all\n<\/Files>/', $htaccess_content, $match) ){
|
319 |
+
foreach($match[0] as $restriction){
|
320 |
+
$htaccess_content = str_replace($restriction, '', $htaccess_content);
|
321 |
+
}
|
322 |
+
file_put_contents($htaccess_upload, $htaccess_content, LOCK_EX);
|
323 |
+
}
|
324 |
+
sucuri_admin_notice('updated', '<strong>OK.</strong> WP-Includes directory protection reverted.');
|
325 |
+
}else{
|
326 |
+
$harden_process = '<strong>Error.</strong> The <code>wp-includes/.htaccess</code> does
|
327 |
+
not exists or is not writable, you will need to remove the following code manually there:
|
328 |
+
<code><Files *.php>deny from all</Files></code>';
|
329 |
+
sucuri_admin_notice('error', $harden_process);
|
330 |
+
}
|
331 |
}
|
332 |
}
|
333 |
|
334 |
sucuriscan_wrapper_open("Restrict wp-includes Access");
|
335 |
+
sucuriscan_harden_status($cp, "sucuriscan_harden_wpincludes",
|
336 |
"wp-includes directory properly hardened",
|
337 |
"wp-includes directory not hardened",
|
338 |
"This option blocks direct PHP access to any file inside wp-includes. ", $upmsg);
|
339 |
sucuriscan_wrapper_close();
|
340 |
+
}
|
341 |
|
342 |
function sucuriscan_harden_phpversion()
|
343 |
{
|
353 |
}
|
354 |
|
355 |
sucuriscan_wrapper_open("Verify PHP Version");
|
356 |
+
sucuriscan_harden_status($cp, NULL,
|
357 |
"Using an updated version of PHP (v $phpv)",
|
358 |
"The version of PHP you are using ($phpv) is not current, not recommended, and/or not supported",
|
359 |
"This checks if you have the latest version of PHP installed.", NULL);
|
readme.txt
CHANGED
@@ -3,16 +3,16 @@ 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.
|
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 |
|
@@ -37,6 +37,7 @@ There are a number of blacklisting authorities that monitor for malware, SPAM, a
|
|
37 |
* Norton
|
38 |
* AVG
|
39 |
* Phish Tank (Phishing Specifically)
|
|
|
40 |
* McAfee SiteAdvisor
|
41 |
* Yandex
|
42 |
|
@@ -47,6 +48,14 @@ We augment the SiteCheck Malware Scanner with various. 1-click hardening options
|
|
47 |
* Restrict wp-content Access
|
48 |
* Restrict wp-includes Access
|
49 |
* Verify PHP Version
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
|
51 |
|
52 |
== Installation ==
|
@@ -58,6 +67,11 @@ We augment the SiteCheck Malware Scanner with various. 1-click hardening options
|
|
58 |
|
59 |
== Changelog ==
|
60 |
|
|
|
|
|
|
|
|
|
|
|
61 |
= 1.3 =
|
62 |
* Removed some PHP warnings and code clean up.
|
63 |
* Added WordPress integrity checks.
|
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.4
|
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 and verify the integrity of your core files right in your dashboard. It also includes post-hack options to help you reset passwords and secret keys in case it has been already hacked.
|
10 |
|
11 |
== Description ==
|
12 |
|
13 |
+
Sucuri SiteCheck will check your site 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 online 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 |
|
37 |
* Norton
|
38 |
* AVG
|
39 |
* Phish Tank (Phishing Specifically)
|
40 |
+
* ESET
|
41 |
* McAfee SiteAdvisor
|
42 |
* Yandex
|
43 |
|
48 |
* Restrict wp-content Access
|
49 |
* Restrict wp-includes Access
|
50 |
* Verify PHP Version
|
51 |
+
* Disable the theme and plugin editors
|
52 |
+
|
53 |
+
On the newest versions of the plugin we also added an option to verify all WordPress core files for changes,
|
54 |
+
which can be useful to detect hidden backdoors.
|
55 |
+
|
56 |
+
Note that if your site is compromised and you need urgent help, you can leverage the
|
57 |
+
Sucuri plans here: http://sucuri.net (even if our free options are not finding
|
58 |
+
the compromise on your site).
|
59 |
|
60 |
|
61 |
== Installation ==
|
67 |
|
68 |
== Changelog ==
|
69 |
|
70 |
+
= 1.4 =
|
71 |
+
* Added post-hack options (reset all passwords).
|
72 |
+
* Added last-login.
|
73 |
+
* Added more hardening and the option to revert any hardening done.
|
74 |
+
|
75 |
= 1.3 =
|
76 |
* Removed some PHP warnings and code clean up.
|
77 |
* Added WordPress integrity checks.
|
sucuri.php
CHANGED
@@ -7,7 +7,7 @@ Description: The <a href="http://sucuri.net">Sucuri Security</a> - SiteCheck Mal
|
|
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.
|
11 |
Author URI: http://sucuri.net
|
12 |
*/
|
13 |
|
@@ -18,8 +18,11 @@ if(!function_exists('add_action'))
|
|
18 |
}
|
19 |
|
20 |
define('SUCURISCAN','sucuriscan');
|
21 |
-
define('SUCURISCAN_VERSION','1.
|
22 |
define( 'SUCURI_URL',plugin_dir_url( __FILE__ ));
|
|
|
|
|
|
|
23 |
|
24 |
/* Requires files. */
|
25 |
//require_once(dirname(__FILE__ ) . '/inc/scripts.php');
|
@@ -54,6 +57,12 @@ function sucuriscan_menu()
|
|
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. */
|
@@ -91,15 +100,15 @@ function sucuri_scan_page()
|
|
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
|
98 |
|
99 |
</div><!-- End sucuriscan-maincontent -->
|
100 |
</div><!-- End postbox-container -->
|
101 |
|
102 |
-
|
103 |
|
104 |
</div><!-- End Wrap -->
|
105 |
|
@@ -159,8 +168,10 @@ function sucuriscan_print_scan()
|
|
159 |
}
|
160 |
echo "<br />";
|
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 |
{
|
@@ -229,7 +240,7 @@ function sucuriscan_print_scan()
|
|
229 |
</div><!-- End sucuriscan-maincontent -->
|
230 |
</div><!-- End postbox-container -->
|
231 |
|
232 |
-
|
233 |
|
234 |
</div><!-- End Wrap -->
|
235 |
|
@@ -278,7 +289,7 @@ function sucuriscan_hardening_page()
|
|
278 |
</div><!-- End sucuriscan-maincontent -->
|
279 |
</div><!-- End postbox-container -->
|
280 |
|
281 |
-
|
282 |
|
283 |
</div><!-- End Wrap -->
|
284 |
|
@@ -313,7 +324,7 @@ function sucuriscan_core_integrity_page()
|
|
313 |
</div><!-- End sucuriscan-maincontent -->
|
314 |
</div><!-- End postbox-container -->
|
315 |
|
316 |
-
|
317 |
|
318 |
</div><!-- End Wrap -->
|
319 |
|
@@ -325,4 +336,363 @@ function sucuriscan_core_integrity_page()
|
|
325 |
add_action('admin_menu', 'sucuriscan_menu');
|
326 |
remove_action('wp_head', 'wp_generator');
|
327 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
?>
|
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.4
|
11 |
Author URI: http://sucuri.net
|
12 |
*/
|
13 |
|
18 |
}
|
19 |
|
20 |
define('SUCURISCAN','sucuriscan');
|
21 |
+
define('SUCURISCAN_VERSION','1.4');
|
22 |
define( 'SUCURI_URL',plugin_dir_url( __FILE__ ));
|
23 |
+
define('SUCURISCAN_PLUGIN_FOLDER', 'sucuri-scanner');
|
24 |
+
/* Sucuri Free/Paid Plugin will use the same tablename, check: sucuriscan_lastlogins_table_exists() */
|
25 |
+
define('SUCURISCAN_LASTLOGINS_TABLENAME', "{$table_prefix}sucuri_lastlogins");
|
26 |
|
27 |
/* Requires files. */
|
28 |
//require_once(dirname(__FILE__ ) . '/inc/scripts.php');
|
57 |
|
58 |
add_submenu_page('sucuriscan', 'WordPress Integrity', 'WordPress Integrity', 'manage_options',
|
59 |
'sucuriscan_core_integrity', 'sucuriscan_core_integrity_page');
|
60 |
+
|
61 |
+
add_submenu_page('sucuriscan', 'Post-Hack', 'Post-Hack', 'manage_options',
|
62 |
+
'sucuriscan_posthack', 'sucuriscan_posthack_page');
|
63 |
+
|
64 |
+
add_submenu_page('sucuriscan', 'Last Logins', 'Last Logins', 'manage_options',
|
65 |
+
'sucuriscan_lastlogins', 'sucuriscan_lastlogins_page');
|
66 |
}
|
67 |
|
68 |
/* Sucuri malware scan page. */
|
100 |
|
101 |
<form action="" method="post">
|
102 |
<input type="hidden" name="wpsucuri-doscan" value="wpsucuri-doscan" />
|
103 |
+
<input class="button button-primary button-hero load-customize" type="submit" name="wpsucuri_doscanrun" value="Scan this site now!" />
|
104 |
</form>
|
105 |
|
106 |
+
<p><strong>If you have any questions about these checks or this plugin, contact us at <a href="mailto:info@sucuri.net">info@sucuri.net</a> or visit <a href="http://sucuri.net">sucuri.net</a></strong></p>
|
107 |
|
108 |
</div><!-- End sucuriscan-maincontent -->
|
109 |
</div><!-- End postbox-container -->
|
110 |
|
111 |
+
<?php echo sucuriscan_get_template('sucuri-wp-sidebar.html.tpl') ?>
|
112 |
|
113 |
</div><!-- End Wrap -->
|
114 |
|
168 |
}
|
169 |
echo "<br />";
|
170 |
}
|
171 |
+
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>';
|
172 |
|
173 |
+
echo "<hr />\n";
|
174 |
+
echo '<i>If our free scanner did not detect any issue, you may have a more complicated and hidden problem. You can try our <a href="admin.php?page=sucuriscan_core_integrity">WordPress integrity checks</a> or sign up with Sucuri <a target="_blank" href="http://sucuri.net/signup">here</a> for a complete and in depth scan+cleanup (not included in the free checks).</i>';
|
175 |
echo "<hr />\n";
|
176 |
if(isset($res['BLACKLIST']['WARN']))
|
177 |
{
|
240 |
</div><!-- End sucuriscan-maincontent -->
|
241 |
</div><!-- End postbox-container -->
|
242 |
|
243 |
+
<?php echo sucuriscan_get_template('sucuri-wp-sidebar.html.tpl') ?>
|
244 |
|
245 |
</div><!-- End Wrap -->
|
246 |
|
289 |
</div><!-- End sucuriscan-maincontent -->
|
290 |
</div><!-- End postbox-container -->
|
291 |
|
292 |
+
<?php echo sucuriscan_get_template('sucuri-wp-sidebar.html.tpl') ?>
|
293 |
|
294 |
</div><!-- End Wrap -->
|
295 |
|
324 |
</div><!-- End sucuriscan-maincontent -->
|
325 |
</div><!-- End postbox-container -->
|
326 |
|
327 |
+
<?php echo sucuriscan_get_template('sucuri-wp-sidebar.html.tpl') ?>
|
328 |
|
329 |
</div><!-- End Wrap -->
|
330 |
|
336 |
add_action('admin_menu', 'sucuriscan_menu');
|
337 |
remove_action('wp_head', 'wp_generator');
|
338 |
|
339 |
+
function sucuriscan_send_mail($to='', $subject='', $message='', $data_set=array(), $debug=FALSE)
|
340 |
+
{
|
341 |
+
$headers = array();
|
342 |
+
$subject = ucwords(strtolower($subject));
|
343 |
+
$wp_domain = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : get_option('siteurl');
|
344 |
+
if( get_option('sucuri_wp_prettify_mails')!='disabled' ){
|
345 |
+
$headers = array( 'Content-type: text/html' );
|
346 |
+
$data_set['PrettifyType'] = 'html';
|
347 |
+
}
|
348 |
+
$message = sucuriscan_prettify_mail($subject, $message, $data_set);
|
349 |
+
|
350 |
+
if($debug){
|
351 |
+
die($message);
|
352 |
+
}else{
|
353 |
+
wp_mail($to, "Sucuri WP Notification: {$wp_domain}: {$subject}" , $message, $headers);
|
354 |
+
}
|
355 |
+
}
|
356 |
+
|
357 |
+
function sucuriscan_admin_notice($type='updated', $message='')
|
358 |
+
{
|
359 |
+
if( !empty($message) ): ?>
|
360 |
+
<div class="<?php echo $type; ?>"><p><?php _e($message); ?></p></div>
|
361 |
+
<?php endif;
|
362 |
+
}
|
363 |
+
|
364 |
+
function sucuriscan_prettify_mail($subject='', $message='', $data_set=array())
|
365 |
+
{
|
366 |
+
$current_user = wp_get_current_user();
|
367 |
+
|
368 |
+
$prettify_type = isset($data_set['PrettifyType']) ? $data_set['PrettifyType'] : 'txt';
|
369 |
+
$real_ip = isset($_SERVER['SUCURI_RIP']) ? $_SERVER['SUCURI_RIP'] : $_SERVER['REMOTE_ADDR'];
|
370 |
+
|
371 |
+
$mail_variables = array(
|
372 |
+
'TemplateTitle'=>'Sucuri WP Notification',
|
373 |
+
'Subject'=>$subject,
|
374 |
+
'Website'=>get_option('siteurl'),
|
375 |
+
'RemoteAddress'=>$real_ip,
|
376 |
+
'Message'=>$message,
|
377 |
+
'User'=>$current_user->display_name,
|
378 |
+
'Time'=>current_time('mysql')
|
379 |
+
);
|
380 |
+
foreach($data_set as $var_key=>$var_value){
|
381 |
+
$mail_variables[$var_key] = $var_value;
|
382 |
+
}
|
383 |
+
|
384 |
+
return sucuriscan_get_template("sucuri-wp-notification.{$prettify_type}.tpl", $mail_variables);
|
385 |
+
}
|
386 |
+
|
387 |
+
function sucuriscan_get_template($template='', $template_variables=array()){
|
388 |
+
$template_content = '';
|
389 |
+
$template_path = WP_PLUGIN_DIR.'/'.SUCURISCAN_PLUGIN_FOLDER."/inc/tpl/{$template}";
|
390 |
+
|
391 |
+
if( file_exists($template_path) && is_readable($template_path) ){
|
392 |
+
$template_content = file_get_contents($template_path);
|
393 |
+
foreach($template_variables as $tpl_key=>$tpl_value){
|
394 |
+
$template_content = str_replace("%%SUCURI.{$tpl_key}%%", $tpl_value, $template_content);
|
395 |
+
}
|
396 |
+
}
|
397 |
+
return $template_content;
|
398 |
+
}
|
399 |
+
|
400 |
+
function sucuriscan_wp_sidebar_gen()
|
401 |
+
{
|
402 |
+
return sucuriscan_get_template('sucuri-wp-sidebar.html.tpl');
|
403 |
+
}
|
404 |
+
|
405 |
+
function sucuriscan_get_new_config_keys()
|
406 |
+
{
|
407 |
+
$request = wp_remote_get('https://api.wordpress.org/secret-key/1.1/salt/');
|
408 |
+
if( !is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200 ){
|
409 |
+
if( preg_match_all("/define\('([A-Z_]+)',[ ]+'(.*)'\);/", $request['body'], $match) ){
|
410 |
+
$new_keys = array();
|
411 |
+
foreach($match[1] as $i=>$value){
|
412 |
+
$new_keys[$value] = $match[2][$i];
|
413 |
+
}
|
414 |
+
return $new_keys;
|
415 |
+
}
|
416 |
+
}
|
417 |
+
return FALSE;
|
418 |
+
}
|
419 |
+
|
420 |
+
function sucuriscan_set_new_config_keys()
|
421 |
+
{
|
422 |
+
$new_wpconfig = '';
|
423 |
+
$wp_config_path = ABSPATH.'wp-config.php';
|
424 |
+
$wp_config_lines = file($wp_config_path);
|
425 |
+
$new_keys = sucuriscan_get_new_config_keys();
|
426 |
+
$old_keys = array();
|
427 |
+
$old_keys_string = $new_keys_string = '';
|
428 |
+
|
429 |
+
foreach($wp_config_lines as $wp_config_line){
|
430 |
+
$wp_config_line = str_replace("\n", '', $wp_config_line);
|
431 |
+
|
432 |
+
if( preg_match("/define\('([A-Z_]+)',([ ]+)'(.*)'\);/", $wp_config_line, $match) ){
|
433 |
+
$key_name = $match[1];
|
434 |
+
if( array_key_exists($key_name, $new_keys) ){
|
435 |
+
$white_spaces = $match[2];
|
436 |
+
$old_keys[$key_name] = $match[3];
|
437 |
+
$wp_config_line = "define('{$key_name}',{$white_spaces}'{$new_keys[$key_name]}');";
|
438 |
+
|
439 |
+
$old_keys_string .= "define('{$key_name}',{$white_spaces}'{$old_keys[$key_name]}');\n";
|
440 |
+
$new_keys_string .= "{$wp_config_line}\n";
|
441 |
+
}
|
442 |
+
}
|
443 |
+
|
444 |
+
$new_wpconfig .= "{$wp_config_line}\n";
|
445 |
+
}
|
446 |
+
|
447 |
+
$response = array(
|
448 |
+
'updated'=>is_writable($wp_config_path),
|
449 |
+
'old_keys'=>$old_keys,
|
450 |
+
'old_keys_string'=>$old_keys_string,
|
451 |
+
'new_keys'=>$new_keys,
|
452 |
+
'new_keys_string'=>$new_keys_string,
|
453 |
+
'new_wpconfig'=>$new_wpconfig
|
454 |
+
);
|
455 |
+
if( $response['updated'] ){
|
456 |
+
file_put_contents($wp_config_path, $new_wpconfig, LOCK_EX);
|
457 |
+
}
|
458 |
+
return $response;
|
459 |
+
}
|
460 |
+
|
461 |
+
function sucuriscan_new_password($user_id=0)
|
462 |
+
{
|
463 |
+
$user_id = intval($user_id);
|
464 |
+
$current_user = wp_get_current_user();
|
465 |
+
|
466 |
+
if( $user_id>0 && $user_id!=$current_user->ID ){
|
467 |
+
$user = get_userdata($user_id);
|
468 |
+
$new_password = wp_generate_password(15, TRUE, FALSE);
|
469 |
+
|
470 |
+
$data_set = array( 'User'=>$user->display_name );
|
471 |
+
$message = "The password for your user account in the website mentioned has been changed by an administrator,
|
472 |
+
this is the new password automatically generated by the system, please update ASAP.<br>
|
473 |
+
<div style='display:inline-block;background:#ddd;font-family:monaco,monospace,courier;
|
474 |
+
font-size:30px;margin:0;padding:15px;border:1px solid #999'>{$new_password}</div>";
|
475 |
+
sucuriscan_send_mail($user->user_email, 'Changed password', $message, $data_set);
|
476 |
+
|
477 |
+
wp_set_password($new_password, $user_id);
|
478 |
+
|
479 |
+
return TRUE;
|
480 |
+
}
|
481 |
+
return FALSE;
|
482 |
+
}
|
483 |
+
|
484 |
+
function sucuriscan_posthack_page()
|
485 |
+
{
|
486 |
+
if( !current_user_can('manage_options') )
|
487 |
+
{
|
488 |
+
wp_die(__('You do not have sufficient permissions to access this page.') );
|
489 |
+
}
|
490 |
+
|
491 |
+
// Page pseudo-variables initialization.
|
492 |
+
$template_variables = array(
|
493 |
+
'SucuriURL'=>SUCURI_URL,
|
494 |
+
'PosthackNonce'=>wp_create_nonce('sucuri_posthack_nonce'),
|
495 |
+
'SucuriWPSidebar'=>sucuriscan_wp_sidebar_gen(),
|
496 |
+
'WPConfigUpdate.Display'=>'display:none',
|
497 |
+
'WPConfigUpdate.NewConfig'=>'',
|
498 |
+
'ResetPassword.UserList'=>''
|
499 |
+
);
|
500 |
+
|
501 |
+
// Process form submission
|
502 |
+
if( isset($_POST['sucuri_posthack_action']) ){
|
503 |
+
if( !wp_verify_nonce($_POST['sucuri_posthack_nonce'], 'sucuri_posthack_nonce') )
|
504 |
+
{
|
505 |
+
wp_die(__('Wordpress Nonce verification failed, try again going back and checking the form.') );
|
506 |
+
}
|
507 |
+
|
508 |
+
switch($_POST['sucuri_posthack_action']){
|
509 |
+
case 'update_wpconfig':
|
510 |
+
$update_wpconfig = ( isset($_POST['sucuri_update_wpconfig']) && $_POST['sucuri_update_wpconfig']==1 ) ? TRUE : FALSE;
|
511 |
+
|
512 |
+
if( $update_wpconfig ){
|
513 |
+
$wpconfig_process = sucuriscan_set_new_config_keys();
|
514 |
+
$template_variables['WPConfigUpdate.Display'] = 'display:block';
|
515 |
+
|
516 |
+
if( $wpconfig_process['updated']===TRUE ){
|
517 |
+
sucuriscan_admin_notice('updated', '<strong>OK.</strong> WP-Config keys updated successfully. In the textarea bellow you will see the old-keys and the new-keys updated.');
|
518 |
+
$template_variables['WPConfigUpdate.NewConfig'] .= "// Old Keys\n";
|
519 |
+
$template_variables['WPConfigUpdate.NewConfig'] .= $wpconfig_process['old_keys_string'];
|
520 |
+
$template_variables['WPConfigUpdate.NewConfig'] .= "//\n";
|
521 |
+
$template_variables['WPConfigUpdate.NewConfig'] .= "// New Keys\n";
|
522 |
+
$template_variables['WPConfigUpdate.NewConfig'] .= $wpconfig_process['new_keys_string'];
|
523 |
+
}else{
|
524 |
+
sucuriscan_admin_notice('error', '<strong>Error.</strong> The wp-config.php file is not writable, please copy and paste the code shown bellow in the textarea into that file manually.');
|
525 |
+
$template_variables['WPConfigUpdate.NewConfig'] = $wpconfig_process['new_wpconfig'];
|
526 |
+
}
|
527 |
+
}else{
|
528 |
+
sucuriscan_admin_notice('error', '<strong>Error.</strong> You need to confirm that you understand the risk of this operation');
|
529 |
+
}
|
530 |
+
break;
|
531 |
+
case 'reset_password':
|
532 |
+
$reset_password = ( isset($_POST['sucuri_reset_password']) && $_POST['sucuri_reset_password']==1 ) ? TRUE : FALSE;
|
533 |
+
|
534 |
+
if( $reset_password ){
|
535 |
+
$user_identifiers = $_POST['user_ids'];
|
536 |
+
$pwd_changed = $pwd_not_changed = array();
|
537 |
+
arsort($user_identifiers);
|
538 |
+
|
539 |
+
foreach($user_identifiers as $user_id){
|
540 |
+
if( sucuriscan_new_password($user_id) ){
|
541 |
+
$passwords_changed[] = $user_id;
|
542 |
+
}else{
|
543 |
+
$pwd_not_changed[] = $user_id;
|
544 |
+
}
|
545 |
+
}
|
546 |
+
if( !empty($pwd_changed) ){
|
547 |
+
sucuriscan_admin_notice('updated', '<strong>OK.</strong> Password changed successfully for users: '.implode(', ',$pwd_changed));
|
548 |
+
}
|
549 |
+
if( !empty($pwd_not_changed) ){
|
550 |
+
sucuriscan_admin_notice('error', '<strong>Error.</strong> Password change failed for users: '.implode(', ',$pwd_not_changed));
|
551 |
+
}
|
552 |
+
}else{
|
553 |
+
sucuriscan_admin_notice('error', '<strong>Error.</strong> You need to confirm that you understand the risk of this operation');
|
554 |
+
}
|
555 |
+
break;
|
556 |
+
default:
|
557 |
+
wp_die(__('Sucuri WP Plugin, invalid form action, go back and try again.'));
|
558 |
+
break;
|
559 |
+
}
|
560 |
+
}
|
561 |
+
|
562 |
+
// Fill the user list for ResetPassword action.
|
563 |
+
$user_list = get_users();
|
564 |
+
foreach($user_list as $user){
|
565 |
+
$user_snippet = sucuriscan_get_template('sucuri-wp-resetpassword.snippet.tpl', array(
|
566 |
+
'ResetPassword.UserId'=>$user->ID,
|
567 |
+
'ResetPassword.Username'=>$user->user_login,
|
568 |
+
'ResetPassword.Displayname'=>$user->display_name,
|
569 |
+
'ResetPassword.Email'=>$user->user_email
|
570 |
+
));
|
571 |
+
$template_variables['ResetPassword.UserList'] .= $user_snippet;
|
572 |
+
}
|
573 |
+
|
574 |
+
echo sucuriscan_get_template('sucuri-wp-posthack.html.tpl', $template_variables);
|
575 |
+
}
|
576 |
+
|
577 |
+
function sucuriscan_lastlogins_page()
|
578 |
+
{
|
579 |
+
if( !current_user_can('manage_options') )
|
580 |
+
{
|
581 |
+
wp_die(__('You do not have sufficient permissions to access this page.') );
|
582 |
+
}
|
583 |
+
|
584 |
+
// Page pseudo-variables initialization.
|
585 |
+
$template_variables = array(
|
586 |
+
'SucuriURL'=>SUCURI_URL,
|
587 |
+
'PosthackNonce'=>wp_create_nonce('sucuri_posthack_nonce'),
|
588 |
+
'SucuriWPSidebar'=>sucuriscan_wp_sidebar_gen(),
|
589 |
+
'UserList'=>'',
|
590 |
+
'CurrentURL'=>site_url().'/wp-admin/admin.php?page='.$_GET['page']
|
591 |
+
);
|
592 |
+
|
593 |
+
$limit = isset($_GET['limit']) ? intval($_GET['limit']) : 10;
|
594 |
+
$template_variables['UserList.ShowAll'] = $limit>0 ? 'display:table' : 'display:none';
|
595 |
+
|
596 |
+
$user_list = sucuriscan_get_logins($limit);
|
597 |
+
foreach($user_list as $user){
|
598 |
+
$user_snippet = sucuriscan_get_template('sucuri-wp-lastlogins.snippet.tpl', array(
|
599 |
+
'UserList.UserId'=>$user->ID,
|
600 |
+
'UserList.Username'=>$user->user_login,
|
601 |
+
'UserList.Email'=>$user->user_email,
|
602 |
+
'UserList.RemoteAddr'=>$user->user_remoteaddr,
|
603 |
+
'UserList.Datetime'=>$user->user_lastlogin
|
604 |
+
));
|
605 |
+
$template_variables['UserList'] .= $user_snippet;
|
606 |
+
}
|
607 |
+
|
608 |
+
echo sucuriscan_get_template('sucuri-wp-lastlogins.html.tpl', $template_variables);
|
609 |
+
}
|
610 |
+
|
611 |
+
function sucuriscan_set_flashdata($key='', $value='')
|
612 |
+
{
|
613 |
+
/* Use wp-sucuri_ to give compatibility between Sucuri Free/Paid Plugin */
|
614 |
+
$session_name = "wp-sucuri_{$key}";
|
615 |
+
$expire = time() + 60*5;
|
616 |
+
setcookie($session_name, $value, $expire, SITECOOKIEPATH.'wp-admin');
|
617 |
+
}
|
618 |
+
|
619 |
+
function sucuriscan_get_flashdata()
|
620 |
+
{
|
621 |
+
/* Use wp-sucuri_ to give compatibility between Sucuri Free/Paid Plugin */
|
622 |
+
foreach($_COOKIE as $key=>$value){
|
623 |
+
if( preg_match('/^(wp\-sucuri_.*)$/', $key) ){
|
624 |
+
sucuriscan_admin_notice('updated', $value);
|
625 |
+
setcookie($key, NULL, time()-3600);
|
626 |
+
}
|
627 |
+
}
|
628 |
+
}
|
629 |
+
add_action('admin_init', 'sucuriscan_get_flashdata');
|
630 |
+
|
631 |
+
function sucuriscan_lastlogins_table_exists()
|
632 |
+
{
|
633 |
+
global $wpdb;
|
634 |
+
if( defined('SUCURISCAN_LASTLOGINS_TABLENAME') ){
|
635 |
+
$table_name = SUCURISCAN_LASTLOGINS_TABLENAME;
|
636 |
+
|
637 |
+
if( $wpdb->get_var("SHOW TABLES LIKE '{$table_name}'")!=$table_name ){
|
638 |
+
$sql = 'CREATE TABLE '.$table_name.' (
|
639 |
+
id int(11) NOT NULL AUTO_INCREMENT,
|
640 |
+
user_id bigint(20) NOT NULL,
|
641 |
+
user_login varchar(60),
|
642 |
+
user_remoteaddr varchar(255),
|
643 |
+
user_lastlogin DATETIME DEFAULT "0000-00-00 00:00:00" NOT NULL,
|
644 |
+
UNIQUE KEY id(id)
|
645 |
+
)';
|
646 |
+
|
647 |
+
require_once(ABSPATH.'wp-admin/includes/upgrade.php');
|
648 |
+
dbDelta($sql);
|
649 |
+
}
|
650 |
+
}
|
651 |
+
}
|
652 |
+
add_action('plugins_loaded', 'sucuriscan_lastlogins_table_exists');
|
653 |
+
|
654 |
+
function sucuriscan_set_lastlogin($user_login='')
|
655 |
+
{
|
656 |
+
global $wpdb;
|
657 |
+
if( defined('SUCURISCAN_LASTLOGINS_TABLENAME') ){
|
658 |
+
$table_name = SUCURISCAN_LASTLOGINS_TABLENAME;
|
659 |
+
$current_user = get_user_by('login', $user_login);
|
660 |
+
|
661 |
+
sucuriscan_set_flashdata('lastlogin', 'Last user login at '.date('Y/M/d H:i:s').' from '.$_SERVER['REMOTE_ADDR']);
|
662 |
+
|
663 |
+
$wpdb->insert($table_name, array(
|
664 |
+
'user_id'=>$current_user->ID,
|
665 |
+
'user_login'=>$current_user->user_login,
|
666 |
+
'user_remoteaddr'=>isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'127.0.0.1',
|
667 |
+
'user_lastlogin'=>current_time('mysql')
|
668 |
+
));
|
669 |
+
}
|
670 |
+
}
|
671 |
+
add_action('wp_login', 'sucuriscan_set_lastlogin', 50);
|
672 |
+
|
673 |
+
function sucuriscan_get_logins($limit=10, $user_id=0)
|
674 |
+
{
|
675 |
+
global $wpdb;
|
676 |
+
if( defined('SUCURISCAN_LASTLOGINS_TABLENAME') ){
|
677 |
+
$table_name = SUCURISCAN_LASTLOGINS_TABLENAME;
|
678 |
+
|
679 |
+
$sql = "SELECT * FROM {$table_name} RIGHT JOIN {$wpdb->prefix}users ON {$table_name}.user_id = {$wpdb->prefix}users.ID";
|
680 |
+
if( !is_admin() ){
|
681 |
+
$current_user = wp_get_current_user();
|
682 |
+
$sql .= chr(32)."WHERE {$wpdb->prefix}users.user_login = '{$current_user->user_login}'";
|
683 |
+
}
|
684 |
+
if( $user_id>0 ){
|
685 |
+
$where_append = strpos('WHERE ', $sql)===FALSE ? 'WHERE' : 'AND';
|
686 |
+
$sql .= chr(32)."{$where_append} {$table_name}.user_id = '{$user_id}'";
|
687 |
+
}
|
688 |
+
$sql .= chr(32)."ORDER BY {$table_name}.id DESC";
|
689 |
+
if( preg_match('/^([0-9]+)$/', $limit) && $limit>0 ){
|
690 |
+
$sql .= chr(32)."LIMIT {$limit}";
|
691 |
+
}
|
692 |
+
return $wpdb->get_results($sql);
|
693 |
+
}
|
694 |
+
|
695 |
+
return FALSE;
|
696 |
+
}
|
697 |
+
|
698 |
?>
|
sucuriscan_core_integrity.php
CHANGED
@@ -61,29 +61,29 @@ function sucuriscan_core_integrity_lib()
|
|
61 |
|
62 |
sucuriscan_core_integrity_function_wrapper(
|
63 |
'sucuriwp_core_integrity_check',
|
64 |
-
'
|
65 |
);
|
66 |
sucuriscan_core_integrity_function_wrapper(
|
67 |
'sucuriwp_list_admins',
|
68 |
-
'
|
69 |
);
|
70 |
sucuriscan_core_integrity_function_wrapper(
|
71 |
'sucuriwp_content_check',
|
72 |
-
'
|
73 |
);
|
74 |
sucuriscan_core_integrity_function_wrapper(
|
75 |
'sucuriwp_check_plugins',
|
76 |
-
'
|
77 |
);
|
78 |
sucuriscan_core_integrity_function_wrapper(
|
79 |
'sucuriwp_check_themes',
|
80 |
-
'
|
81 |
);
|
82 |
?>
|
83 |
|
84 |
</div>
|
85 |
|
86 |
-
<p align="center"><strong>If you have any questions about these
|
87 |
|
88 |
<?php
|
89 |
}
|
61 |
|
62 |
sucuriscan_core_integrity_function_wrapper(
|
63 |
'sucuriwp_core_integrity_check',
|
64 |
+
'This test will check wp-includes, wp-admin, and the top directory files against the latest WordPress hashing database. If any of those files were modified, it is a big sign of a possible compromise.'
|
65 |
);
|
66 |
sucuriscan_core_integrity_function_wrapper(
|
67 |
'sucuriwp_list_admins',
|
68 |
+
'List all administrator users and their latest login time.'
|
69 |
);
|
70 |
sucuriscan_core_integrity_function_wrapper(
|
71 |
'sucuriwp_content_check',
|
72 |
+
'This test will list all files inside wp-content that have been modified in the past 3 days.'
|
73 |
);
|
74 |
sucuriscan_core_integrity_function_wrapper(
|
75 |
'sucuriwp_check_plugins',
|
76 |
+
'This test will list any outdated (active) plugins.'
|
77 |
);
|
78 |
sucuriscan_core_integrity_function_wrapper(
|
79 |
'sucuriwp_check_themes',
|
80 |
+
'This test will list any outdated theme.'
|
81 |
);
|
82 |
?>
|
83 |
|
84 |
</div>
|
85 |
|
86 |
+
<p align="center"><strong>If you have any questions about these tests or this plugin, contact us at info@sucuri.net or visit <a href="http://sucuri.net">Sucuri Security</a></strong></p>
|
87 |
|
88 |
<?php
|
89 |
}
|