Version Description
- Added list of logged in users.
- Added system page.
- Change the integrity checking to use WP API.
Download this release
Release Info
Developer | dd@sucuri.net |
Plugin | Sucuri Security – Auditing, Malware Scanner and Security Hardening |
Version | 1.5.5 |
Comparing to | |
See all releases |
Code changes from version 1.5.2 to 1.5.5
- inc/css/sucuriscan-default-css.css +16 -8
- {images → inc/images}/menu-icon.png +0 -0
- {images → inc/images}/ok.png +0 -0
- {images → inc/images}/warn.png +0 -0
- inc/tpl/about.html.tpl +160 -0
- inc/tpl/infosys-cronjobs.html.tpl +19 -0
- inc/tpl/infosys-cronjobs.snippet.tpl +7 -0
- inc/tpl/infosys-htaccess.html.tpl +1 -1
- inc/tpl/infosys.html.tpl +3 -1
- inc/tpl/integrity-admins.html.tpl +2 -2
- inc/tpl/integrity-admins.snippet.tpl +7 -1
- inc/tpl/sidebar.html.tpl +1 -1
- lib/core_integrity.php +0 -269
- lib/hardening.php +0 -379
- readme.txt +11 -4
- sucuri.php +1826 -457
- sucuriscan_core_integrity.php +0 -152
- sucuriscan_hardening.php +0 -57
inc/css/sucuriscan-default-css.css
CHANGED
@@ -3,21 +3,26 @@
|
|
3 |
* Copyright (C) 2010-2012 Sucuri Security - http://sucuri.net
|
4 |
* Released under the GPL - see LICENSE file for details.
|
5 |
*/
|
6 |
-
.sucuriscan_header{background:#333;border-
|
7 |
.sucuriscan_header img{float:left;height:38px;width:101px}
|
8 |
.wrap .sucuriscan_header h2{color:#fff;float:left;margin-left:10px;padding:3px 0 0;text-shadow:#000 0 1px 0}
|
9 |
-
.sucuriscan-maincontent{padding:
|
10 |
-
#sidebar{
|
11 |
#sidebar .sucuriscan-sidebar{border:1px solid #ccc;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top-left-radius:5px;border-top-right-radius:5px;margin:0 0 10px;padding:10px 15px}
|
12 |
#sitecleanup.sucuriscan-sidebar{background-color:#bbe8f5;border-color:#4393ac}
|
13 |
#sucuri-latest-posts.sucuriscan-sidebar{background-color:#ececec;border-color:#999}
|
|
|
14 |
.sucuriscan-maincontent .widefat tbody th.check-column{padding:6px 0 3px 0}
|
15 |
.sucuriscan-maincontent .hardening-box .primary-secondary{margin:0 0 0 10px}
|
16 |
.sucuriscan-maincontent a.lastlogins-showall{display:inline-block;float:right}
|
|
|
|
|
17 |
.sucuri-alert{position:relative}
|
18 |
-
.sucuri-alert-updated{background-color:#bbe8f5 !important;border-color:#4393ac !important}
|
19 |
.sucuri-alert>a.close{position:absolute;top:8px;right:10px;font-size:18px;text-decoration:none}
|
20 |
-
.sucuri-
|
|
|
|
|
|
|
21 |
.sucuri-inline-error{font-weight:bold;color:red}
|
22 |
.sucuri-list li{list-style:disc;margin:0 0 5px 15px}
|
23 |
.sucuriscan-maincontent hr{border:none;border-top:1px solid #999}
|
@@ -28,9 +33,12 @@
|
|
28 |
.sucuriscan-maincontent .thead-with-button span{line-height:24px}
|
29 |
.sucuriscan-maincontent .thead-with-button .input-text{line-height:22px}
|
30 |
.sucuriscan-maincontent .thead-topright-action{display:inline-block;float:right}
|
31 |
-
|
32 |
.sucuriscan-monospace{font-family: Monaco, Monospace, Courier;line-height:26px}
|
33 |
.sucuriscan-maincontent .sucuri-infosys-htaccess{margin:20px 0 0 0}
|
34 |
-
.sucuriscan-maincontent .sucuri-full-textarea{width:100%;height:
|
35 |
-
.sucuriscan-maincontent .sucuri-notice-error{background:#ffebe8;margin:5px 0 15px;padding:0 .6em;border:1px solid #c00;border-radius:3px}
|
36 |
.sucuriscan-wpconfig-textarea{width:600px;height:525px;background:#f5f5f5;line-height:1.4em;resize:none;margin:15px 0 0 0;padding:10px}
|
|
|
|
|
|
|
|
|
|
3 |
* Copyright (C) 2010-2012 Sucuri Security - http://sucuri.net
|
4 |
* Released under the GPL - see LICENSE file for details.
|
5 |
*/
|
6 |
+
.sucuriscan_header{background:#333;border-radius:5px;height:38px;margin:0 0 20px 0;min-width:255px;padding:10px;position:relative}
|
7 |
.sucuriscan_header img{float:left;height:38px;width:101px}
|
8 |
.wrap .sucuriscan_header h2{color:#fff;float:left;margin-left:10px;padding:3px 0 0;text-shadow:#000 0 1px 0}
|
9 |
+
.sucuriscan-maincontent{padding:0 20px 0 0}
|
10 |
+
#sidebar{}
|
11 |
#sidebar .sucuriscan-sidebar{border:1px solid #ccc;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top-left-radius:5px;border-top-right-radius:5px;margin:0 0 10px;padding:10px 15px}
|
12 |
#sitecleanup.sucuriscan-sidebar{background-color:#bbe8f5;border-color:#4393ac}
|
13 |
#sucuri-latest-posts.sucuriscan-sidebar{background-color:#ececec;border-color:#999}
|
14 |
+
.sucuriscan-maincontent #poststuff{padding-top:0}
|
15 |
.sucuriscan-maincontent .widefat tbody th.check-column{padding:6px 0 3px 0}
|
16 |
.sucuriscan-maincontent .hardening-box .primary-secondary{margin:0 0 0 10px}
|
17 |
.sucuriscan-maincontent a.lastlogins-showall{display:inline-block;float:right}
|
18 |
+
.sucuri-visible{}
|
19 |
+
.sucuri-hidden{display:none !important}
|
20 |
.sucuri-alert{position:relative}
|
|
|
21 |
.sucuri-alert>a.close{position:absolute;top:8px;right:10px;font-size:18px;text-decoration:none}
|
22 |
+
.sucuri-alert-updated, .sucuri-alert-error{background:#fff;margin:5px 0 15px;padding:1px 12px;border:1px solid #e5e5e5;border-left:4px solid #ccc}
|
23 |
+
.sucuri-alert-updated{border-left:4px solid #7ad03a}
|
24 |
+
.sucuri-alert-error{border-left:4px solid #dd3d36}
|
25 |
+
.sucuri-alert-updated p, .sucuri-alert-error p{margin:.5em 0;padding:2px}
|
26 |
.sucuri-inline-error{font-weight:bold;color:red}
|
27 |
.sucuri-list li{list-style:disc;margin:0 0 5px 15px}
|
28 |
.sucuriscan-maincontent hr{border:none;border-top:1px solid #999}
|
33 |
.sucuriscan-maincontent .thead-with-button span{line-height:24px}
|
34 |
.sucuriscan-maincontent .thead-with-button .input-text{line-height:22px}
|
35 |
.sucuriscan-maincontent .thead-topright-action{display:inline-block;float:right}
|
|
|
36 |
.sucuriscan-monospace{font-family: Monaco, Monospace, Courier;line-height:26px}
|
37 |
.sucuriscan-maincontent .sucuri-infosys-htaccess{margin:20px 0 0 0}
|
38 |
+
.sucuriscan-maincontent .sucuri-full-textarea{width:100%;height:400px;line-height:normal;resize:vertical;padding:10px}
|
|
|
39 |
.sucuriscan-wpconfig-textarea{width:600px;height:525px;background:#f5f5f5;line-height:1.4em;resize:none;margin:15px 0 0 0;padding:10px}
|
40 |
+
.sucuriscan-maincontent .sucuriscan-about-list{margin:20px 0}
|
41 |
+
.sucuriscan-maincontent .sucuriscan-about-list td+td{font-family:Monaco, Monspace, Courier;font-weight:bold}
|
42 |
+
.sucuriscan-maincontent .sucuriscan-wpcron-list{margin:20px 0 15px 0}
|
43 |
+
.sucuriscan-maincontent .sucuriscan-wpcron-list td+td+td+td{font-family:Monaco, Monspace, Courier;font-weight:bold}
|
44 |
+
.sucuriscan-results .icon-ok, .sucuriscan-results .icon-warn, .sucuriscan-results .icon-error{position:relative;top:5px;width:22px;height:22px}
|
{images → inc/images}/menu-icon.png
RENAMED
File without changes
|
{images → inc/images}/ok.png
RENAMED
File without changes
|
{images → inc/images}/warn.png
RENAMED
File without changes
|
inc/tpl/about.html.tpl
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wrap">
|
2 |
+
<h2 id="warnings_hook"></h2>
|
3 |
+
<div class="sucuriscan_header">
|
4 |
+
<a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">
|
5 |
+
<img src="%%SUCURI.SucuriURL%%/inc/images/logo.png" alt="Sucuri Security" />
|
6 |
+
</a>
|
7 |
+
<h2>Sucuri Security WordPress Plugin (About)</h2>
|
8 |
+
</div>
|
9 |
+
|
10 |
+
<div class="postbox-container" style="width:75%;">
|
11 |
+
<div class="sucuriscan-maincontent">
|
12 |
+
<div id="poststuff">
|
13 |
+
<div class="postbox">
|
14 |
+
<h3>About</h3>
|
15 |
+
<div class="inside">
|
16 |
+
<p>
|
17 |
+
Our WordPress Security Plugin will monitor your site from the inside, creating
|
18 |
+
a complete audit trail, alerting you of possible security issues (file changes,
|
19 |
+
password guessing attacks, etc) and blocking the attackers. This is the perfect
|
20 |
+
complement for our external security scans.
|
21 |
+
</p>
|
22 |
+
</div>
|
23 |
+
</div>
|
24 |
+
</div><!-- End poststuff -->
|
25 |
+
|
26 |
+
<table class="wp-list-table widefat sucuriscan-about-list sucuri-%%SUCURI.SettingsDisplay%%">
|
27 |
+
<thead>
|
28 |
+
<tr>
|
29 |
+
<th colspan="2">Plugin & Server Information</th>
|
30 |
+
</tr>
|
31 |
+
</thead>
|
32 |
+
|
33 |
+
<tbody>
|
34 |
+
<tr><td>Sucuri Plugin version</td><td>%%SUCURI.PluginVersion%%</td></li>
|
35 |
+
<tr><td>Sucuri Plugin MD5Sum (sucuri.php)</td><td>%%SUCURI.PluginMD5%%</td></li>
|
36 |
+
<tr><td>Sucuri Plugin Last-time scan</td><td>%%SUCURI.PluginRuntimeDatetime%%</td></li>
|
37 |
+
<tr><td>Operating System</td><td>%%SUCURI.OperatingSystem%%</td></li>
|
38 |
+
<tr><td>Server</td><td>%%SUCURI.Server%%</td></li>
|
39 |
+
<tr><td>Memory usage</td><td>%%SUCURI.MemoryUsage%%</td></li>
|
40 |
+
<tr><td>MYSQL Version</td><td>%%SUCURI.MySQLVersion%%</td></li>
|
41 |
+
<tr><td>SQL Mode</td><td>%%SUCURI.SQLMode%%</td></li>
|
42 |
+
<tr><td>PHP Version</td><td>%%SUCURI.PHPVersion%%</td></li>
|
43 |
+
<tr><td>PHP Safe Mode</td><td>%%SUCURI.SafeMode%%</td></li>
|
44 |
+
<tr><td>PHP Allow URL fopen</td><td>%%SUCURI.AllowUrlFopen%%</td></li>
|
45 |
+
<tr><td>PHP Memory Limit</td><td>%%SUCURI.MemoryLimit%%</td></li>
|
46 |
+
<tr><td>PHP Max Upload Size</td><td>%%SUCURI.UploadMaxFilesize%%</td></li>
|
47 |
+
<tr><td>PHP Max Post Size</td><td>%%SUCURI.PostMaxSize%%</td></li>
|
48 |
+
<tr><td>PHP Max Script Execute Time</td><td>%%SUCURI.MaxExecutionTime%%</td></li>
|
49 |
+
<tr><td>PHP Max Input Time</td><td>%%SUCURI.MaxInputTime%%</td></li>
|
50 |
+
</tbody>
|
51 |
+
</table>
|
52 |
+
|
53 |
+
<div id="poststuff">
|
54 |
+
<div class="postbox">
|
55 |
+
<h3>How does it work?</h3>
|
56 |
+
<div class="inside">
|
57 |
+
<ul>
|
58 |
+
<li>Web Application Firewall. Block attacks before they reach your site.</li>
|
59 |
+
<li>Integrity Monitoring. Receive notifications if any of your files are modified.</li>
|
60 |
+
<li>Audit Logs. Keep track of everything that happens inside WordPress, including new users, posts, login failures and successful logins.</li>
|
61 |
+
<li>Activity Reporting</li>
|
62 |
+
<li>1-click Hardening. Easy-to-use hardening options for your site.</li>
|
63 |
+
</ul>
|
64 |
+
</div>
|
65 |
+
</div>
|
66 |
+
</div><!-- End poststuff -->
|
67 |
+
|
68 |
+
<div id="poststuff">
|
69 |
+
<div class="postbox">
|
70 |
+
<h3>Web Application Firewall (WAF)</h3>
|
71 |
+
<div class="inside">
|
72 |
+
<p>
|
73 |
+
The WAF is a unique feature that is designed to intelligently protect your sites
|
74 |
+
from brute-force attacks like dictionary attacks and other similar unauthorized
|
75 |
+
access attempts. When a bad IP is identified it is blacklisted in your admin
|
76 |
+
dashboard. If it was an unintentional block, you have the ability to white-list
|
77 |
+
access to any IP.
|
78 |
+
</p>
|
79 |
+
<p>
|
80 |
+
The WAF is not tied to your application, it communicates with our servers and
|
81 |
+
allows us to see malicious attacks across the network. When one client gets attacked
|
82 |
+
by one bad IP in Croatia, we are able to push preventive measures to every plugin
|
83 |
+
to protect against that IP.
|
84 |
+
</p>
|
85 |
+
</div>
|
86 |
+
</div>
|
87 |
+
</div><!-- End poststuff -->
|
88 |
+
|
89 |
+
<div id="poststuff">
|
90 |
+
<div class="postbox">
|
91 |
+
<h3>Integrity Monitoring</h3>
|
92 |
+
<div class="inside">
|
93 |
+
<p>
|
94 |
+
This feature compares your core install against a clean version of core. In other
|
95 |
+
words, if it is not a 1-to-1 match with core you will be notified of a problem.
|
96 |
+
Future add-ons include:
|
97 |
+
</p>
|
98 |
+
<ul>
|
99 |
+
<li>Theme Integrity Checks</li>
|
100 |
+
<li>Plugin Integrity Checks</li>
|
101 |
+
<li>Third-party Integrity Checks</li>
|
102 |
+
</ul>
|
103 |
+
</div>
|
104 |
+
</div>
|
105 |
+
</div><!-- End poststuff -->
|
106 |
+
|
107 |
+
<div id="poststuff">
|
108 |
+
<div class="postbox">
|
109 |
+
<h3>Audit Trails</h3>
|
110 |
+
<div class="inside">
|
111 |
+
<p>
|
112 |
+
This feature is great for proactive webmasters who want to monitor their website
|
113 |
+
to ensure no unauthorized access or changes are made without prior approval.
|
114 |
+
Monitor your site for changes. This feature monitors for a large number of actions,
|
115 |
+
including:
|
116 |
+
</p>
|
117 |
+
<ul>
|
118 |
+
<li>Login attempts</li>
|
119 |
+
<li>New Posts</li>
|
120 |
+
<li>Failed Logins</li>
|
121 |
+
<li>New Plugins</li>
|
122 |
+
<li>File Changes</li>
|
123 |
+
<li>New Users</li>
|
124 |
+
<li>New Attachments</li>
|
125 |
+
<li>Delete Actions (users and posts)</li>
|
126 |
+
<li>Revisions</li>
|
127 |
+
</ul>
|
128 |
+
</div>
|
129 |
+
</div>
|
130 |
+
</div><!-- End poststuff -->
|
131 |
+
|
132 |
+
<div id="poststuff">
|
133 |
+
<div class="postbox">
|
134 |
+
<h3>1-Click Hardening</h3>
|
135 |
+
<div class="inside">
|
136 |
+
<p>
|
137 |
+
In our experience a high-percentage of the infections we see every day come from
|
138 |
+
poor management on the end-user’s part. This feature uses common hardening
|
139 |
+
measures that can be taken at any time and helps reduce infection risk. This
|
140 |
+
feature performs the following:
|
141 |
+
</p>
|
142 |
+
<ul>
|
143 |
+
<li>Checks software core version</li>
|
144 |
+
<li>Hides your version (security through obscurity)</li>
|
145 |
+
<li>Upload directory protected</li>
|
146 |
+
<li>Secret keys and salts created</li>
|
147 |
+
<li>Configuration file hardening/location verification</li>
|
148 |
+
<li>Hardening of readme file</li>
|
149 |
+
<li>PHP verification</li>
|
150 |
+
</ul>
|
151 |
+
</div>
|
152 |
+
</div>
|
153 |
+
</div><!-- End poststuff -->
|
154 |
+
|
155 |
+
</div><!-- End sucuriscan-maincontent -->
|
156 |
+
</div><!-- End postbox-container -->
|
157 |
+
|
158 |
+
%%SUCURI.SucuriWPSidebar%%
|
159 |
+
|
160 |
+
</div><!-- End wrap -->
|
inc/tpl/infosys-cronjobs.html.tpl
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<table class="wp-list-table widefat sucuriscan-wpcron-list">
|
3 |
+
<thead>
|
4 |
+
<tr>
|
5 |
+
<th colspan="4">Wordpress Cronjobs (%%SUCURI.Cronjobs.Total%% tasks)</th>
|
6 |
+
</tr>
|
7 |
+
<tr>
|
8 |
+
<th>Task</th>
|
9 |
+
<th>Schedule</th>
|
10 |
+
<th>Next due (GMT/UTC)</th>
|
11 |
+
<th>Wordpress Hook</th>
|
12 |
+
<!-- <th>Hook arguments</th> -->
|
13 |
+
</tr>
|
14 |
+
</thead>
|
15 |
+
|
16 |
+
<tbody>
|
17 |
+
%%SUCURI.Cronjobs.List%%
|
18 |
+
</tbody>
|
19 |
+
</table>
|
inc/tpl/infosys-cronjobs.snippet.tpl
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr>
|
2 |
+
<td>%%SUCURI.Cronjob.Task%%</td>
|
3 |
+
<td>%%SUCURI.Cronjob.Schedule%%</td>
|
4 |
+
<td>%%SUCURI.Cronjob.Nexttime%%</td>
|
5 |
+
<td>%%SUCURI.Cronjob.Hook%%</td>
|
6 |
+
<!-- <td>%%SUCURI.Cronjob.Arguments%%</td> -->
|
7 |
+
</tr>
|
inc/tpl/infosys-htaccess.html.tpl
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
modifies this file to be able to handle pretty permalinks.
|
11 |
</p>
|
12 |
|
13 |
-
<div class="sucuri-
|
14 |
<p>%%SUCURI.HTAccess.Message%%</p>
|
15 |
</div>
|
16 |
|
10 |
modifies this file to be able to handle pretty permalinks.
|
11 |
</p>
|
12 |
|
13 |
+
<div class="sucuri-alert-%%SUCURI.HTAccess.MessageType%% %%SUCURI.HTAccess.MessageVisible%%">
|
14 |
<p>%%SUCURI.HTAccess.Message%%</p>
|
15 |
</div>
|
16 |
|
inc/tpl/infosys.html.tpl
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
<a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">
|
5 |
<img src="%%SUCURI.SucuriURL%%/inc/images/logo.png" alt="Sucuri Security" />
|
6 |
</a>
|
7 |
-
<h2>Sucuri Security WordPress Plugin (Info
|
8 |
</div>
|
9 |
|
10 |
|
@@ -12,6 +12,8 @@
|
|
12 |
<div class="sucuriscan-maincontent">
|
13 |
%%SUCURI.LoggedInUsers%%
|
14 |
|
|
|
|
|
15 |
%%SUCURI.HTAccessIntegrity%%
|
16 |
|
17 |
%%SUCURI.WordpressConfig%%
|
4 |
<a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">
|
5 |
<img src="%%SUCURI.SucuriURL%%/inc/images/logo.png" alt="Sucuri Security" />
|
6 |
</a>
|
7 |
+
<h2>Sucuri Security WordPress Plugin (Site Info)</h2>
|
8 |
</div>
|
9 |
|
10 |
|
12 |
<div class="sucuriscan-maincontent">
|
13 |
%%SUCURI.LoggedInUsers%%
|
14 |
|
15 |
+
%%SUCURI.Cronjobs%%
|
16 |
+
|
17 |
%%SUCURI.HTAccessIntegrity%%
|
18 |
|
19 |
%%SUCURI.WordpressConfig%%
|
inc/tpl/integrity-admins.html.tpl
CHANGED
@@ -1,12 +1,13 @@
|
|
1 |
<table class="wp-list-table widefat">
|
2 |
<thead>
|
3 |
<tr>
|
4 |
-
<th colspan="
|
5 |
</tr>
|
6 |
<tr>
|
7 |
<th class="manage-column">Username</th>
|
8 |
<th class="manage-column">Email</th>
|
9 |
<th class="manage-column">Last Logins (newest to oldest)</th>
|
|
|
10 |
</tr>
|
11 |
</thead>
|
12 |
|
@@ -14,4 +15,3 @@
|
|
14 |
%%SUCURI.AdminUsers.UserList%%
|
15 |
</tbody>
|
16 |
</table>
|
17 |
-
<br>
|
1 |
<table class="wp-list-table widefat">
|
2 |
<thead>
|
3 |
<tr>
|
4 |
+
<th colspan="4">Administrator Users</th>
|
5 |
</tr>
|
6 |
<tr>
|
7 |
<th class="manage-column">Username</th>
|
8 |
<th class="manage-column">Email</th>
|
9 |
<th class="manage-column">Last Logins (newest to oldest)</th>
|
10 |
+
<th class="manage-column"> </th>
|
11 |
</tr>
|
12 |
</thead>
|
13 |
|
15 |
%%SUCURI.AdminUsers.UserList%%
|
16 |
</tbody>
|
17 |
</table>
|
|
inc/tpl/integrity-admins.snippet.tpl
CHANGED
@@ -2,7 +2,10 @@
|
|
2 |
<td>%%SUCURI.AdminUsers.Username%%</td>
|
3 |
<td><a href="mailto:%%SUCURI.AdminUsers.Email%%">%%SUCURI.AdminUsers.Email%%</a></td>
|
4 |
<td class="adminusers-lastlogin">
|
5 |
-
<div class="sucuri-%%SUCURI.AdminUsers.NoLastLogins%%">
|
|
|
|
|
|
|
6 |
<table class="widefat sucuri-%%SUCURI.AdminUsers.NoLastLoginsTable%%">
|
7 |
<thead>
|
8 |
<tr>
|
@@ -15,4 +18,7 @@
|
|
15 |
</tbody>
|
16 |
</table>
|
17 |
</td>
|
|
|
|
|
|
|
18 |
</tr>
|
2 |
<td>%%SUCURI.AdminUsers.Username%%</td>
|
3 |
<td><a href="mailto:%%SUCURI.AdminUsers.Email%%">%%SUCURI.AdminUsers.Email%%</a></td>
|
4 |
<td class="adminusers-lastlogin">
|
5 |
+
<div class="sucuri-%%SUCURI.AdminUsers.NoLastLogins%%">
|
6 |
+
<i>There isn't information available for this account.</i>
|
7 |
+
</div>
|
8 |
+
|
9 |
<table class="widefat sucuri-%%SUCURI.AdminUsers.NoLastLoginsTable%%">
|
10 |
<thead>
|
11 |
<tr>
|
18 |
</tbody>
|
19 |
</table>
|
20 |
</td>
|
21 |
+
<td>
|
22 |
+
<a href="%%SUCURI.AdminUsers.UserURL%%" target="_blank" class="button-primary">Edit</a>
|
23 |
+
</td>
|
24 |
</tr>
|
inc/tpl/sidebar.html.tpl
CHANGED
@@ -21,4 +21,4 @@
|
|
21 |
<a href="http://cloudproxy.sucuri.net/" target="_blank" class="button button-primary">Read more</a>
|
22 |
</div>
|
23 |
</div>
|
24 |
-
</div>
|
21 |
<a href="http://cloudproxy.sucuri.net/" target="_blank" class="button button-primary">Read more</a>
|
22 |
</div>
|
23 |
</div>
|
24 |
+
</div>
|
lib/core_integrity.php
DELETED
@@ -1,269 +0,0 @@
|
|
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 read_dir_r($dir = "./", $recursiv = false)
|
12 |
-
{
|
13 |
-
$skipname = basename(__FILE__);
|
14 |
-
$skipname .= ",_sucuribackup,wp-config.php";
|
15 |
-
|
16 |
-
$files_info = array();
|
17 |
-
|
18 |
-
$dir_handler = opendir($dir);
|
19 |
-
|
20 |
-
while(($entry = readdir($dir_handler)) !== false) {
|
21 |
-
if ($entry != "." && $entry != "..") {
|
22 |
-
$dir = preg_replace("/^(.*)(\/)+$/", "$1", $dir);
|
23 |
-
$item = $dir . "/" . $entry;
|
24 |
-
if (is_file($item)) {
|
25 |
-
|
26 |
-
$skip_parts = explode(",", $skipname);
|
27 |
-
foreach ($skip_parts as $skip) {
|
28 |
-
if (strpos($item,$skip) !== false) {
|
29 |
-
continue 2;
|
30 |
-
}
|
31 |
-
}
|
32 |
-
|
33 |
-
$md5 = @md5_file($item);
|
34 |
-
$time_stamp = @filectime($item);
|
35 |
-
$item_name = str_replace(ABSPATH, "./", $item);
|
36 |
-
$files_info[$item_name] = array(
|
37 |
-
'md5' => $md5,
|
38 |
-
'time' => $time_stamp
|
39 |
-
);
|
40 |
-
|
41 |
-
}
|
42 |
-
elseif (is_dir($item) && $recursiv) {
|
43 |
-
$files_info = array_merge( $files_info , read_dir_r($item) );
|
44 |
-
}
|
45 |
-
}
|
46 |
-
}
|
47 |
-
|
48 |
-
closedir($dir_handler);
|
49 |
-
return $files_info;
|
50 |
-
}
|
51 |
-
|
52 |
-
function sucuriwp_core_integrity_check()
|
53 |
-
{
|
54 |
-
|
55 |
-
global $wp_version;
|
56 |
-
|
57 |
-
$curlang = get_bloginfo("language");
|
58 |
-
|
59 |
-
$cp = 0;
|
60 |
-
$updates = get_core_updates();
|
61 |
-
if( !is_array($updates) || empty($updates) || $updates[0]->response=='latest' ){
|
62 |
-
$cp = 1;
|
63 |
-
}
|
64 |
-
if(strcmp($wp_version, "3.7") < 0)
|
65 |
-
{
|
66 |
-
$cp = 0;
|
67 |
-
}
|
68 |
-
$wp_version = htmlspecialchars($wp_version);
|
69 |
-
|
70 |
-
if($cp == 0)
|
71 |
-
{
|
72 |
-
echo '<p><img style="position:relative;top:5px" height="22" width="22" '
|
73 |
-
.'src="'.SUCURI_URL.'images/warn.png" /> Your current version ('.$wp_version.') is not the latest. '
|
74 |
-
.'<a class="button-primary" href="update-core.php">Update now!</a> to be able to run the integrity check.</p>';
|
75 |
-
}
|
76 |
-
else
|
77 |
-
{
|
78 |
-
$latest_hashes = @file_get_contents("http://wordpress.sucuri.net/wp_core_latest_hashes.json");
|
79 |
-
if($latest_hashes){
|
80 |
-
$wp_core_latest_hashes = json_decode($latest_hashes, true);
|
81 |
-
|
82 |
-
$wp_includes_hashes = read_dir_r( ABSPATH . "wp-includes", true);
|
83 |
-
$wp_admin_hashes = read_dir_r( ABSPATH . "wp-admin", true);
|
84 |
-
$wp_top_hashes = read_dir_r( ABSPATH , false);
|
85 |
-
|
86 |
-
$wp_core_hashes = array_merge( $wp_includes_hashes , $wp_admin_hashes );
|
87 |
-
$wp_core_hashes = array_merge( $wp_core_hashes , $wp_top_hashes );
|
88 |
-
|
89 |
-
$added = @array_diff_assoc( $wp_core_hashes, $wp_core_latest_hashes ); //files added
|
90 |
-
$removed = @array_diff_assoc( $wp_core_latest_hashes, $wp_core_hashes ); //files deleted
|
91 |
-
unset($removed['wp_version']); //ignore wp_version key
|
92 |
-
$compcurrent = @array_diff_key( $wp_core_hashes, $added ); //remove all added files from current filelist
|
93 |
-
$complog = @array_diff_key( $wp_core_latest_hashes, $removed ); //remove all deleted files from old file list
|
94 |
-
$modified = array(); //array of modified files
|
95 |
-
|
96 |
-
//compare file hashes and mod dates
|
97 |
-
foreach ( $compcurrent as $currfile => $currattr) {
|
98 |
-
|
99 |
-
if ( array_key_exists( $currfile, $complog ) ) {
|
100 |
-
|
101 |
-
//if attributes differ added to modified files array
|
102 |
-
if ( strcmp( $currattr['md5'], $complog[$currfile]['md5'] ) != 0 ) {
|
103 |
-
$modified[$currfile]['md5'] = $currattr['md5'];
|
104 |
-
}
|
105 |
-
|
106 |
-
}
|
107 |
-
|
108 |
-
}
|
109 |
-
|
110 |
-
//ignore some junk files
|
111 |
-
if($curlang != "en_US")
|
112 |
-
{
|
113 |
-
//ignore added files
|
114 |
-
unset($added['./licencia.txt']);
|
115 |
-
|
116 |
-
//ignore removed files
|
117 |
-
unset($removed['./license.txt']);
|
118 |
-
|
119 |
-
//ignore modified files
|
120 |
-
unset($modified['./wp-includes/version.php']);
|
121 |
-
unset($modified['./wp-admin/setup-config.php']);
|
122 |
-
unset($modified['./readme.html']);
|
123 |
-
unset($modified['./wp-config-sample.php']);
|
124 |
-
}
|
125 |
-
|
126 |
-
sucuriscan_draw_corefiles_status(array(
|
127 |
-
'added'=>$added,
|
128 |
-
'removed'=>$removed,
|
129 |
-
'modified'=>$modified
|
130 |
-
));
|
131 |
-
}else{
|
132 |
-
sucuriscan_admin_notice('error', 'Error retrieving the wordpress core hashes, try again.');
|
133 |
-
}
|
134 |
-
}
|
135 |
-
}
|
136 |
-
|
137 |
-
function sucuriscan_draw_corefiles_status($list=array()){
|
138 |
-
if( is_array($list) && !empty($list) ): ?>
|
139 |
-
<table class="wp-list-table widefat sucuriscan-corefiles">
|
140 |
-
<thead>
|
141 |
-
<tr><th>Core files altered</th></tr>
|
142 |
-
</thead>
|
143 |
-
<tbody>
|
144 |
-
<?php
|
145 |
-
foreach($list as $core_file_type=>$core_file_list){
|
146 |
-
printf('<tr><th>Core File %s: %d</th></tr>', ucwords($core_file_type), sizeof($core_file_list));
|
147 |
-
foreach($core_file_list as $filepath=>$extrainfo){
|
148 |
-
printf('<tr><td>%s</td></tr>', $filepath);
|
149 |
-
}
|
150 |
-
}
|
151 |
-
?>
|
152 |
-
</tbody>
|
153 |
-
</table>
|
154 |
-
<?php endif; ?>
|
155 |
-
<?php }
|
156 |
-
|
157 |
-
function sucuriwp_list_admins($userlevel = '10') {
|
158 |
-
|
159 |
-
global $wpdb;
|
160 |
-
/*
|
161 |
-
1 = subscriber
|
162 |
-
2 = editor
|
163 |
-
3 = author
|
164 |
-
7 = publisher
|
165 |
-
10 = administrator
|
166 |
-
*/
|
167 |
-
|
168 |
-
// Page pseudo-variables initialization.
|
169 |
-
$template_variables = array(
|
170 |
-
'SucuriURL'=>SUCURI_URL,
|
171 |
-
'AdminUsers.UserList'=>''
|
172 |
-
);
|
173 |
-
|
174 |
-
$admins = $wpdb->get_results("SELECT * FROM $wpdb->usermeta WHERE meta_value = '$userlevel'");
|
175 |
-
foreach ( (array) $admins as $user ) {
|
176 |
-
$admin = get_userdata( $user->user_id );
|
177 |
-
$admin->lastlogins = sucuriscan_get_logins(4, $admin->ID);
|
178 |
-
$userlevel = $admin->wp2_user_level;
|
179 |
-
$name = $admin->nickname;
|
180 |
-
|
181 |
-
$user_snippet = array(
|
182 |
-
'AdminUsers.Username'=>$admin->user_login,
|
183 |
-
'AdminUsers.Email'=>$admin->user_email,
|
184 |
-
'AdminUsers.LastLogins'=>''
|
185 |
-
);
|
186 |
-
if( !empty($admin->lastlogins) ){
|
187 |
-
$user_snippet['AdminUsers.NoLastLogins'] = 'hidden';
|
188 |
-
$user_snippet['AdminUsers.NoLastLoginsTable'] = 'visible';
|
189 |
-
foreach($admin->lastlogins as $lastlogin){
|
190 |
-
$user_snippet['AdminUsers.LastLogins'] .= sucuriscan_get_template('integrity-admins-lastlogin.snippet.tpl', array(
|
191 |
-
'AdminUsers.RemoteAddr'=>$lastlogin->user_remoteaddr,
|
192 |
-
'AdminUsers.Datetime'=>$lastlogin->user_lastlogin
|
193 |
-
));
|
194 |
-
}
|
195 |
-
}else{
|
196 |
-
$user_snippet['AdminUsers.NoLastLogins'] = 'visible';
|
197 |
-
$user_snippet['AdminUsers.NoLastLoginsTable'] = 'hidden';
|
198 |
-
}
|
199 |
-
|
200 |
-
$template_variables['AdminUsers.UserList'] .= sucuriscan_get_template('integrity-admins.snippet.tpl', $user_snippet);
|
201 |
-
}
|
202 |
-
|
203 |
-
echo sucuriscan_get_template('integrity-admins.html.tpl', $template_variables);
|
204 |
-
}
|
205 |
-
|
206 |
-
function sucuriwp_check_plugins()
|
207 |
-
{
|
208 |
-
do_action("wp_update_plugins"); // force WP to check plugins for updates
|
209 |
-
wp_update_plugins();
|
210 |
-
$update_plugins = get_site_transient('update_plugins'); // get information of updates
|
211 |
-
$plugins_need_update = $update_plugins->response; // plugins that need updating
|
212 |
-
|
213 |
-
echo '<div class="postbox">';
|
214 |
-
echo "<h3>Outdated Plugins</h3>";
|
215 |
-
echo '<div class="inside">';
|
216 |
-
if (!empty($update_plugins->response)) { // any plugin updates available?
|
217 |
-
$plugins_need_update = $update_plugins->response; // plugins that need updating
|
218 |
-
$active_plugins = array_flip(get_option('active_plugins')); // find which plugins are active
|
219 |
-
$plugins_need_update = array_intersect_key($plugins_need_update, $active_plugins); // only keep plugins that are active
|
220 |
-
if(count($plugins_need_update) >= 1) { // any plugins need updating after all the filtering gone on above?
|
221 |
-
require_once(ABSPATH . 'wp-admin/includes/plugin-install.php'); // Required for plugin API
|
222 |
-
require_once(ABSPATH . WPINC . '/version.php' ); // Required for WP core version
|
223 |
-
foreach($plugins_need_update as $key => $data) { // loop through the plugins that need updating
|
224 |
-
$plugin_info = get_plugin_data(WP_PLUGIN_DIR . "/" . $key); // get local plugin info
|
225 |
-
$info = plugins_api('plugin_information', array('slug' => $data->slug )); // get repository plugin info
|
226 |
-
$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";
|
227 |
-
echo "<p>$message</p>";
|
228 |
-
}
|
229 |
-
}
|
230 |
-
else
|
231 |
-
{
|
232 |
-
echo "<p>All plugins are up-to-date!</p>";
|
233 |
-
}
|
234 |
-
}
|
235 |
-
else
|
236 |
-
{
|
237 |
-
echo "<p>All plugins are up-to-date!</p>";
|
238 |
-
}
|
239 |
-
echo '</div>';
|
240 |
-
echo '</div>';
|
241 |
-
}
|
242 |
-
|
243 |
-
function sucuriwp_check_themes()
|
244 |
-
{
|
245 |
-
do_action("wp_update_themes"); // force WP to check for theme updates
|
246 |
-
wp_update_themes();
|
247 |
-
$update_themes = get_site_transient('update_themes'); // get information of updates
|
248 |
-
|
249 |
-
echo '<div class="postbox">';
|
250 |
-
echo "<h3>Outdated Themes</h3>";
|
251 |
-
echo '<div class="inside">';
|
252 |
-
if (!empty($update_themes->response)) { // any theme updates available?
|
253 |
-
$themes_need_update = $update_themes->response; // themes that need updating
|
254 |
-
|
255 |
-
if(count($themes_need_update) >= 1) { // any themes need updating after all the filtering gone on above?
|
256 |
-
foreach($themes_need_update as $key => $data) { // loop through the themes that need updating
|
257 |
-
$theme_info = get_theme_data(WP_CONTENT_DIR . "/themes/" . $key . "/style.css"); // get theme info
|
258 |
-
$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";
|
259 |
-
echo "<p>$message</p>";
|
260 |
-
}
|
261 |
-
}
|
262 |
-
}
|
263 |
-
else
|
264 |
-
{
|
265 |
-
echo "<p>All themes are up-to-date!</p>";
|
266 |
-
}
|
267 |
-
echo '</div>';
|
268 |
-
echo '</div>';
|
269 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/hardening.php
DELETED
@@ -1,379 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/* Sucuri Security - SiteCheck Malware Scanner
|
3 |
-
* Copyright (C) 2010-2013 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" /> '.
|
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 |
-
|
67 |
-
if($updatemsg != NULL){ echo $updatemsg; }
|
68 |
-
|
69 |
-
if($type != NULL)
|
70 |
-
{
|
71 |
-
echo '<input class="button-primary" type="submit" name="'.$type.'"
|
72 |
-
value="Harden it!" />';
|
73 |
-
}
|
74 |
-
}
|
75 |
-
|
76 |
-
|
77 |
-
}
|
78 |
-
|
79 |
-
function sucuriscan_harden_version()
|
80 |
-
{
|
81 |
-
global $wp_version;
|
82 |
-
$cp = 0;
|
83 |
-
$updates = get_core_updates();
|
84 |
-
if (!is_array($updates))
|
85 |
-
{
|
86 |
-
$cp = 1;
|
87 |
-
}
|
88 |
-
else if(empty($updates))
|
89 |
-
{
|
90 |
-
$cp = 1;
|
91 |
-
}
|
92 |
-
else if($updates[0]->response == 'latest')
|
93 |
-
{
|
94 |
-
$cp = 1;
|
95 |
-
}
|
96 |
-
if(strcmp($wp_version, "3.7") < 0)
|
97 |
-
{
|
98 |
-
$cp = 0;
|
99 |
-
}
|
100 |
-
$wp_version = htmlspecialchars($wp_version);
|
101 |
-
|
102 |
-
|
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 |
-
|
110 |
-
if($cp == 0)
|
111 |
-
{
|
112 |
-
echo "<p>Your current version ($wp_version) is not current.</p><p><a class='button-primary' href='update-core.php'>Update now!</a></p>";
|
113 |
-
}
|
114 |
-
else
|
115 |
-
{
|
116 |
-
echo "<p>Your WordPress installation ($wp_version) is current.</p>";
|
117 |
-
}
|
118 |
-
sucuriscan_wrapper_close();
|
119 |
-
}
|
120 |
-
|
121 |
-
function sucuri_harden_removegenerator()
|
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 ".
|
132 |
-
"(enabled by default with this plugin).");
|
133 |
-
|
134 |
-
sucuriscan_wrapper_close();
|
135 |
-
}
|
136 |
-
|
137 |
-
function sucuriscan_harden_upload()
|
138 |
-
{
|
139 |
-
$cp = 1;
|
140 |
-
$upmsg = NULL;
|
141 |
-
$htaccess_upload = dirname(sucuriscan_dir_filepath())."/.htaccess";
|
142 |
-
|
143 |
-
if(!is_readable($htaccess_upload))
|
144 |
-
{
|
145 |
-
$cp = 0;
|
146 |
-
}
|
147 |
-
else
|
148 |
-
{
|
149 |
-
$cp = 0;
|
150 |
-
$fcontent = file($htaccess_upload);
|
151 |
-
foreach($fcontent as $fline)
|
152 |
-
{
|
153 |
-
if(strpos($fline, "deny from all") !== FALSE)
|
154 |
-
{
|
155 |
-
$cp = 1;
|
156 |
-
break;
|
157 |
-
}
|
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 <code>.htaccess</code> file, folder destination is not writable.");
|
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 |
-
sucuriscan_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 |
-
sucuriscan_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)
|
222 |
-
{
|
223 |
-
$cp = 1;
|
224 |
-
break;
|
225 |
-
}
|
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 <code>.htaccess</code> file, folder destination is not writable.");
|
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 |
-
sucuriscan_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 |
-
sucuriscan_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)
|
290 |
-
{
|
291 |
-
$cp = 1;
|
292 |
-
break;
|
293 |
-
}
|
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 <code>.htaccess</code> file, folder destination is not writable.");
|
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 |
-
sucuriscan_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 |
-
sucuriscan_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 |
-
{
|
344 |
-
$phpv = phpversion();
|
345 |
-
|
346 |
-
if(strncmp($phpv, "5.", 2) < 0)
|
347 |
-
{
|
348 |
-
$cp = 0;
|
349 |
-
}
|
350 |
-
else
|
351 |
-
{
|
352 |
-
$cp = 1;
|
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);
|
360 |
-
sucuriscan_wrapper_close();
|
361 |
-
}
|
362 |
-
|
363 |
-
function sucuriscan_cloudproxy_enabled(){
|
364 |
-
$enabled = sucuriscan_is_behind_cloudproxy();
|
365 |
-
|
366 |
-
sucuriscan_wrapper_open('Verify if your site is protected by a Web Firewall');
|
367 |
-
sucuriscan_harden_status(
|
368 |
-
$enabled, NULL,
|
369 |
-
'Your website is protected by a Website Firewall (WAF)',
|
370 |
-
'Your website is not protected by a Website Firewall (WAF)',
|
371 |
-
'A WAF is a protection layer for your web site, blocking all sort of attacks (brute force attempts, DDoS, SQL injections, etc) and helping it remain
|
372 |
-
malware and blacklist free. This test checks if your site is using <a href="http://sucuri.net/services/preventive">Sucuri\'s CloudProxy WAF</a> to protect your site. ',
|
373 |
-
NULL
|
374 |
-
);
|
375 |
-
if( $enabled!==TRUE ){
|
376 |
-
echo '<a href="https://login.sucuri.net/signup2/create?CloudProxy" target="_blank" class="button button-primary">Harden it!</a>';
|
377 |
-
}
|
378 |
-
sucuriscan_wrapper_close();
|
379 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.5.
|
7 |
-
Tested up to: 3.
|
8 |
|
9 |
-
The Sucuri Security - SiteCheck Malware Scanner plugin enables you to scan your WordPress site using Sucuri SiteCheck and
|
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
|
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 |
|
@@ -66,6 +66,13 @@ the compromise on your site).
|
|
66 |
|
67 |
== Changelog ==
|
68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
= 1.5.2 =
|
70 |
* Adding additional information about .htaccess hacks and the server environment.
|
71 |
|
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.5.5
|
7 |
+
Tested up to: 3.8
|
8 |
|
9 |
+
The Sucuri Security - SiteCheck Malware Scanner is a security plugin enables you to scan your WordPress site using Sucuri SiteCheck for security and malware issues, and also verifies the security integrity of your core files right in your dashboard. It also includes post-hack security ions to help you reset passwords and secret keys in case it has been already hacked, or infected with malware.
|
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 check for malware, blacklisting, and overall security status by scanning for free 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 |
|
66 |
|
67 |
== Changelog ==
|
68 |
|
69 |
+
= 1.5.5 =
|
70 |
+
* Added list of logged in users.
|
71 |
+
* Added system page.
|
72 |
+
* Change the integrity checking to use WP API.
|
73 |
+
|
74 |
+
= 1.5.4 = Bug fixes.
|
75 |
+
|
76 |
= 1.5.2 =
|
77 |
* Adding additional information about .htaccess hacks and the server environment.
|
78 |
|
sucuri.php
CHANGED
@@ -7,28 +7,78 @@ 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, INC
|
10 |
-
Version: 1.5.
|
11 |
Author URI: http://sucuri.net
|
12 |
*/
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
/* No direct access. */
|
15 |
if(!function_exists('add_action'))
|
16 |
{
|
17 |
exit(0);
|
18 |
}
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
@ignore_user_abort(TRUE);
|
24 |
-
|
25 |
define('SUCURISCAN','sucuriscan');
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
define('SUCURI_URL',plugin_dir_url( __FILE__ ));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
define('SUCURISCAN_PLUGIN_FOLDER', 'sucuri-scanner');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
define('SUCURISCAN_LASTLOGINS_USERSLIMIT', 100);
|
30 |
|
31 |
if( !function_exists('sucuriscan_create_uploaddir') ){
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
function sucuriscan_create_uploaddir(){
|
33 |
$plugin_upload_folder = sucuriscan_dir_filepath();
|
34 |
if( !file_exists($plugin_upload_folder) ){
|
@@ -45,8 +95,10 @@ if( !function_exists('sucuriscan_create_uploaddir') ){
|
|
45 |
add_action('admin_init', 'sucuriscan_create_uploaddir');
|
46 |
}
|
47 |
|
48 |
-
|
49 |
-
|
|
|
|
|
50 |
function sucuriscan_admin_script_style_registration() { ?>
|
51 |
<link rel="stylesheet" href="<?php echo SUCURI_URL; ?>/inc/css/sucuriscan-default-css.css" type="text/css" media="all" />
|
52 |
<script type="text/javascript">
|
@@ -56,10 +108,14 @@ function sucuriscan_admin_script_style_registration() { ?>
|
|
56 |
}
|
57 |
</script>
|
58 |
<?php }
|
|
|
59 |
|
60 |
-
|
61 |
-
* Returns the system filepath to the relevant user uploads
|
62 |
-
*
|
|
|
|
|
|
|
63 |
*/
|
64 |
function sucuriscan_dir_filepath($path = '')
|
65 |
{
|
@@ -68,11 +124,15 @@ function sucuriscan_dir_filepath($path = '')
|
|
68 |
return($wp_dir_array['basedir']."/sucuri/$path");
|
69 |
}
|
70 |
|
71 |
-
|
|
|
|
|
|
|
|
|
72 |
function sucuriscan_menu()
|
73 |
{
|
74 |
add_menu_page('Sucuri Free', 'Sucuri Free', 'manage_options',
|
75 |
-
'sucuriscan', 'sucuri_scan_page', SUCURI_URL.'images/menu-icon.png');
|
76 |
add_submenu_page('sucuriscan', 'Sucuri Scanner', 'Sucuri Scanner', 'manage_options',
|
77 |
'sucuriscan', 'sucuri_scan_page');
|
78 |
|
@@ -88,209 +148,22 @@ function sucuriscan_menu()
|
|
88 |
add_submenu_page('sucuriscan', 'Last Logins', 'Last Logins', 'manage_options',
|
89 |
'sucuriscan_lastlogins', 'sucuriscan_lastlogins_page');
|
90 |
|
91 |
-
add_submenu_page('sucuriscan', 'Info
|
92 |
'sucuriscan_infosys', 'sucuriscan_infosys_page');
|
93 |
-
}
|
94 |
-
|
95 |
-
/* Sucuri malware scan page. */
|
96 |
-
|
97 |
-
function sucuri_scan_page()
|
98 |
-
{
|
99 |
-
$U_ERROR = NULL;
|
100 |
-
if( !current_user_can('manage_options') ){
|
101 |
-
wp_die(__('You do not have sufficient permissions to access this page: Sucuri Malware Scanner') );
|
102 |
-
}
|
103 |
-
|
104 |
-
$template_variables = array(
|
105 |
-
'PluginURL'=>SUCURI_URL,
|
106 |
-
'Sidebar'=>sucuriscan_get_template('sidebar.html.tpl')
|
107 |
-
);
|
108 |
-
|
109 |
-
if( isset($_POST['wpsucuri-doscan']) ){
|
110 |
-
sucuriscan_print_scan();
|
111 |
-
return(1);
|
112 |
-
}
|
113 |
-
|
114 |
-
echo sucuriscan_get_template('initial-page.html.tpl', $template_variables);
|
115 |
-
}
|
116 |
-
|
117 |
-
function sucuriscan_print_scan()
|
118 |
-
{
|
119 |
-
$website_scanned = home_url();
|
120 |
-
$myresults = wp_remote_get('http://sitecheck.sucuri.net/scanner/?serialized&clear&fromwp&scan='.$website_scanned, array('timeout' => 180));
|
121 |
-
|
122 |
-
echo '<div class="wrap">';
|
123 |
-
echo '<h2 id="warnings_hook"></h2>';
|
124 |
-
echo '<div class="sucuriscan_header">';
|
125 |
-
echo '<a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">';
|
126 |
-
echo '<img src="'.SUCURI_URL.'/inc/images/logo.png" alt="Sucuri Security" />';
|
127 |
-
echo '</a>';
|
128 |
-
sucuriscan_pagestop("Sucuri SiteCheck Malware Scanner");
|
129 |
-
echo '</div>';
|
130 |
-
|
131 |
-
echo '<div class="postbox-container" style="width:75%;">';
|
132 |
-
echo '<div class="sucuriscan-maincontent">';
|
133 |
-
|
134 |
-
if(is_wp_error($myresults))
|
135 |
-
{
|
136 |
-
echo '<div id="poststuff">';
|
137 |
-
echo '<div class="postbox">';
|
138 |
-
echo '<h3>Error retrieving the scan report</h3>';
|
139 |
-
|
140 |
-
echo '<div class="inside">';
|
141 |
-
print_r($myresults);
|
142 |
-
echo '</div>';
|
143 |
-
echo '</div>';
|
144 |
-
echo '</div>';
|
145 |
-
}else if( preg_match('/^ERROR:/', $myresults['body']) ){
|
146 |
-
sucuriscan_admin_notice('error', $myresults['body'].' The URL scanned was: <code>'.$website_scanned.'</code>');
|
147 |
-
}else{
|
148 |
-
$res = unserialize($myresults['body']);
|
149 |
-
|
150 |
-
|
151 |
-
// Check for general warnings, and return the information for Infected/Clean site.
|
152 |
-
$malware_warns_exists = isset($res['MALWARE']['WARN']) ? TRUE : FALSE;
|
153 |
-
echo '<div id="poststuff">';
|
154 |
-
echo '<div class="postbox">';
|
155 |
-
echo '<h3>';
|
156 |
-
if( !$malware_warns_exists ){
|
157 |
-
echo '<img style="position:relative;top:5px" height="22" width="22" src="
|
158 |
-
'.site_url().'/wp-content/plugins/sucuri-scanner/images/ok.png" />
|
159 |
-
No malware was identified';
|
160 |
-
}else{
|
161 |
-
echo '<img style="position:relative;top:5px" height="22" width="22" src="
|
162 |
-
'.site_url().'/wp-content/plugins/sucuri-scanner/images/warn.png" />
|
163 |
-
Site compromised (malware was identified)';
|
164 |
-
}
|
165 |
-
echo '</h3>';
|
166 |
-
echo '<div class="inside">';
|
167 |
-
if( !$malware_warns_exists ){
|
168 |
-
echo "<span><strong>Malware:</strong> No.</span><br>";
|
169 |
-
echo "<span><strong>Malicious javascript:</strong> No.</span><br>";
|
170 |
-
echo "<span><strong>Malicious iframes:</strong> No.</span><br>";
|
171 |
-
echo "<span><strong>Suspicious redirections (htaccess):</strong> No.</span><br>";
|
172 |
-
echo "<span><strong>Blackhat SEO Spam:</strong> No.</span><br>";
|
173 |
-
echo "<span><strong>Anomaly detection:</strong> Clean.</span><br>";
|
174 |
-
}else{
|
175 |
-
foreach($res['MALWARE']['WARN'] as $malres)
|
176 |
-
{
|
177 |
-
if(!is_array($malres))
|
178 |
-
{
|
179 |
-
echo htmlspecialchars($malres);
|
180 |
-
}
|
181 |
-
else
|
182 |
-
{
|
183 |
-
$mwdetails = explode("\n", htmlspecialchars($malres[1]));
|
184 |
-
echo htmlspecialchars($malres[0])."\n<br />". substr($mwdetails[0], 1)."<br />\n";
|
185 |
-
}
|
186 |
-
}
|
187 |
-
}
|
188 |
-
echo "<br />";
|
189 |
-
echo '<i>More details here: <a href="http://sitecheck.sucuri.net/scanner/?scan='.$website_scanned.'">http://sitecheck.sucuri.net/scanner/?scan='.$website_scanned.'</a></i>';
|
190 |
-
echo "<hr />\n";
|
191 |
-
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>';
|
192 |
-
echo "<hr />\n";
|
193 |
-
echo '</div>';
|
194 |
-
echo '</div>';
|
195 |
-
echo '</div>';
|
196 |
-
|
197 |
-
|
198 |
-
// Check for blacklist reports, and return the information retrieved from multiple blacklist services.
|
199 |
-
echo '<div id="poststuff">';
|
200 |
-
echo '<div class="postbox">';
|
201 |
-
echo '<h3>';
|
202 |
-
if(isset($res['BLACKLIST']['WARN']))
|
203 |
-
{
|
204 |
-
echo '<img style="position:relative;top:5px" height="22" width="22" src="
|
205 |
-
'.site_url().'/wp-content/plugins/sucuri-scanner/images/warn.png" />
|
206 |
-
Site blacklisted';
|
207 |
-
}
|
208 |
-
else
|
209 |
-
{
|
210 |
-
echo '<img style="position:relative;top:5px" height="22" width="22" src="
|
211 |
-
'.site_url().'/wp-content/plugins/sucuri-scanner/images/ok.png" />
|
212 |
-
Site blacklist-free';
|
213 |
-
}
|
214 |
-
echo '</h3>';
|
215 |
-
echo '<div class="inside">';
|
216 |
-
foreach(array(
|
217 |
-
'INFO'=>'CLEAN',
|
218 |
-
'WARN'=>'WARNING'
|
219 |
-
) as $type=>$group_title){
|
220 |
-
if( isset($res['BLACKLIST'][$type]) ){
|
221 |
-
foreach($res['BLACKLIST'][$type] as $blres){
|
222 |
-
$report_site = htmlspecialchars($blres[0]);
|
223 |
-
$report_url = htmlspecialchars($blres[1]);
|
224 |
-
echo "<b>{$group_title}: </b>{$report_site} <a href='{$report_url}' target='_blank'>{$report_url}</a><br />";
|
225 |
-
}
|
226 |
-
}
|
227 |
-
}
|
228 |
-
echo '</div>';
|
229 |
-
echo '</div>';
|
230 |
-
echo '</div>';
|
231 |
-
|
232 |
-
|
233 |
-
// Check for general versions in some common services/software used to serve this website.
|
234 |
-
global $wp_version;
|
235 |
-
$wordpress_updated = FALSE;
|
236 |
-
$updates = function_exists('get_core_updates') ? get_core_updates() : array();
|
237 |
-
if( !is_array($updates) || empty($updates) || $updates[0]->response=='latest' ){
|
238 |
-
$wordpress_updated = TRUE;
|
239 |
-
}
|
240 |
-
|
241 |
-
echo '<div id="poststuff">';
|
242 |
-
echo '<div class="postbox">';
|
243 |
-
echo '<h3>';
|
244 |
-
if($wordpress_updated)
|
245 |
-
{
|
246 |
-
echo '<img style="position:relative;top:5px" height="22" width="22" src="
|
247 |
-
'.site_url().'/wp-content/plugins/sucuri-scanner/images/ok.png" />
|
248 |
-
System info (WordPress upgraded)';
|
249 |
-
}
|
250 |
-
else
|
251 |
-
{
|
252 |
-
echo '<img style="position:relative;top:5px" height="22" width="22" src="
|
253 |
-
'.site_url().'/wp-content/plugins/sucuri-scanner/images/warn.png" />
|
254 |
-
System info (WordPress outdated)';
|
255 |
-
}
|
256 |
-
echo '</h3>';
|
257 |
-
echo '<div class="inside">';
|
258 |
-
echo "<b>Site:</b> ".$res['SCAN']['SITE'][0]." (".$res['SCAN']['IP'][0].")<br />\n";
|
259 |
-
echo "<b>WordPress: </b> $wp_version<br />\n";
|
260 |
-
echo "<b>PHP: </b> ".phpversion()."<br />\n";
|
261 |
-
if(isset($res['SYSTEM']['NOTICE']))
|
262 |
-
{
|
263 |
-
foreach($res['SYSTEM']['NOTICE'] as $notres)
|
264 |
-
{
|
265 |
-
if(is_array($notres))
|
266 |
-
{
|
267 |
-
echo htmlspecialchars($notres[0]). " ".htmlspecialchars($notres[1]);
|
268 |
-
}
|
269 |
-
else
|
270 |
-
{
|
271 |
-
echo htmlspecialchars($notres)."<br />\n";
|
272 |
-
}
|
273 |
-
}
|
274 |
-
}
|
275 |
-
echo '</div>';
|
276 |
-
echo '</div>';
|
277 |
-
echo '</div>';
|
278 |
-
}
|
279 |
-
?>
|
280 |
-
|
281 |
-
<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>
|
282 |
-
</div><!-- End sucuriscan-maincontent -->
|
283 |
-
</div><!-- End postbox-container -->
|
284 |
-
|
285 |
-
<?php echo sucuriscan_get_template('sidebar.html.tpl') ?>
|
286 |
|
287 |
-
|
288 |
-
|
289 |
-
<?php
|
290 |
}
|
291 |
|
292 |
-
|
|
|
293 |
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
function sucuriscan_pagestop($sucuri_title = 'Sucuri Plugin')
|
295 |
{
|
296 |
if(!current_user_can('manage_options'))
|
@@ -303,87 +176,16 @@ function sucuriscan_pagestop($sucuri_title = 'Sucuri Plugin')
|
|
303 |
<?php
|
304 |
}
|
305 |
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
echo '<div class="sucuriscan_header">';
|
317 |
-
echo '<a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">';
|
318 |
-
echo '<img src="'.SUCURI_URL.'/inc/images/logo.png" alt="Sucuri Security" />';
|
319 |
-
echo '</a>';
|
320 |
-
sucuriscan_pagestop("Sucuri 1-Click Hardening Options");
|
321 |
-
echo '</div>';
|
322 |
-
|
323 |
-
if(!current_user_can('manage_options'))
|
324 |
-
{
|
325 |
-
wp_die(__('You do not have sufficient permissions to access this page: Sucuri Hardening') );
|
326 |
-
}
|
327 |
-
|
328 |
-
include_once("sucuriscan_hardening.php");
|
329 |
-
|
330 |
-
sucuriscan_hardening_lib()
|
331 |
-
|
332 |
-
?>
|
333 |
-
|
334 |
-
</div><!-- End sucuriscan-maincontent -->
|
335 |
-
</div><!-- End postbox-container -->
|
336 |
-
|
337 |
-
<?php echo sucuriscan_get_template('sidebar.html.tpl') ?>
|
338 |
-
|
339 |
-
</div><!-- End Wrap -->
|
340 |
-
|
341 |
-
<?php
|
342 |
-
}
|
343 |
-
|
344 |
-
/* Sucuri WordPress Integrity page. */
|
345 |
-
|
346 |
-
function sucuriscan_core_integrity_page()
|
347 |
-
|
348 |
-
{
|
349 |
-
|
350 |
-
/* WordPress Integrity page. */
|
351 |
-
|
352 |
-
echo '<div class="wrap">';
|
353 |
-
echo '<h2 id="warnings_hook"></h2>';
|
354 |
-
echo '<div class="sucuriscan_header">';
|
355 |
-
echo '<a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">';
|
356 |
-
echo '<img src="'.SUCURI_URL.'/inc/images/logo.png" alt="Sucuri Security" />';
|
357 |
-
echo '</a>';
|
358 |
-
sucuriscan_pagestop("Sucuri WordPress Integrity");
|
359 |
-
echo '</div>';
|
360 |
-
|
361 |
-
if(!current_user_can('manage_options'))
|
362 |
-
{
|
363 |
-
wp_die(__('You do not have sufficient permissions to access this page: Sucuri Integrity Check') );
|
364 |
-
}
|
365 |
-
|
366 |
-
include_once("sucuriscan_core_integrity.php");
|
367 |
-
|
368 |
-
sucuriscan_core_integrity_lib()
|
369 |
-
|
370 |
-
?>
|
371 |
-
|
372 |
-
</div><!-- End sucuriscan-maincontent -->
|
373 |
-
</div><!-- End postbox-container -->
|
374 |
-
|
375 |
-
<?php echo sucuriscan_get_template('sidebar.html.tpl') ?>
|
376 |
-
|
377 |
-
</div><!-- End Wrap -->
|
378 |
-
|
379 |
-
<?php
|
380 |
-
}
|
381 |
-
|
382 |
-
/* Sucuri's admin menu. */
|
383 |
-
|
384 |
-
add_action('admin_menu', 'sucuriscan_menu');
|
385 |
-
remove_action('wp_head', 'wp_generator');
|
386 |
-
|
387 |
function sucuriscan_send_mail($to='', $subject='', $message='', $data_set=array(), $debug=FALSE)
|
388 |
{
|
389 |
$headers = array();
|
@@ -402,6 +204,13 @@ function sucuriscan_send_mail($to='', $subject='', $message='', $data_set=array(
|
|
402 |
}
|
403 |
}
|
404 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
405 |
function sucuriscan_admin_notice($type='updated', $message='')
|
406 |
{
|
407 |
$alert_id = rand(100, 999);
|
@@ -413,6 +222,14 @@ function sucuriscan_admin_notice($type='updated', $message='')
|
|
413 |
<?php endif;
|
414 |
}
|
415 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
416 |
function sucuriscan_prettify_mail($subject='', $message='', $data_set=array())
|
417 |
{
|
418 |
$current_user = wp_get_current_user();
|
@@ -433,109 +250,1479 @@ function sucuriscan_prettify_mail($subject='', $message='', $data_set=array())
|
|
433 |
$mail_variables[$var_key] = $var_value;
|
434 |
}
|
435 |
|
436 |
-
return sucuriscan_get_template("notification.{$prettify_type}.tpl", $mail_variables);
|
437 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
438 |
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
447 |
}
|
448 |
}
|
449 |
-
return $template_content;
|
450 |
-
}
|
451 |
|
452 |
-
|
453 |
-
|
454 |
-
|
|
|
|
|
|
|
|
|
455 |
}
|
456 |
|
457 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
458 |
{
|
459 |
-
$
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
465 |
}
|
466 |
-
return $new_keys;
|
467 |
}
|
468 |
}
|
469 |
-
return FALSE;
|
470 |
-
}
|
471 |
-
|
472 |
-
function sucuriscan_set_new_config_keys()
|
473 |
-
{
|
474 |
-
$new_wpconfig = '';
|
475 |
-
$wp_config_path = ABSPATH.'wp-config.php';
|
476 |
-
if( file_exists($wp_config_path) ){
|
477 |
-
$wp_config_lines = file($wp_config_path);
|
478 |
-
$new_keys = sucuriscan_get_new_config_keys();
|
479 |
-
$old_keys = array();
|
480 |
-
$old_keys_string = $new_keys_string = '';
|
481 |
|
482 |
-
|
483 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
484 |
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
$white_spaces = $match[2];
|
489 |
-
$old_keys[$key_name] = $match[3];
|
490 |
-
$wp_config_line = "define('{$key_name}',{$white_spaces}'{$new_keys[$key_name]}');";
|
491 |
|
492 |
-
|
493 |
-
|
|
|
|
|
|
|
|
|
|
|
494 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
495 |
}
|
496 |
-
|
497 |
-
$new_wpconfig .= "{$wp_config_line}\n";
|
498 |
-
}
|
499 |
-
|
500 |
-
$response = array(
|
501 |
-
'updated'=>is_writable($wp_config_path),
|
502 |
-
'old_keys'=>$old_keys,
|
503 |
-
'old_keys_string'=>$old_keys_string,
|
504 |
-
'new_keys'=>$new_keys,
|
505 |
-
'new_keys_string'=>$new_keys_string,
|
506 |
-
'new_wpconfig'=>$new_wpconfig
|
507 |
-
);
|
508 |
-
if( $response['updated'] ){
|
509 |
-
file_put_contents($wp_config_path, $new_wpconfig, LOCK_EX);
|
510 |
}
|
511 |
-
return $response;
|
512 |
}
|
513 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
514 |
}
|
515 |
|
516 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
517 |
{
|
518 |
-
$
|
519 |
-
$current_user = wp_get_current_user();
|
520 |
-
|
521 |
-
if( $user_id>0 && $user_id!=$current_user->ID ){
|
522 |
-
$user = get_userdata($user_id);
|
523 |
-
$new_password = wp_generate_password(15, TRUE, FALSE);
|
524 |
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
|
|
|
|
531 |
|
532 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
533 |
|
534 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
535 |
}
|
536 |
-
|
537 |
}
|
538 |
|
|
|
|
|
|
|
|
|
|
|
539 |
function sucuriscan_posthack_page()
|
540 |
{
|
541 |
if( !current_user_can('manage_options') )
|
@@ -637,49 +1824,13 @@ function sucuriscan_posthack_page()
|
|
637 |
echo sucuriscan_get_template('posthack.html.tpl', $template_variables);
|
638 |
}
|
639 |
|
640 |
-
function sucuriscan_get_remoteaddr()
|
641 |
-
{
|
642 |
-
$alternatives = array(
|
643 |
-
'HTTP_X_REAL_IP',
|
644 |
-
'HTTP_CLIENT_IP',
|
645 |
-
'HTTP_X_FORWARDED_FOR',
|
646 |
-
'HTTP_X_FORWARDED',
|
647 |
-
'HTTP_FORWARDED_FOR',
|
648 |
-
'HTTP_FORWARDED',
|
649 |
-
'REMOTE_ADDR',
|
650 |
-
'SUCURI_RIP',
|
651 |
-
);
|
652 |
-
foreach($alternatives as $alternative){
|
653 |
-
if( !isset($_SERVER[$alternative]) ){ continue; }
|
654 |
-
|
655 |
-
$remote_addr = preg_replace('/[^0-9., ]/', '', $_SERVER[$alternative]);
|
656 |
-
if($remote_addr) break;
|
657 |
-
}
|
658 |
-
|
659 |
-
return $remote_addr;
|
660 |
-
}
|
661 |
-
|
662 |
-
function sucuriscan_is_behind_cloudproxy(){
|
663 |
-
$http_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '127.0.0.1';
|
664 |
-
if( preg_match('/^(.*):.*/', $http_host, $match) ){ $http_host = $match[1]; }
|
665 |
-
$host = gethostbyaddr(gethostbyname($http_host));
|
666 |
-
|
667 |
-
if(
|
668 |
-
isset($_SERVER['SUCURIREAL_REMOTE_ADDR'])
|
669 |
-
|| preg_match('/cloudproxy.*\.sucuri\.net/', $host)
|
670 |
-
){
|
671 |
-
return TRUE;
|
672 |
-
}
|
673 |
-
|
674 |
-
return FALSE;
|
675 |
-
}
|
676 |
-
|
677 |
-
|
678 |
/**
|
679 |
-
*
|
680 |
-
*
|
|
|
|
|
|
|
681 |
*/
|
682 |
-
|
683 |
function sucuriscan_lastlogins_page()
|
684 |
{
|
685 |
if( !current_user_can('manage_options') )
|
@@ -720,12 +1871,23 @@ function sucuriscan_lastlogins_page()
|
|
720 |
echo sucuriscan_get_template('lastlogins.html.tpl', $template_variables);
|
721 |
}
|
722 |
|
|
|
|
|
|
|
|
|
|
|
723 |
function sucuriscan_lastlogins_datastore_filepath(){
|
724 |
$plugin_upload_folder = sucuriscan_dir_filepath();
|
725 |
$datastore_filepath = rtrim($plugin_upload_folder,'/').'/sucuri-lastlogins.php';
|
726 |
return $datastore_filepath;
|
727 |
}
|
728 |
|
|
|
|
|
|
|
|
|
|
|
|
|
729 |
function sucuriscan_lastlogins_datastore_exists(){
|
730 |
$datastore_filepath = sucuriscan_lastlogins_datastore_filepath();
|
731 |
|
@@ -738,6 +1900,12 @@ function sucuriscan_lastlogins_datastore_exists(){
|
|
738 |
return file_exists($datastore_filepath) ? $datastore_filepath : FALSE;
|
739 |
}
|
740 |
|
|
|
|
|
|
|
|
|
|
|
|
|
741 |
function sucuriscan_lastlogins_datastore_is_writable(){
|
742 |
$datastore_filepath = sucuriscan_lastlogins_datastore_exists();
|
743 |
if($datastore_filepath){
|
@@ -749,6 +1917,12 @@ function sucuriscan_lastlogins_datastore_is_writable(){
|
|
749 |
return FALSE;
|
750 |
}
|
751 |
|
|
|
|
|
|
|
|
|
|
|
|
|
752 |
function sucuriscan_lastlogins_datastore_is_readable(){
|
753 |
$datastore_filepath = sucuriscan_lastlogins_datastore_exists();
|
754 |
if( $datastore_filepath && is_readable($datastore_filepath) ){
|
@@ -758,6 +1932,12 @@ function sucuriscan_lastlogins_datastore_is_readable(){
|
|
758 |
}
|
759 |
|
760 |
if( !function_exists('sucuri_set_lastlogin') ){
|
|
|
|
|
|
|
|
|
|
|
|
|
761 |
function sucuriscan_set_lastlogin($user_login=''){
|
762 |
$datastore_filepath = sucuriscan_lastlogins_datastore_is_writable();
|
763 |
|
@@ -779,6 +1959,16 @@ if( !function_exists('sucuri_set_lastlogin') ){
|
|
779 |
add_action('wp_login', 'sucuriscan_set_lastlogin', 50);
|
780 |
}
|
781 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
782 |
function sucuriscan_get_logins($limit=10, $user_id=0){
|
783 |
$lastlogins = array();
|
784 |
$datastore_filepath = sucuriscan_lastlogins_datastore_is_readable();
|
@@ -821,6 +2011,15 @@ function sucuriscan_get_logins($limit=10, $user_id=0){
|
|
821 |
}
|
822 |
|
823 |
if( !function_exists('sucuri_login_redirect') ){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
824 |
function sucuriscan_login_redirect($redirect_to='', $request=NULL, $user=FALSE){
|
825 |
$login_url = !empty($redirect_to) ? $redirect_to : admin_url();
|
826 |
if( $user instanceof WP_User && $user->ID ){
|
@@ -832,6 +2031,11 @@ if( !function_exists('sucuri_login_redirect') ){
|
|
832 |
}
|
833 |
|
834 |
if( !function_exists('sucuri_get_user_lastlogin') ){
|
|
|
|
|
|
|
|
|
|
|
835 |
function sucuriscan_get_user_lastlogin(){
|
836 |
if( isset($_GET['sucuriscan_lastlogin_message']) && current_user_can('manage_options') ){
|
837 |
$current_user = wp_get_current_user();
|
@@ -851,38 +2055,15 @@ if( !function_exists('sucuri_get_user_lastlogin') ){
|
|
851 |
add_action('admin_notices', 'sucuriscan_get_user_lastlogin');
|
852 |
}
|
853 |
|
854 |
-
|
855 |
/**
|
856 |
-
*
|
857 |
-
*
|
|
|
|
|
|
|
|
|
|
|
858 |
*/
|
859 |
-
|
860 |
-
function sucuriscan_is_multisite(){
|
861 |
-
if( function_exists('is_multisite') && is_multisite() ){ return TRUE; }
|
862 |
-
return FALSE;
|
863 |
-
}
|
864 |
-
|
865 |
-
|
866 |
-
function sucuriscan_get_wpconfig_path(){
|
867 |
-
$wp_config_path = ABSPATH.'wp-config.php';
|
868 |
-
|
869 |
-
// if wp-config.php doesn't exist/not readable check one directory up
|
870 |
-
if( !is_readable($wp_config_path)){
|
871 |
-
$wp_config_path = ABSPATH.'/../wp-config.php';
|
872 |
-
}
|
873 |
-
return $wp_config_path;
|
874 |
-
}
|
875 |
-
|
876 |
-
|
877 |
-
function sucuriscan_get_htaccess_path(){
|
878 |
-
$htaccess_path = ABSPATH.'.htaccess';
|
879 |
-
if( file_exists($htaccess_path) ){
|
880 |
-
return $htaccess_path;
|
881 |
-
}
|
882 |
-
return FALSE;
|
883 |
-
}
|
884 |
-
|
885 |
-
|
886 |
function sucuriscan_infosys_page(){
|
887 |
if( !current_user_can('manage_options') )
|
888 |
{
|
@@ -897,15 +2078,22 @@ function sucuriscan_infosys_page(){
|
|
897 |
);
|
898 |
|
899 |
$template_variables['LoggedInUsers'] = sucuriscan_infosys_loggedin();
|
|
|
900 |
$template_variables['HTAccessIntegrity'] = sucuriscan_infosys_htaccess();
|
901 |
$template_variables['WordpressConfig'] = sucuriscan_infosys_wpconfig();
|
902 |
|
903 |
echo sucuriscan_get_template('infosys.html.tpl', $template_variables);
|
904 |
}
|
905 |
|
906 |
-
|
|
|
|
|
|
|
|
|
|
|
907 |
function sucuriscan_infosys_htaccess(){
|
908 |
$htaccess_path = sucuriscan_get_htaccess_path();
|
|
|
909 |
$template_variables = array(
|
910 |
'HTAccess.Content' => '',
|
911 |
'HTAccess.Message' => '',
|
@@ -916,18 +2104,23 @@ function sucuriscan_infosys_htaccess(){
|
|
916 |
|
917 |
if( $htaccess_path ){
|
918 |
$htaccess_rules = file_get_contents($htaccess_path);
|
|
|
|
|
|
|
919 |
$template_variables['HTAccess.TextareaVisible'] = 'visible';
|
920 |
$template_variables['HTAccess.Content'] = $htaccess_rules;
|
|
|
921 |
|
|
|
|
|
|
|
|
|
922 |
if( sucuriscan_htaccess_is_standard($htaccess_rules) ){
|
923 |
-
$template_variables['HTAccess.Message']
|
924 |
The main <code>.htaccess</code> file in your site has the standard rules for a WordPress installation. You can customize it to improve the
|
925 |
performance and change the behaviour of the redirections for pages and posts in your site. To get more information visit the official documentation at
|
926 |
<a href="http://codex.wordpress.org/Using_Permalinks#Creating_and_editing_.28.htaccess.29" target="_blank">Codex WordPrexx - Creating and editing (.htaccess)</a>';
|
927 |
-
$template_variables['HTAccess.MessageType'] = 'updated';
|
928 |
-
$template_variables['HTAccess.MessageVisible'] = 'visible';
|
929 |
}
|
930 |
-
|
931 |
}else{
|
932 |
$template_variables['HTAccess.Message'] = 'Your website does not contains a <code>.htaccess</code> file or it was not found in the default location.';
|
933 |
$template_variables['HTAccess.MessageType'] = 'error';
|
@@ -937,7 +2130,13 @@ function sucuriscan_infosys_htaccess(){
|
|
937 |
return sucuriscan_get_template('infosys-htaccess.html.tpl', $template_variables);
|
938 |
}
|
939 |
|
940 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
941 |
function sucuriscan_htaccess_is_standard($rules=FALSE){
|
942 |
if( $rules===FALSE ){
|
943 |
$htaccess_path = sucuriscan_get_htaccess_path();
|
@@ -976,13 +2175,20 @@ function sucuriscan_htaccess_is_standard($rules=FALSE){
|
|
976 |
return FALSE;
|
977 |
}
|
978 |
|
979 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
980 |
function sucuriscan_infosys_wpconfig(){
|
981 |
$template_variables = array(
|
982 |
'WordpressConfig.Rules' => '',
|
983 |
'WordpressConfig.Total' => 0,
|
984 |
'WordpressConfig.Content' => '',
|
985 |
);
|
|
|
986 |
|
987 |
$wp_config_path = sucuriscan_get_wpconfig_path();
|
988 |
if( $wp_config_path ){
|
@@ -998,7 +2204,7 @@ function sucuriscan_infosys_wpconfig(){
|
|
998 |
// Ignore useless lines and append to the clean string the important lines.
|
999 |
if( preg_match('/^define\(/', $line) ){
|
1000 |
$line = str_replace('define(', '', $line);
|
1001 |
-
$line =
|
1002 |
$line_parts = explode(',', $line, 2);
|
1003 |
}
|
1004 |
else if( preg_match('/^\$[a-zA-Z_]+/', $line) ){
|
@@ -1024,7 +2230,10 @@ function sucuriscan_infosys_wpconfig(){
|
|
1024 |
if( $i==0 ){ $key_name = $line_part; }
|
1025 |
if( $i==1 ){ $key_value = $line_part; }
|
1026 |
}
|
1027 |
-
|
|
|
|
|
|
|
1028 |
}
|
1029 |
}
|
1030 |
|
@@ -1041,7 +2250,11 @@ function sucuriscan_infosys_wpconfig(){
|
|
1041 |
return sucuriscan_get_template('infosys-wpconfig.html.tpl', $template_variables);
|
1042 |
}
|
1043 |
|
1044 |
-
|
|
|
|
|
|
|
|
|
1045 |
function sucuriscan_infosys_loggedin(){
|
1046 |
// Get user logged in list.
|
1047 |
$template_variables = array(
|
@@ -1049,7 +2262,7 @@ function sucuriscan_infosys_loggedin(){
|
|
1049 |
'LoggedInUsers.Total' => 0,
|
1050 |
);
|
1051 |
|
1052 |
-
$logged_in_users = sucuriscan_get_online_users();
|
1053 |
if( is_array($logged_in_users) && !empty($logged_in_users) ){
|
1054 |
$template_variables['LoggedInUsers.Total'] = count($logged_in_users);
|
1055 |
|
@@ -1072,16 +2285,41 @@ function sucuriscan_infosys_loggedin(){
|
|
1072 |
return sucuriscan_get_template('infosys-loggedin.html.tpl', $template_variables);
|
1073 |
}
|
1074 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1075 |
|
1076 |
-
function sucuriscan_get_online_users(){
|
1077 |
if( sucuriscan_is_multisite() ){
|
1078 |
-
|
1079 |
}else{
|
1080 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1081 |
}
|
1082 |
-
}
|
1083 |
|
|
|
|
|
1084 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1085 |
function sucuriscan_save_online_users($logged_in_users=array()){
|
1086 |
$expiration = 30 * 60;
|
1087 |
if( sucuriscan_is_multisite() ){
|
@@ -1091,8 +2329,13 @@ function sucuriscan_save_online_users($logged_in_users=array()){
|
|
1091 |
}
|
1092 |
}
|
1093 |
|
1094 |
-
|
1095 |
if( !function_exists('sucuriscan_unset_online_user_on_logout') ){
|
|
|
|
|
|
|
|
|
|
|
|
|
1096 |
function sucuriscan_unset_online_user_on_logout(){
|
1097 |
$current_user = wp_get_current_user();
|
1098 |
$user_id = $current_user->ID;
|
@@ -1104,6 +2347,14 @@ if( !function_exists('sucuriscan_unset_online_user_on_logout') ){
|
|
1104 |
add_action('wp_logout', 'sucuriscan_unset_online_user_on_logout');
|
1105 |
}
|
1106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1107 |
function sucuriscan_unset_online_user($user_id=0, $remote_addr=0){
|
1108 |
$logged_in_users = sucuriscan_get_online_users();
|
1109 |
|
@@ -1123,8 +2374,14 @@ function sucuriscan_unset_online_user($user_id=0, $remote_addr=0){
|
|
1123 |
return sucuriscan_save_online_users($logged_in_users);
|
1124 |
}
|
1125 |
|
1126 |
-
|
1127 |
if( !function_exists('sucuriscan_set_online_user') ){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1128 |
function sucuriscan_set_online_user($user_login='', $user=FALSE){
|
1129 |
if( $user ){
|
1130 |
// Get logged in user information.
|
@@ -1185,3 +2442,115 @@ if( !function_exists('sucuriscan_set_online_user') ){
|
|
1185 |
add_action('wp_login', 'sucuriscan_set_online_user', 10, 2);
|
1186 |
}
|
1187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
You can also scan your site at <a href="http://sitecheck.sucuri.net">SiteCheck.Sucuri.net</a>.
|
8 |
|
9 |
Author: Sucuri, INC
|
10 |
+
Version: 1.5.5
|
11 |
Author URI: http://sucuri.net
|
12 |
*/
|
13 |
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Main file to control the plugin.
|
17 |
+
*
|
18 |
+
* @category Bootstrap
|
19 |
+
* @package Sucuri Security - SiteCheck Malware Scanner
|
20 |
+
* @author Daniel <dcid@sucuri.net>
|
21 |
+
* @copyright Since 2010 Sucuri Inc.
|
22 |
+
* @license Released under the GPL - see LICENSE file for details.
|
23 |
+
* @version HG: $Id$
|
24 |
+
* @link https://wordpress.sucuri.net/
|
25 |
+
* @since File available since Release 0.1
|
26 |
+
*/
|
27 |
+
|
28 |
+
|
29 |
/* No direct access. */
|
30 |
if(!function_exists('add_action'))
|
31 |
{
|
32 |
exit(0);
|
33 |
}
|
34 |
|
35 |
+
/**
|
36 |
+
* Unique name of the plugin through out all the code.
|
37 |
+
*/
|
|
|
|
|
38 |
define('SUCURISCAN','sucuriscan');
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Current version of the plugin's code.
|
42 |
+
*/
|
43 |
+
define('SUCURISCAN_VERSION','1.5.5');
|
44 |
+
|
45 |
+
/**
|
46 |
+
* The local URL where the plugin's files and assets are served.
|
47 |
+
*/
|
48 |
define('SUCURI_URL',plugin_dir_url( __FILE__ ));
|
49 |
+
|
50 |
+
/**
|
51 |
+
* The name of the Sucuri plugin main file.
|
52 |
+
*/
|
53 |
+
define('SUCURISCAN_PLUGIN_FILE', 'sucuri.php');
|
54 |
+
|
55 |
+
/**
|
56 |
+
* The name of the folder where the plugin's files will be located.
|
57 |
+
*/
|
58 |
define('SUCURISCAN_PLUGIN_FOLDER', 'sucuri-scanner');
|
59 |
+
|
60 |
+
/**
|
61 |
+
* The fullpath where the plugin's files will be located.
|
62 |
+
*/
|
63 |
+
define('SUCURISCAN_PLUGIN_PATH', WP_PLUGIN_DIR.'/'.SUCURISCAN_PLUGIN_FOLDER);
|
64 |
+
|
65 |
+
/**
|
66 |
+
* The fullpath of the main plugin file.
|
67 |
+
*/
|
68 |
+
define('SUCURISCAN_PLUGIN_FILEPATH', SUCURISCAN_PLUGIN_PATH.'/'.SUCURISCAN_PLUGIN_FILE);
|
69 |
+
|
70 |
+
/**
|
71 |
+
* The maximum quantity of entries that will be displayed in the last login page.
|
72 |
+
*/
|
73 |
define('SUCURISCAN_LASTLOGINS_USERSLIMIT', 100);
|
74 |
|
75 |
if( !function_exists('sucuriscan_create_uploaddir') ){
|
76 |
+
/**
|
77 |
+
* Create a folder in the Wordpress upload directory where the plugin will
|
78 |
+
* store all the temporal or dynamic information.
|
79 |
+
*
|
80 |
+
* @return void
|
81 |
+
*/
|
82 |
function sucuriscan_create_uploaddir(){
|
83 |
$plugin_upload_folder = sucuriscan_dir_filepath();
|
84 |
if( !file_exists($plugin_upload_folder) ){
|
95 |
add_action('admin_init', 'sucuriscan_create_uploaddir');
|
96 |
}
|
97 |
|
98 |
+
/**
|
99 |
+
* Define which javascript and css files will be loaded in the header of the page.
|
100 |
+
* @return void
|
101 |
+
*/
|
102 |
function sucuriscan_admin_script_style_registration() { ?>
|
103 |
<link rel="stylesheet" href="<?php echo SUCURI_URL; ?>/inc/css/sucuriscan-default-css.css" type="text/css" media="all" />
|
104 |
<script type="text/javascript">
|
108 |
}
|
109 |
</script>
|
110 |
<?php }
|
111 |
+
add_action( 'admin_enqueue_scripts', 'sucuriscan_admin_script_style_registration', 1 );
|
112 |
|
113 |
+
/**
|
114 |
+
* Returns the system filepath to the relevant user uploads directory for this
|
115 |
+
* site. This is a multisite capable function.
|
116 |
+
*
|
117 |
+
* @param string $path The relative path that needs to be completed to get the absolute path.
|
118 |
+
* @return string The full filesystem path including the directory specified.
|
119 |
*/
|
120 |
function sucuriscan_dir_filepath($path = '')
|
121 |
{
|
124 |
return($wp_dir_array['basedir']."/sucuri/$path");
|
125 |
}
|
126 |
|
127 |
+
/**
|
128 |
+
* Generate the menu and submenus for the plugin in the admin interface.
|
129 |
+
*
|
130 |
+
* @return void
|
131 |
+
*/
|
132 |
function sucuriscan_menu()
|
133 |
{
|
134 |
add_menu_page('Sucuri Free', 'Sucuri Free', 'manage_options',
|
135 |
+
'sucuriscan', 'sucuri_scan_page', SUCURI_URL.'inc/images/menu-icon.png');
|
136 |
add_submenu_page('sucuriscan', 'Sucuri Scanner', 'Sucuri Scanner', 'manage_options',
|
137 |
'sucuriscan', 'sucuri_scan_page');
|
138 |
|
148 |
add_submenu_page('sucuriscan', 'Last Logins', 'Last Logins', 'manage_options',
|
149 |
'sucuriscan_lastlogins', 'sucuriscan_lastlogins_page');
|
150 |
|
151 |
+
add_submenu_page('sucuriscan', 'Site Info', 'Site Info', 'manage_options',
|
152 |
'sucuriscan_infosys', 'sucuriscan_infosys_page');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
|
154 |
+
add_submenu_page('sucuriscan', 'About', 'About', 'manage_options',
|
155 |
+
'sucuriscan_about', 'sucuriscan_about_page');
|
|
|
156 |
}
|
157 |
|
158 |
+
add_action('admin_menu', 'sucuriscan_menu');
|
159 |
+
remove_action('wp_head', 'wp_generator');
|
160 |
|
161 |
+
/**
|
162 |
+
* Print the HTML code for the header of each plugin's page.
|
163 |
+
*
|
164 |
+
* @param string $sucuri_title Title of the page that will be loaded.
|
165 |
+
* @return void
|
166 |
+
*/
|
167 |
function sucuriscan_pagestop($sucuri_title = 'Sucuri Plugin')
|
168 |
{
|
169 |
if(!current_user_can('manage_options'))
|
176 |
<?php
|
177 |
}
|
178 |
|
179 |
+
/**
|
180 |
+
* Send a message to a specific email address.
|
181 |
+
*
|
182 |
+
* @param string $to The email address of the recipient that will receive the message.
|
183 |
+
* @param string $subject The reason of the message that will be sent.
|
184 |
+
* @param string $message Body of the message that will be sent.
|
185 |
+
* @param array $data_set Optional parameter to add more information to the notification.
|
186 |
+
* @param boolean $debug TRUE if you want to test the function printing the email before sending it.
|
187 |
+
* @return void
|
188 |
+
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
function sucuriscan_send_mail($to='', $subject='', $message='', $data_set=array(), $debug=FALSE)
|
190 |
{
|
191 |
$headers = array();
|
204 |
}
|
205 |
}
|
206 |
|
207 |
+
/**
|
208 |
+
* Prints a HTML alert in the Wordpress admin interface.
|
209 |
+
*
|
210 |
+
* @param string $type The type of alert, it can be either Updated or Error.
|
211 |
+
* @param string $message The message that will be printed in the alert.
|
212 |
+
* @return void
|
213 |
+
*/
|
214 |
function sucuriscan_admin_notice($type='updated', $message='')
|
215 |
{
|
216 |
$alert_id = rand(100, 999);
|
222 |
<?php endif;
|
223 |
}
|
224 |
|
225 |
+
/**
|
226 |
+
* Generate a HTML version of the message that will be sent through an email.
|
227 |
+
*
|
228 |
+
* @param string $subject The reason of the message that will be sent.
|
229 |
+
* @param string $message Body of the message that will be sent.
|
230 |
+
* @param array $data_set Optional parameter to add more information to the notification.
|
231 |
+
* @return string The message formatted in a HTML template.
|
232 |
+
*/
|
233 |
function sucuriscan_prettify_mail($subject='', $message='', $data_set=array())
|
234 |
{
|
235 |
$current_user = wp_get_current_user();
|
250 |
$mail_variables[$var_key] = $var_value;
|
251 |
}
|
252 |
|
253 |
+
return sucuriscan_get_template("notification.{$prettify_type}.tpl", $mail_variables);
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Generate a HTML code using a template and replacing all the pseudo-variables
|
258 |
+
* by the dynamic variables provided by the developer through one of the parameters
|
259 |
+
* of the function.
|
260 |
+
*
|
261 |
+
* @param string $template Filename of the template that will be used to generate the page.
|
262 |
+
* @param array $template_variables A hash containing the pseudo-variable name as the key and the value that will replace it.
|
263 |
+
* @return string The formatted HTML page after replace all the pseudo-variables.
|
264 |
+
*/
|
265 |
+
function sucuriscan_get_template($template='', $template_variables=array()){
|
266 |
+
$template_content = '';
|
267 |
+
$template_path = WP_PLUGIN_DIR.'/'.SUCURISCAN_PLUGIN_FOLDER."/inc/tpl/{$template}";
|
268 |
+
|
269 |
+
if( file_exists($template_path) && is_readable($template_path) ){
|
270 |
+
$template_content = file_get_contents($template_path);
|
271 |
+
foreach($template_variables as $tpl_key=>$tpl_value){
|
272 |
+
$template_content = str_replace("%%SUCURI.{$tpl_key}%%", $tpl_value, $template_content);
|
273 |
+
}
|
274 |
+
}
|
275 |
+
return $template_content;
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Get the HTML content of the sidebar for the plugin interface.
|
280 |
+
*
|
281 |
+
* @return string HTML of the side for the plugin interface.
|
282 |
+
*/
|
283 |
+
function sucuriscan_wp_sidebar_gen()
|
284 |
+
{
|
285 |
+
return sucuriscan_get_template('sidebar.html.tpl');
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Retrieve a new set of keys for the Wordpress configuration file using the
|
290 |
+
* official API provided by Wordpress itself.
|
291 |
+
*
|
292 |
+
* @return array A list of the new set of keys generated by Wordpress API.
|
293 |
+
*/
|
294 |
+
function sucuriscan_get_new_config_keys()
|
295 |
+
{
|
296 |
+
$request = wp_remote_get('https://api.wordpress.org/secret-key/1.1/salt/');
|
297 |
+
if( !is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200 ){
|
298 |
+
if( preg_match_all("/define\('([A-Z_]+)',[ ]+'(.*)'\);/", $request['body'], $match) ){
|
299 |
+
$new_keys = array();
|
300 |
+
foreach($match[1] as $i=>$value){
|
301 |
+
$new_keys[$value] = $match[2][$i];
|
302 |
+
}
|
303 |
+
return $new_keys;
|
304 |
+
}
|
305 |
+
}
|
306 |
+
return FALSE;
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Modify the Wordpress configuration file and change the keys that were defined
|
311 |
+
* by a new random-generated list of keys retrieved from the official Wordpress
|
312 |
+
* API. The result of the operation will be either FALSE in case of error, or an
|
313 |
+
* array containing multiple indexes explaining the modification, among them you
|
314 |
+
* will find the old and new keys.
|
315 |
+
*
|
316 |
+
* @return false|array Either FALSE in case of error, or an array with the old and new keys.
|
317 |
+
*/
|
318 |
+
function sucuriscan_set_new_config_keys()
|
319 |
+
{
|
320 |
+
$new_wpconfig = '';
|
321 |
+
$wp_config_path = ABSPATH.'wp-config.php';
|
322 |
+
|
323 |
+
if( file_exists($wp_config_path) ){
|
324 |
+
$wp_config_lines = file($wp_config_path);
|
325 |
+
$new_keys = sucuriscan_get_new_config_keys();
|
326 |
+
$old_keys = array();
|
327 |
+
$old_keys_string = $new_keys_string = '';
|
328 |
+
|
329 |
+
foreach($wp_config_lines as $wp_config_line){
|
330 |
+
$wp_config_line = str_replace("\n", '', $wp_config_line);
|
331 |
+
|
332 |
+
if( preg_match("/define\('([A-Z_]+)',([ ]+)'(.*)'\);/", $wp_config_line, $match) ){
|
333 |
+
$key_name = $match[1];
|
334 |
+
if( array_key_exists($key_name, $new_keys) ){
|
335 |
+
$white_spaces = $match[2];
|
336 |
+
$old_keys[$key_name] = $match[3];
|
337 |
+
$wp_config_line = "define('{$key_name}',{$white_spaces}'{$new_keys[$key_name]}');";
|
338 |
+
|
339 |
+
$old_keys_string .= "define('{$key_name}',{$white_spaces}'{$old_keys[$key_name]}');\n";
|
340 |
+
$new_keys_string .= "{$wp_config_line}\n";
|
341 |
+
}
|
342 |
+
}
|
343 |
+
|
344 |
+
$new_wpconfig .= "{$wp_config_line}\n";
|
345 |
+
}
|
346 |
+
|
347 |
+
$response = array(
|
348 |
+
'updated'=>is_writable($wp_config_path),
|
349 |
+
'old_keys'=>$old_keys,
|
350 |
+
'old_keys_string'=>$old_keys_string,
|
351 |
+
'new_keys'=>$new_keys,
|
352 |
+
'new_keys_string'=>$new_keys_string,
|
353 |
+
'new_wpconfig'=>$new_wpconfig
|
354 |
+
);
|
355 |
+
if( $response['updated'] ){
|
356 |
+
file_put_contents($wp_config_path, $new_wpconfig, LOCK_EX);
|
357 |
+
}
|
358 |
+
return $response;
|
359 |
+
}
|
360 |
+
return FALSE;
|
361 |
+
}
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Generate and set a new password for a specific user not in session.
|
365 |
+
*
|
366 |
+
* @param integer $user_id The user identifier that will be changed, this must be different than the user in session.
|
367 |
+
* @return boolean Either TRUE or FALSE in case of success or error respectively.
|
368 |
+
*/
|
369 |
+
function sucuriscan_new_password($user_id=0)
|
370 |
+
{
|
371 |
+
$user_id = intval($user_id);
|
372 |
+
$current_user = wp_get_current_user();
|
373 |
+
|
374 |
+
if( $user_id>0 && $user_id!=$current_user->ID ){
|
375 |
+
$user = get_userdata($user_id);
|
376 |
+
$new_password = wp_generate_password(15, TRUE, FALSE);
|
377 |
+
|
378 |
+
$data_set = array( 'User'=>$user->display_name );
|
379 |
+
$message = "The password for your user account in the website mentioned has been changed by an administrator,
|
380 |
+
this is the new password automatically generated by the system, please update ASAP.<br>
|
381 |
+
<div style='display:inline-block;background:#ddd;font-family:monaco,monospace,courier;
|
382 |
+
font-size:30px;margin:0;padding:15px;border:1px solid #999'>{$new_password}</div>";
|
383 |
+
sucuriscan_send_mail($user->user_email, 'Changed password', $message, $data_set);
|
384 |
+
|
385 |
+
wp_set_password($new_password, $user_id);
|
386 |
+
|
387 |
+
return TRUE;
|
388 |
+
}
|
389 |
+
return FALSE;
|
390 |
+
}
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Retrieve the real ip address of the user in the current request.
|
394 |
+
*
|
395 |
+
* @return string The real ip address of the user in the current request.
|
396 |
+
*/
|
397 |
+
function sucuriscan_get_remoteaddr()
|
398 |
+
{
|
399 |
+
$alternatives = array(
|
400 |
+
'HTTP_X_REAL_IP',
|
401 |
+
'HTTP_CLIENT_IP',
|
402 |
+
'HTTP_X_FORWARDED_FOR',
|
403 |
+
'HTTP_X_FORWARDED',
|
404 |
+
'HTTP_FORWARDED_FOR',
|
405 |
+
'HTTP_FORWARDED',
|
406 |
+
'REMOTE_ADDR',
|
407 |
+
'SUCURI_RIP',
|
408 |
+
);
|
409 |
+
foreach($alternatives as $alternative){
|
410 |
+
if( !isset($_SERVER[$alternative]) ){ continue; }
|
411 |
+
|
412 |
+
$remote_addr = preg_replace('/[^0-9., ]/', '', $_SERVER[$alternative]);
|
413 |
+
if($remote_addr) break;
|
414 |
+
}
|
415 |
+
|
416 |
+
return $remote_addr;
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* Check whether the site is behing the Sucuri CloudProxy network.
|
421 |
+
*
|
422 |
+
* @return boolean Either TRUE or FALSE if the site is behind CloudProxy.
|
423 |
+
*/
|
424 |
+
function sucuriscan_is_behind_cloudproxy(){
|
425 |
+
$http_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
426 |
+
if( preg_match('/^(.*):([0-9]+)/', $http_host, $match) ){ $http_host = $match[1]; }
|
427 |
+
$host_by_name = gethostbyname($http_host);
|
428 |
+
$host_by_addr = gethostbyaddr($host_by_name);
|
429 |
+
|
430 |
+
if(
|
431 |
+
isset($_SERVER['SUCURIREAL_REMOTE_ADDR'])
|
432 |
+
|| preg_match('/^cloudproxy([0-9]+)\.sucuri\.net$/', $host_by_addr)
|
433 |
+
){
|
434 |
+
return TRUE;
|
435 |
+
}
|
436 |
+
|
437 |
+
return FALSE;
|
438 |
+
}
|
439 |
+
|
440 |
+
/**
|
441 |
+
* Check whether the current site is working as a multi-site instance.
|
442 |
+
*
|
443 |
+
* @return boolean Either TRUE or FALSE in case Wordpress is being used as a multi-site instance.
|
444 |
+
*/
|
445 |
+
function sucuriscan_is_multisite(){
|
446 |
+
if( function_exists('is_multisite') && is_multisite() ){ return TRUE; }
|
447 |
+
return FALSE;
|
448 |
+
}
|
449 |
+
|
450 |
+
/**
|
451 |
+
* Find and retrieve the absolute path of the Wordpress configuration file.
|
452 |
+
*
|
453 |
+
* @return string Absolute path of the Wordpress configuration file.
|
454 |
+
*/
|
455 |
+
function sucuriscan_get_wpconfig_path(){
|
456 |
+
$wp_config_path = ABSPATH.'wp-config.php';
|
457 |
+
|
458 |
+
// if wp-config.php doesn't exist/not readable check one directory up
|
459 |
+
if( !is_readable($wp_config_path)){
|
460 |
+
$wp_config_path = ABSPATH.'/../wp-config.php';
|
461 |
+
}
|
462 |
+
return $wp_config_path;
|
463 |
+
}
|
464 |
+
|
465 |
+
/**
|
466 |
+
* Find and retrieve the absolute path of the main Wordpress htaccess file.
|
467 |
+
*
|
468 |
+
* @return string Absolute path of the main Wordpress htaccess file.
|
469 |
+
*/
|
470 |
+
function sucuriscan_get_htaccess_path(){
|
471 |
+
$base_dirs = array(
|
472 |
+
rtrim(ABSPATH, '/'),
|
473 |
+
dirname(ABSPATH),
|
474 |
+
dirname(dirname(ABSPATH))
|
475 |
+
);
|
476 |
+
|
477 |
+
foreach($base_dirs as $base_dir){
|
478 |
+
$htaccess_path = sprintf('%s/.htaccess', $base_dir);
|
479 |
+
if( file_exists($htaccess_path) ){
|
480 |
+
return $htaccess_path;
|
481 |
+
}
|
482 |
+
}
|
483 |
+
|
484 |
+
return FALSE;
|
485 |
+
}
|
486 |
+
|
487 |
+
/**
|
488 |
+
* Print a HTML code with a form from where the administrator can check the state
|
489 |
+
* of this site through Sucuri SiteCheck.
|
490 |
+
*
|
491 |
+
* @return void
|
492 |
+
*/
|
493 |
+
function sucuri_scan_page()
|
494 |
+
{
|
495 |
+
$U_ERROR = NULL;
|
496 |
+
if( !current_user_can('manage_options') ){
|
497 |
+
wp_die(__('You do not have sufficient permissions to access this page: Sucuri Malware Scanner') );
|
498 |
+
}
|
499 |
+
|
500 |
+
$template_variables = array(
|
501 |
+
'PluginURL'=>SUCURI_URL,
|
502 |
+
'Sidebar'=>sucuriscan_get_template('sidebar.html.tpl')
|
503 |
+
);
|
504 |
+
|
505 |
+
if( isset($_POST['wpsucuri-doscan']) ){
|
506 |
+
sucuriscan_print_scan();
|
507 |
+
return(1);
|
508 |
+
}
|
509 |
+
|
510 |
+
echo sucuriscan_get_template('initial-page.html.tpl', $template_variables);
|
511 |
+
}
|
512 |
+
|
513 |
+
/**
|
514 |
+
* Display the result of site scan made through SiteCheck.
|
515 |
+
*
|
516 |
+
* @return void
|
517 |
+
*/
|
518 |
+
function sucuriscan_print_scan()
|
519 |
+
{
|
520 |
+
$website_scanned = home_url();
|
521 |
+
$remote_url = 'http://sitecheck.sucuri.net/scanner/?serialized&clear&fromwp&scan='.$website_scanned;
|
522 |
+
$myresults = wp_remote_get($remote_url, array('timeout' => 180));
|
523 |
+
?>
|
524 |
+
<div class="wrap">
|
525 |
+
<h2 id="warnings_hook"></h2>
|
526 |
+
<div class="sucuriscan_header">
|
527 |
+
<a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">
|
528 |
+
<img src="<?php echo SUCURI_URL; ?>/inc/images/logo.png" alt="Sucuri Security" />
|
529 |
+
</a>
|
530 |
+
<?php sucuriscan_pagestop('Sucuri SiteCheck Malware Scanner'); ?>
|
531 |
+
</div>
|
532 |
+
|
533 |
+
<div class="postbox-container sucuriscan-results" style="width:75%;">
|
534 |
+
<div class="sucuriscan-maincontent">
|
535 |
+
<?php if( is_wp_error($myresults) ){ ?>
|
536 |
+
<div id="poststuff">
|
537 |
+
<div class="postbox">
|
538 |
+
<h3>Error retrieving the scan report</h3>
|
539 |
+
<div class="inside">
|
540 |
+
<?php print_r($myresults); ?>
|
541 |
+
</div>
|
542 |
+
</div>
|
543 |
+
</div>
|
544 |
+
<?php
|
545 |
+
}else if( preg_match('/^ERROR:/', $myresults['body']) ){
|
546 |
+
sucuriscan_admin_notice('error', $myresults['body'].' The URL scanned was: <code>'.$website_scanned.'</code>');
|
547 |
+
}else{
|
548 |
+
$res = unserialize($myresults['body']);
|
549 |
+
|
550 |
+
// Check for general warnings, and return the information for Infected/Clean site.
|
551 |
+
$malware_warns_exists = isset($res['MALWARE']['WARN']) ? TRUE : FALSE;
|
552 |
+
?>
|
553 |
+
<div id="poststuff">
|
554 |
+
<div class="postbox">
|
555 |
+
<h3>
|
556 |
+
<?php if( !$malware_warns_exists ): ?>
|
557 |
+
<img src="<?php echo SUCURI_URL; ?>/inc/images/ok.png" class="icon-ok" />
|
558 |
+
No malware was identified
|
559 |
+
<?php else: ?>
|
560 |
+
<img src="<?php echo SUCURI_URL; ?>/inc/images/warn.png" class="icon-warn" />
|
561 |
+
Site compromised (malware was identified)
|
562 |
+
<?php endif; ?>
|
563 |
+
</h3>
|
564 |
+
<div class="inside">
|
565 |
+
<?php if( !$malware_warns_exists ): ?>
|
566 |
+
<span><strong>Malware:</strong> No.</span><br>
|
567 |
+
<span><strong>Malicious javascript:</strong> No.</span><br>
|
568 |
+
<span><strong>Malicious iframes:</strong> No.</span><br>
|
569 |
+
<span><strong>Suspicious redirections (htaccess):</strong> No.</span><br>
|
570 |
+
<span><strong>Blackhat SEO Spam:</strong> No.</span><br>
|
571 |
+
<span><strong>Anomaly detection:</strong> Clean.</span><br>
|
572 |
+
<?php else: ?>
|
573 |
+
<?php
|
574 |
+
foreach( $res['MALWARE']['WARN'] as $malres ){
|
575 |
+
if( !is_array($malres) ){
|
576 |
+
echo htmlspecialchars($malres);
|
577 |
+
}else{
|
578 |
+
$mwdetails = explode("\n", htmlspecialchars($malres[1]));
|
579 |
+
echo htmlspecialchars($malres[0])."\n<br />". substr($mwdetails[0], 1)."<br />\n";
|
580 |
+
}
|
581 |
+
}
|
582 |
+
?>
|
583 |
+
<?php endif; ?>
|
584 |
+
<br />
|
585 |
+
<i>
|
586 |
+
More details here: <a href="http://sitecheck.sucuri.net/scanner/?scan=<?php echo $website_scanned; ?>">
|
587 |
+
http://sitecheck.sucuri.net/scanner/?scan=<?php echo $website_scanned; ?></a>
|
588 |
+
</i>
|
589 |
+
<hr />
|
590 |
+
<i>
|
591 |
+
If our free scanner did not detect any issue, you may have a more complicated and hidden
|
592 |
+
problem. You can try our <a href="admin.php?page=sucuriscan_core_integrity">WordPress integrity
|
593 |
+
checks</a> or sign up with Sucuri <a target="_blank" href="http://sucuri.net/signup">here</a>
|
594 |
+
for a complete and in depth scan+cleanup (not included in the free checks).
|
595 |
+
</i>
|
596 |
+
<hr />
|
597 |
+
</div>
|
598 |
+
</div>
|
599 |
+
</div>
|
600 |
+
|
601 |
+
<div id="poststuff">
|
602 |
+
<div class="postbox">
|
603 |
+
<h3>
|
604 |
+
<?php if( isset($res['BLACKLIST']['WARN']) ): ?>
|
605 |
+
<img src="<?php echo SUCURI_URL; ?>/inc/images/warn.png" class="icon-warn" />
|
606 |
+
Site blacklisted
|
607 |
+
<?php else: ?>
|
608 |
+
<img src="<?php echo SUCURI_URL; ?>/inc/images/ok.png" class="icon-ok" />
|
609 |
+
Site blacklist-free
|
610 |
+
<?php endif; ?>
|
611 |
+
</h3>
|
612 |
+
<div class="inside">
|
613 |
+
<?php
|
614 |
+
foreach(array(
|
615 |
+
'INFO'=>'CLEAN',
|
616 |
+
'WARN'=>'WARNING'
|
617 |
+
) as $type=>$group_title){
|
618 |
+
if( isset($res['BLACKLIST'][$type]) ){
|
619 |
+
foreach($res['BLACKLIST'][$type] as $blres){
|
620 |
+
$report_site = htmlspecialchars($blres[0]);
|
621 |
+
$report_url = htmlspecialchars($blres[1]);
|
622 |
+
echo "<b>{$group_title}: </b>{$report_site} <a href='{$report_url}' target='_blank'>{$report_url}</a><br />";
|
623 |
+
}
|
624 |
+
}
|
625 |
+
}
|
626 |
+
?>
|
627 |
+
</div>
|
628 |
+
</div>
|
629 |
+
</div>
|
630 |
+
|
631 |
+
<?php
|
632 |
+
global $wp_version;
|
633 |
+
$wordpress_updated = FALSE;
|
634 |
+
$updates = function_exists('get_core_updates') ? get_core_updates() : array();
|
635 |
+
if( !is_array($updates) || empty($updates) || $updates[0]->response=='latest' ){
|
636 |
+
$wordpress_updated = TRUE;
|
637 |
+
}
|
638 |
+
?>
|
639 |
+
<div id="poststuff">
|
640 |
+
<div class="postbox">
|
641 |
+
<h3>
|
642 |
+
<?php if($wordpress_updated): ?>
|
643 |
+
<img src="<?php echo SUCURI_URL; ?>/inc/images/ok.png" class="icon-ok" />
|
644 |
+
System info (WordPress upgraded)
|
645 |
+
<?php else: ?>
|
646 |
+
<img src="<?php echo SUCURI_URL; ?>/inc/images/warn.png" class="icon-warn" />
|
647 |
+
System info (WordPress outdated)
|
648 |
+
<?php endif; ?>
|
649 |
+
</h3>
|
650 |
+
<div class="inside">
|
651 |
+
<b>Site:</b> <?php echo $res['SCAN']['SITE'][0]; ?> (<?php echo $res['SCAN']['IP'][0]; ?>)<br />
|
652 |
+
<b>PHP (version installed): </b> <?php echo phpversion(); ?><br />
|
653 |
+
<b>WordPress (installed):</b> <?php echo $wp_version; ?><br />
|
654 |
+
<?php if( !$wordpress_updated ): ?>
|
655 |
+
<b>WordPress (update):</b> <?php echo $updates[0]->version; ?><br />
|
656 |
+
<a href="<?php echo admin_url('update-core.php'); ?>" class="button button-primary">Update</a>
|
657 |
+
<?php endif; ?>
|
658 |
+
<?php
|
659 |
+
if( isset($res['SYSTEM']['NOTICE']) ){
|
660 |
+
foreach( $res['SYSTEM']['NOTICE'] as $notres ){
|
661 |
+
if( is_array($notres) ){
|
662 |
+
echo htmlspecialchars($notres[0]).chr(32).htmlspecialchars($notres[1]);
|
663 |
+
}else{
|
664 |
+
echo htmlspecialchars($notres)."<br />\n";
|
665 |
+
}
|
666 |
+
}
|
667 |
+
}
|
668 |
+
?>
|
669 |
+
</div>
|
670 |
+
</div>
|
671 |
+
</div>
|
672 |
+
<?php } ?>
|
673 |
+
|
674 |
+
<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>
|
675 |
+
</div><!-- End sucuriscan-maincontent -->
|
676 |
+
</div><!-- End postbox-container -->
|
677 |
+
|
678 |
+
<?php echo sucuriscan_get_template('sidebar.html.tpl') ?>
|
679 |
+
|
680 |
+
</div><!-- End Wrap -->
|
681 |
+
|
682 |
+
<?php
|
683 |
+
}
|
684 |
+
|
685 |
+
/**
|
686 |
+
* Wordpress core integrity page.
|
687 |
+
*
|
688 |
+
* It checks whether the Wordpress core files are the original ones, and the state
|
689 |
+
* of the themes and plugins reporting the availability of updates. It also checks
|
690 |
+
* the user accounts under the administrator group.
|
691 |
+
*
|
692 |
+
* @return void
|
693 |
+
*/
|
694 |
+
function sucuriscan_core_integrity_page()
|
695 |
+
{
|
696 |
+
|
697 |
+
/* WordPress Integrity page. */
|
698 |
+
|
699 |
+
echo '<div class="wrap">';
|
700 |
+
echo '<h2 id="warnings_hook"></h2>';
|
701 |
+
echo '<div class="sucuriscan_header">';
|
702 |
+
echo '<a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">';
|
703 |
+
echo '<img src="'.SUCURI_URL.'/inc/images/logo.png" alt="Sucuri Security" />';
|
704 |
+
echo '</a>';
|
705 |
+
sucuriscan_pagestop("Sucuri WordPress Integrity");
|
706 |
+
echo '</div>';
|
707 |
+
|
708 |
+
if(!current_user_can('manage_options'))
|
709 |
+
{
|
710 |
+
wp_die(__('You do not have sufficient permissions to access this page: Sucuri Integrity Check') );
|
711 |
+
}
|
712 |
+
?>
|
713 |
+
|
714 |
+
<div class="postbox-container" style="width:75%;">
|
715 |
+
<div class="sucuriscan-maincontent">
|
716 |
+
<div class="postbox">
|
717 |
+
<div class="inside">
|
718 |
+
<h2 align="center">Sucuri WordPress Integrity Checks</h2>
|
719 |
+
</div>
|
720 |
+
</div>
|
721 |
+
|
722 |
+
<?php
|
723 |
+
if( isset($_POST['wpsucuri-core-integrity']) ){
|
724 |
+
if(!wp_verify_nonce($_POST['sucuriscan_core_integritynonce'], 'sucuriscan_core_integritynonce'))
|
725 |
+
{
|
726 |
+
unset($_POST['wpsucuri-core_integrity']);
|
727 |
+
}
|
728 |
+
}
|
729 |
+
?>
|
730 |
+
|
731 |
+
<div id="poststuff">
|
732 |
+
<?php
|
733 |
+
sucuriscan_core_integrity_function_wrapper(
|
734 |
+
'sucuriwp_core_integrity_check',
|
735 |
+
'Verify Integrity of WordPress Core Files',
|
736 |
+
'This test will check wp-includes, wp-admin, and the top directory files against the latest WordPress
|
737 |
+
hashing database. If any of those files were modified, it is a big sign of a possible compromise.'
|
738 |
+
);
|
739 |
+
|
740 |
+
sucuriscan_core_integrity_wp_content_wrapper();
|
741 |
+
|
742 |
+
sucuriscan_core_integrity_function_wrapper(
|
743 |
+
'sucuriwp_list_admins',
|
744 |
+
'Admin User Dump',
|
745 |
+
'List all administrator users and their latest login time.'
|
746 |
+
);
|
747 |
+
|
748 |
+
sucuriscan_core_integrity_function_wrapper(
|
749 |
+
'sucuriwp_check_plugins',
|
750 |
+
'Outdated Plugin list',
|
751 |
+
'This test will list any outdated (active) plugins.'
|
752 |
+
);
|
753 |
+
|
754 |
+
sucuriscan_core_integrity_function_wrapper(
|
755 |
+
'sucuriwp_check_themes',
|
756 |
+
'Outdated Theme List',
|
757 |
+
'This test will list any outdated theme.'
|
758 |
+
);
|
759 |
+
?>
|
760 |
+
</div>
|
761 |
+
|
762 |
+
<p align="center">
|
763 |
+
<strong>If you have any questions about these tests or this plugin, contact us at <a href="mailto:info@sucuri.net">
|
764 |
+
info@sucuri.net</a> or visit <a href="http://sucuri.net">Sucuri Security</a></strong>
|
765 |
+
</p>
|
766 |
+
</div><!-- End sucuriscan-maincontent -->
|
767 |
+
</div><!-- End postbox-container -->
|
768 |
+
|
769 |
+
<?php echo sucuriscan_get_template('sidebar.html.tpl') ?>
|
770 |
+
|
771 |
+
</div><!-- End Wrap -->
|
772 |
+
|
773 |
+
<?php
|
774 |
+
}
|
775 |
+
|
776 |
+
/**
|
777 |
+
* Print the HTML code with the form needed to check the integrity of specific
|
778 |
+
* parts of the site and administrator panel.
|
779 |
+
*
|
780 |
+
* @param string $function_name Name of the function that will be executed on form submission.
|
781 |
+
* @param string $stitle Title of the HTML panel.
|
782 |
+
* @param string $description Explanation of the action that will be performed once the form is submitted.
|
783 |
+
* @return void
|
784 |
+
*/
|
785 |
+
function sucuriscan_core_integrity_function_wrapper($function_name='', $stitle='', $description=''){ ?>
|
786 |
+
<div class="postbox">
|
787 |
+
<h3><?php echo $stitle; ?></h3>
|
788 |
+
<div class="inside">
|
789 |
+
<form method="post">
|
790 |
+
<input type="hidden" name="<?php echo $function_name; ?>nonce" value="<?php echo wp_create_nonce($function_name.'nonce'); ?>" />
|
791 |
+
<input type="hidden" name="<?php echo $function_name; ?>" value="1" />
|
792 |
+
<p><?php echo $description; ?></p>
|
793 |
+
<input class="button-primary" type="submit" name="<?php echo $function_name; ?>" value="Check" />
|
794 |
+
</form>
|
795 |
+
<br />
|
796 |
+
<?php
|
797 |
+
if (isset($_POST[$function_name.'nonce']) && isset($_POST[$function_name])) {
|
798 |
+
if( function_exists($function_name) ){
|
799 |
+
$function_name();
|
800 |
+
}
|
801 |
+
}
|
802 |
+
?>
|
803 |
+
</div>
|
804 |
+
</div>
|
805 |
+
<?php }
|
806 |
+
|
807 |
+
/**
|
808 |
+
* List all files inside wp-content that have been modified in the last days.
|
809 |
+
*
|
810 |
+
* @return void
|
811 |
+
*/
|
812 |
+
function sucuriscan_core_integrity_wp_content_wrapper(){ ?>
|
813 |
+
<div class="postbox">
|
814 |
+
<h3>Latest modified files</h3>
|
815 |
+
<div class="inside">
|
816 |
+
<form method="post">
|
817 |
+
<input type="hidden" name="sucuriwp_content_checknonce" value="<?php echo wp_create_nonce('sucuriwp_content_checknonce'); ?>" />
|
818 |
+
<input type="hidden" name="sucuriwp_content_check" value="sucuriwp_content_check" />
|
819 |
+
<p>
|
820 |
+
This test will list all files inside wp-content that have been modified in the past
|
821 |
+
<select name="sucuriwp_content_check_back">
|
822 |
+
<?php foreach(array( 1,3,7,30 ) as $days): ?>
|
823 |
+
<?php $selected =
|
824 |
+
( isset($_POST['sucuriwp_content_check_back']) && $_POST['sucuriwp_content_check_back']==$days )
|
825 |
+
? 'selected="selected"' : ''; ?>
|
826 |
+
<option value="<?php echo $days; ?>" <?php echo $selected; ?>><?php echo $days; ?></option>
|
827 |
+
<?php endforeach; ?>
|
828 |
+
</select> days. (select the number of days first)
|
829 |
+
</p>
|
830 |
+
<input class="button-primary" type="submit" name="sucuriwp_content_check" value="Check">
|
831 |
+
</form>
|
832 |
+
|
833 |
+
<?php if (
|
834 |
+
isset($_POST['sucuriwp_content_checknonce'])
|
835 |
+
// && wp_verify_nonce($_POST['sucuriwp_content_checknonce'], 'sucuriwp_content_checknonce')
|
836 |
+
&& isset($_POST['sucuriwp_content_check'])
|
837 |
+
): ?>
|
838 |
+
<br />
|
839 |
+
<table class="wp-list-table widefat sucuriscan-lastmodified">
|
840 |
+
<thead>
|
841 |
+
<tr>
|
842 |
+
<th colspan="2">wp_content latest modified files</th>
|
843 |
+
</tr>
|
844 |
+
<tr>
|
845 |
+
<th class="manage-column">Filepath</th>
|
846 |
+
<th class="manage-column">Modification date/time</th>
|
847 |
+
</tr>
|
848 |
+
</thead>
|
849 |
+
<tbody>
|
850 |
+
<?php
|
851 |
+
$wp_content_hashes = read_dir_r(ABSPATH.'wp-content', true);
|
852 |
+
$days = htmlspecialchars(trim((int)$_POST['sucuriwp_content_check_back']));
|
853 |
+
$back_days = current_time( 'timestamp' ) - ( $days * 86400);
|
854 |
+
|
855 |
+
foreach ( $wp_content_hashes as $key => $value) {
|
856 |
+
if ($value['time'] >= $back_days ){
|
857 |
+
$date = date('d-m-Y H:i:s', $value['time']);
|
858 |
+
printf('<tr><td>%s</td><td>%s</td></tr>', $key, $date);
|
859 |
+
}
|
860 |
+
}
|
861 |
+
?>
|
862 |
+
</tbody>
|
863 |
+
</table>
|
864 |
+
<?php endif; ?>
|
865 |
+
</div>
|
866 |
+
</div>
|
867 |
+
<?php }
|
868 |
+
|
869 |
+
/**
|
870 |
+
* Retrieve a list of md5sum and last modification time of all the files in the
|
871 |
+
* folder specified. This is a recursive function.
|
872 |
+
*
|
873 |
+
* @param string $dir The base path where the scanning will start.
|
874 |
+
* @param boolean $recursiv Either TRUE or FALSE if the scan should be performed recursively.
|
875 |
+
* @return array List of arrays containing the md5sum and last modification time of the files found.
|
876 |
+
*/
|
877 |
+
function read_dir_r($dir = "./", $recursiv = false)
|
878 |
+
{
|
879 |
+
$skipname = basename(__FILE__);
|
880 |
+
$skipname .= ",_sucuribackup,wp-config.php";
|
881 |
+
|
882 |
+
$files_info = array();
|
883 |
+
|
884 |
+
$dir_handler = opendir($dir);
|
885 |
+
|
886 |
+
while(($entry = readdir($dir_handler)) !== false) {
|
887 |
+
if ($entry != "." && $entry != "..") {
|
888 |
+
$dir = preg_replace("/^(.*)(\/)+$/", "$1", $dir);
|
889 |
+
$item = $dir . "/" . $entry;
|
890 |
+
if (is_file($item)) {
|
891 |
+
|
892 |
+
$skip_parts = explode(",", $skipname);
|
893 |
+
foreach ($skip_parts as $skip) {
|
894 |
+
if (strpos($item,$skip) !== false) {
|
895 |
+
continue 2;
|
896 |
+
}
|
897 |
+
}
|
898 |
+
|
899 |
+
$md5 = @md5_file($item);
|
900 |
+
$time_stamp = @filectime($item);
|
901 |
+
$item_name = str_replace(ABSPATH, "./", $item);
|
902 |
+
$files_info[$item_name] = array(
|
903 |
+
'md5' => $md5,
|
904 |
+
'time' => $time_stamp
|
905 |
+
);
|
906 |
+
|
907 |
+
}
|
908 |
+
elseif (is_dir($item) && $recursiv) {
|
909 |
+
$files_info = array_merge( $files_info , read_dir_r($item) );
|
910 |
+
}
|
911 |
+
}
|
912 |
+
}
|
913 |
+
|
914 |
+
closedir($dir_handler);
|
915 |
+
return $files_info;
|
916 |
+
}
|
917 |
+
|
918 |
+
/**
|
919 |
+
* Compare the md5sum of the core files in the current site with the hashes hosted
|
920 |
+
* remotely in Sucuri servers. These hashes are updated every time a new version
|
921 |
+
* of Wordpress is released.
|
922 |
+
*
|
923 |
+
* @return void
|
924 |
+
*/
|
925 |
+
function sucuriwp_core_integrity_check()
|
926 |
+
{
|
927 |
+
|
928 |
+
global $wp_version;
|
929 |
+
|
930 |
+
$curlang = get_bloginfo("language");
|
931 |
+
|
932 |
+
$cp = 0;
|
933 |
+
$updates = get_core_updates();
|
934 |
+
if( !is_array($updates) || empty($updates) || $updates[0]->response=='latest' ){
|
935 |
+
$cp = 1;
|
936 |
+
}
|
937 |
+
if(strcmp($wp_version, "3.7") < 0)
|
938 |
+
{
|
939 |
+
$cp = 0;
|
940 |
+
}
|
941 |
+
$wp_version = htmlspecialchars($wp_version);
|
942 |
+
|
943 |
+
if($cp == 0)
|
944 |
+
{
|
945 |
+
echo '<p><img style="position:relative;top:5px" height="22" width="22" src="'.SUCURI_URL.'inc/images/warn.png" />'
|
946 |
+
.' The current version of your site was detected as <code>'.$wp_version.'</code> which is different to the '
|
947 |
+
.'official latest version. The integrity check can not run using this version number <a href="'.admin_url('update-core.php').'">'
|
948 |
+
.'update now</a> to be able to run the integrity check.</p>';
|
949 |
+
}
|
950 |
+
else
|
951 |
+
{
|
952 |
+
$latest_hashes = sucuriscan_check_wp_integrity($wp_version);
|
953 |
+
if($latest_hashes){
|
954 |
+
sucuriscan_draw_corefiles_status(array(
|
955 |
+
'added'=>$latest_hashes['added'],
|
956 |
+
'removed'=>$latest_hashes['removed'],
|
957 |
+
'modified'=>$latest_hashes['bad']
|
958 |
+
));
|
959 |
+
}else{
|
960 |
+
sucuriscan_admin_notice('error', 'Error retrieving the wordpress core hashes, try again.');
|
961 |
+
}
|
962 |
+
}
|
963 |
+
}
|
964 |
+
|
965 |
+
/**
|
966 |
+
* List all the Wordpress core files modified until now.
|
967 |
+
*
|
968 |
+
* @param array $list List of Wordpress core files modified.
|
969 |
+
* @return void
|
970 |
+
*/
|
971 |
+
function sucuriscan_draw_corefiles_status($list=array()){
|
972 |
+
if( is_array($list) && !empty($list) ): ?>
|
973 |
+
<table class="wp-list-table widefat sucuriscan-corefiles">
|
974 |
+
<tbody>
|
975 |
+
<?php
|
976 |
+
foreach($list as $diff_type=>$file_list){
|
977 |
+
printf('<tr><th>Core File %s: %d</th></tr>', ucwords($diff_type), sizeof($file_list));
|
978 |
+
foreach($file_list as $filepath){
|
979 |
+
printf('<tr><td>%s</td></tr>', $filepath);
|
980 |
+
}
|
981 |
+
}
|
982 |
+
?>
|
983 |
+
</tbody>
|
984 |
+
</table>
|
985 |
+
<?php endif; ?>
|
986 |
+
<?php }
|
987 |
+
|
988 |
+
/**
|
989 |
+
* List all the user accounts under the user level specified, by default the
|
990 |
+
* users analyzed are the administrator accounts.
|
991 |
+
*
|
992 |
+
* @param string $userlevel Identifier of the user level that will be filtered in the search.
|
993 |
+
* @return void
|
994 |
+
*/
|
995 |
+
function sucuriwp_list_admins($userlevel = '10') {
|
996 |
+
|
997 |
+
global $wpdb;
|
998 |
+
/*
|
999 |
+
1 = subscriber
|
1000 |
+
2 = editor
|
1001 |
+
3 = author
|
1002 |
+
7 = publisher
|
1003 |
+
10 = administrator
|
1004 |
+
*/
|
1005 |
+
|
1006 |
+
// Page pseudo-variables initialization.
|
1007 |
+
$template_variables = array(
|
1008 |
+
'SucuriURL'=>SUCURI_URL,
|
1009 |
+
'AdminUsers.UserList'=>''
|
1010 |
+
);
|
1011 |
+
|
1012 |
+
$admins = $wpdb->get_results("SELECT DISTINCT(user_id) AS user_id FROM `$wpdb->usermeta` WHERE meta_value = '$userlevel'");
|
1013 |
+
foreach ( (array) $admins as $user ) {
|
1014 |
+
$admin = get_userdata( $user->user_id );
|
1015 |
+
$admin->lastlogins = sucuriscan_get_logins(4, $admin->ID);
|
1016 |
+
$userlevel = $admin->wp2_user_level;
|
1017 |
+
$name = $admin->nickname;
|
1018 |
+
|
1019 |
+
$user_snippet = array(
|
1020 |
+
'AdminUsers.Username'=>$admin->user_login,
|
1021 |
+
'AdminUsers.Email'=>$admin->user_email,
|
1022 |
+
'AdminUsers.LastLogins'=>'',
|
1023 |
+
'AdminUsers.UserURL'=>admin_url('user-edit.php?user_id='.$user->user_id)
|
1024 |
+
);
|
1025 |
+
if( !empty($admin->lastlogins) ){
|
1026 |
+
$user_snippet['AdminUsers.NoLastLogins'] = 'hidden';
|
1027 |
+
$user_snippet['AdminUsers.NoLastLoginsTable'] = 'visible';
|
1028 |
+
foreach($admin->lastlogins as $lastlogin){
|
1029 |
+
$user_snippet['AdminUsers.LastLogins'] .= sucuriscan_get_template('integrity-admins-lastlogin.snippet.tpl', array(
|
1030 |
+
'AdminUsers.RemoteAddr'=>$lastlogin->user_remoteaddr,
|
1031 |
+
'AdminUsers.Datetime'=>$lastlogin->user_lastlogin
|
1032 |
+
));
|
1033 |
+
}
|
1034 |
+
}else{
|
1035 |
+
$user_snippet['AdminUsers.NoLastLogins'] = 'visible';
|
1036 |
+
$user_snippet['AdminUsers.NoLastLoginsTable'] = 'hidden';
|
1037 |
+
}
|
1038 |
+
|
1039 |
+
$template_variables['AdminUsers.UserList'] .= sucuriscan_get_template('integrity-admins.snippet.tpl', $user_snippet);
|
1040 |
+
}
|
1041 |
+
|
1042 |
+
echo sucuriscan_get_template('integrity-admins.html.tpl', $template_variables);
|
1043 |
+
}
|
1044 |
+
|
1045 |
+
/**
|
1046 |
+
* Check if any installed plugin has an update available.
|
1047 |
+
*
|
1048 |
+
* @return void
|
1049 |
+
*/
|
1050 |
+
function sucuriwp_check_plugins()
|
1051 |
+
{
|
1052 |
+
do_action("wp_update_plugins"); // force WP to check plugins for updates
|
1053 |
+
wp_update_plugins();
|
1054 |
+
$update_plugins = get_site_transient('update_plugins'); // get information of updates
|
1055 |
+
$plugins_need_update = $update_plugins->response; // plugins that need updating
|
1056 |
+
|
1057 |
+
echo '<div class="postbox">';
|
1058 |
+
echo "<h3>Outdated Plugins</h3>";
|
1059 |
+
echo '<div class="inside">';
|
1060 |
+
if (!empty($update_plugins->response)) { // any plugin updates available?
|
1061 |
+
$plugins_need_update = $update_plugins->response; // plugins that need updating
|
1062 |
+
$active_plugins = array_flip(get_option('active_plugins')); // find which plugins are active
|
1063 |
+
$plugins_need_update = array_intersect_key($plugins_need_update, $active_plugins); // only keep plugins that are active
|
1064 |
+
if(count($plugins_need_update) >= 1) { // any plugins need updating after all the filtering gone on above?
|
1065 |
+
require_once(ABSPATH . 'wp-admin/includes/plugin-install.php'); // Required for plugin API
|
1066 |
+
require_once(ABSPATH . WPINC . '/version.php' ); // Required for WP core version
|
1067 |
+
foreach($plugins_need_update as $key => $data) { // loop through the plugins that need updating
|
1068 |
+
$plugin_info = get_plugin_data(WP_PLUGIN_DIR . "/" . $key); // get local plugin info
|
1069 |
+
$info = plugins_api('plugin_information', array('slug' => $data->slug )); // get repository plugin info
|
1070 |
+
$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";
|
1071 |
+
echo "<p>$message</p>";
|
1072 |
+
}
|
1073 |
+
}
|
1074 |
+
else
|
1075 |
+
{
|
1076 |
+
echo "<p>All plugins are up-to-date!</p>";
|
1077 |
+
}
|
1078 |
+
}
|
1079 |
+
else
|
1080 |
+
{
|
1081 |
+
echo "<p>All plugins are up-to-date!</p>";
|
1082 |
+
}
|
1083 |
+
echo '</div>';
|
1084 |
+
echo '</div>';
|
1085 |
+
}
|
1086 |
+
|
1087 |
+
/**
|
1088 |
+
* Check if any installed theme has an update available.
|
1089 |
+
*
|
1090 |
+
* @return void
|
1091 |
+
*/
|
1092 |
+
function sucuriwp_check_themes()
|
1093 |
+
{
|
1094 |
+
do_action("wp_update_themes"); // force WP to check for theme updates
|
1095 |
+
wp_update_themes();
|
1096 |
+
$update_themes = get_site_transient('update_themes'); // get information of updates
|
1097 |
+
|
1098 |
+
echo '<div class="postbox">';
|
1099 |
+
echo "<h3>Outdated Themes</h3>";
|
1100 |
+
echo '<div class="inside">';
|
1101 |
+
if (!empty($update_themes->response)) { // any theme updates available?
|
1102 |
+
$themes_need_update = $update_themes->response; // themes that need updating
|
1103 |
+
|
1104 |
+
if(count($themes_need_update) >= 1) { // any themes need updating after all the filtering gone on above?
|
1105 |
+
foreach($themes_need_update as $key => $data) { // loop through the themes that need updating
|
1106 |
+
$theme_info = get_theme_data(WP_CONTENT_DIR . "/themes/" . $key . "/style.css"); // get theme info
|
1107 |
+
$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";
|
1108 |
+
echo "<p>$message</p>";
|
1109 |
+
}
|
1110 |
+
}
|
1111 |
+
}
|
1112 |
+
else
|
1113 |
+
{
|
1114 |
+
echo "<p>All themes are up-to-date!</p>";
|
1115 |
+
}
|
1116 |
+
echo '</div>';
|
1117 |
+
echo '</div>';
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
/**
|
1121 |
+
* Retrieve a list with the checksums of the files in a specific version of Wordpress.
|
1122 |
+
*
|
1123 |
+
* @param integer $version Valid version number of the Wordpress project.
|
1124 |
+
* @return object Associative object with the relative filepath and the checksums of the project files.
|
1125 |
+
*/
|
1126 |
+
function sucuriscan_get_official_checksums($version=0){
|
1127 |
+
$api_url = sprintf('http://api.wordpress.org/core/checksums/1.0/?version=%s&locale=en_US', $version);
|
1128 |
+
|
1129 |
+
$request = wp_remote_get($api_url);
|
1130 |
+
if( !is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200 ){
|
1131 |
+
$json_data = json_decode($request['body']);
|
1132 |
+
if( $json_data->checksums !== FALSE ){
|
1133 |
+
return $json_data->checksums;
|
1134 |
+
}
|
1135 |
+
}
|
1136 |
+
|
1137 |
+
return FALSE;
|
1138 |
+
}
|
1139 |
+
|
1140 |
+
/**
|
1141 |
+
* Check whether the core Wordpress files where modified, removed or if any file
|
1142 |
+
* was added to the core folders. This function returns an associative array with
|
1143 |
+
* these keys:
|
1144 |
+
*
|
1145 |
+
* <ul>
|
1146 |
+
* <li>bad: Files with a different checksum according to the official files of the Wordpress version filtered,</li>
|
1147 |
+
* <li>good: Files with the same checksums than the official files,</li>
|
1148 |
+
* <li>removed: Official files which are not present in the local project,</li>
|
1149 |
+
* <li>added: Files present in the local project but not in the official Wordpress packages.</li>
|
1150 |
+
* </ul>
|
1151 |
+
*
|
1152 |
+
* @param integer $version Valid version number of the Wordpress project.
|
1153 |
+
* @return array Associative array with these keys: bad, good, removed, added.
|
1154 |
+
*/
|
1155 |
+
function sucuriscan_check_wp_integrity($version=0){
|
1156 |
+
$latest_hashes = sucuriscan_get_official_checksums($version);
|
1157 |
+
|
1158 |
+
if( !$latest_hashes ){ return FALSE; }
|
1159 |
+
|
1160 |
+
$output = array( 'bad'=>array(), 'good'=>array(), 'removed'=>array(), 'added'=>array() );
|
1161 |
+
|
1162 |
+
// Get current filesystem tree.
|
1163 |
+
$wp_top_hashes = read_dir_r( ABSPATH , false);
|
1164 |
+
$wp_admin_hashes = read_dir_r( ABSPATH . 'wp-admin', true);
|
1165 |
+
$wp_includes_hashes = read_dir_r( ABSPATH . 'wp-includes', true);
|
1166 |
+
$wp_core_hashes = array_merge( $wp_top_hashes, $wp_admin_hashes, $wp_includes_hashes );
|
1167 |
+
|
1168 |
+
// Compare remote and local md5sums and search removed files.
|
1169 |
+
foreach( $latest_hashes as $filepath=>$remote_checksum ){
|
1170 |
+
$full_filepath = sprintf('%s/%s', ABSPATH, $filepath);
|
1171 |
+
if( file_exists($full_filepath) ){
|
1172 |
+
$local_checksum = @md5_file($full_filepath);
|
1173 |
+
if( $local_checksum && $local_checksum == $remote_checksum ){
|
1174 |
+
$output['good'][] = $filepath;
|
1175 |
+
}else{
|
1176 |
+
$output['bad'][] = $filepath;
|
1177 |
+
}
|
1178 |
+
}else{
|
1179 |
+
$output['removed'][] = $filepath;
|
1180 |
+
}
|
1181 |
+
}
|
1182 |
+
|
1183 |
+
// Search added files (files not common in a normal wordpress installation).
|
1184 |
+
foreach( $wp_core_hashes as $filepath=>$extra_info ){
|
1185 |
+
$filepath = preg_replace('/^\.\/(.*)/', '$1', $filepath);
|
1186 |
+
if( !property_exists($latest_hashes, $filepath) ){
|
1187 |
+
$output['added'][] = $filepath;
|
1188 |
+
}
|
1189 |
+
}
|
1190 |
+
|
1191 |
+
return $output;
|
1192 |
+
}
|
1193 |
+
|
1194 |
+
/**
|
1195 |
+
* Sucuri one-click hardening page.
|
1196 |
+
*
|
1197 |
+
* It loads all the functions defined in /lib/hardening.php and shows the forms
|
1198 |
+
* that the administrator can use to harden multiple parts of the site.
|
1199 |
+
*
|
1200 |
+
* @return void
|
1201 |
+
*/
|
1202 |
+
function sucuriscan_hardening_page(){
|
1203 |
+
echo '<div class="wrap">';
|
1204 |
+
echo '<h2 id="warnings_hook"></h2>';
|
1205 |
+
echo '<div class="sucuriscan_header">';
|
1206 |
+
echo '<a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">';
|
1207 |
+
echo '<img src="'.SUCURI_URL.'/inc/images/logo.png" alt="Sucuri Security" />';
|
1208 |
+
echo '</a>';
|
1209 |
+
sucuriscan_pagestop("Sucuri 1-Click Hardening Options");
|
1210 |
+
echo '</div>';
|
1211 |
+
|
1212 |
+
if(!current_user_can('manage_options'))
|
1213 |
+
{
|
1214 |
+
wp_die(__('You do not have sufficient permissions to access this page: Sucuri Hardening') );
|
1215 |
+
}
|
1216 |
+
?>
|
1217 |
+
|
1218 |
+
<div class="postbox-container" style="width:75%">
|
1219 |
+
<div class="sucuriscan-maincontent">
|
1220 |
+
<div class="postbox">
|
1221 |
+
<div class="inside">
|
1222 |
+
<h2 align="center">Help secure your WordPress install with <a href="http://sucuri.net/signup">Sucuri</a> 1-Click Hardening Options.</h2>
|
1223 |
+
</div>
|
1224 |
+
</div>
|
1225 |
+
|
1226 |
+
<?php
|
1227 |
+
if( isset($_POST['wpsucuri-doharden']) ){
|
1228 |
+
if(!wp_verify_nonce($_POST['sucuriscan_wphardeningnonce'], 'sucuriscan_wphardeningnonce'))
|
1229 |
+
{
|
1230 |
+
unset($_POST['wpsucuri-doharden']);
|
1231 |
+
}
|
1232 |
+
}
|
1233 |
+
?>
|
1234 |
+
|
1235 |
+
<div id="poststuff">
|
1236 |
+
<form method="post">
|
1237 |
+
<input type="hidden" name="sucuriscan_wphardeningnonce" value="<?php echo wp_create_nonce('sucuriscan_wphardeningnonce'); ?>" />
|
1238 |
+
<input type="hidden" name="wpsucuri-doharden" value="wpsucuri-doharden" />
|
1239 |
+
<?php
|
1240 |
+
sucuriscan_harden_version();
|
1241 |
+
sucuriscan_cloudproxy_enabled();
|
1242 |
+
sucuri_harden_removegenerator();
|
1243 |
+
sucuriscan_harden_upload();
|
1244 |
+
sucuriscan_harden_wpcontent();
|
1245 |
+
sucuriscan_harden_wpincludes();
|
1246 |
+
sucuriscan_harden_phpversion();
|
1247 |
+
?>
|
1248 |
+
</form>
|
1249 |
+
|
1250 |
+
<p align="center">
|
1251 |
+
<strong>If you have any questions about these checks or this plugin, contact us at
|
1252 |
+
<a href="mailto:info@sucuri.net">info@sucuri.net</a> or visit <a href="http://sucuri.net">
|
1253 |
+
Sucuri Security</a></strong>
|
1254 |
+
</p>
|
1255 |
+
</div><!-- End poststuff -->
|
1256 |
+
</div><!-- End sucuriscan-maincontent -->
|
1257 |
+
</div><!-- End postbox-container -->
|
1258 |
+
|
1259 |
+
<?php echo sucuriscan_get_template('sidebar.html.tpl') ?>
|
1260 |
+
|
1261 |
+
</div><!-- End Wrap -->
|
1262 |
+
|
1263 |
+
<?php
|
1264 |
+
}
|
1265 |
+
|
1266 |
+
/**
|
1267 |
+
* Print the HTML code to show the title of a hardening option box.
|
1268 |
+
*
|
1269 |
+
* @param string $msg The title of the hardening option.
|
1270 |
+
* @return void
|
1271 |
+
*/
|
1272 |
+
function sucuriscan_wrapper_open($msg)
|
1273 |
+
{
|
1274 |
+
?>
|
1275 |
+
<div class="postbox">
|
1276 |
+
<h3><?php echo $msg; ?></h3>
|
1277 |
+
<div class="inside">
|
1278 |
+
<?php
|
1279 |
+
}
|
1280 |
+
|
1281 |
+
/**
|
1282 |
+
* Close the HTML tags of the containers opened with __ss_wraphardeningboxopen()
|
1283 |
+
*
|
1284 |
+
* @return void
|
1285 |
+
*/
|
1286 |
+
function sucuriscan_wrapper_close()
|
1287 |
+
{
|
1288 |
+
?>
|
1289 |
+
</div>
|
1290 |
+
</div>
|
1291 |
+
<?php
|
1292 |
+
}
|
1293 |
+
|
1294 |
+
/**
|
1295 |
+
* Print an error message in the interface.
|
1296 |
+
*
|
1297 |
+
* @param string $message The text string that will be shown inside the error box.
|
1298 |
+
* @return void
|
1299 |
+
*/
|
1300 |
+
function sucuriscan_harden_error($message)
|
1301 |
+
{
|
1302 |
+
return('<div id="message" class="error"><p>'.$message.'</p></div>');
|
1303 |
+
}
|
1304 |
+
|
1305 |
+
/**
|
1306 |
+
* Print a success message in the interface.
|
1307 |
+
*
|
1308 |
+
* @param string $message The text string that will be shown inside the success box.
|
1309 |
+
* @return void
|
1310 |
+
*/
|
1311 |
+
function sucuriscan_harden_ok($message)
|
1312 |
+
{
|
1313 |
+
return( '<div id="message" class="updated"><p>'.$message.'</p></div>');
|
1314 |
+
}
|
1315 |
+
|
1316 |
+
/**
|
1317 |
+
* Generate the HTML code necessary to show a form with the options to harden
|
1318 |
+
* a specific part of the Wordpress installation, if the Status variable is
|
1319 |
+
* set as a positive integer the button is shown as "unharden".
|
1320 |
+
*
|
1321 |
+
* @param integer $status Either one or zero representing the state of the hardening, one for secure, zero for insecure.
|
1322 |
+
* @param string $type Name of the hardening option, this will be used through out the form generation.
|
1323 |
+
* @param string $messageok Message that will be shown if the hardening was executed.
|
1324 |
+
* @param string $messagewarn Message that will be shown if the hardening is not executed.
|
1325 |
+
* @param string $desc Optional description of the hardening.
|
1326 |
+
* @param string $updatemsg Optional explanation of the hardening after the submission of the form.
|
1327 |
+
* @return void
|
1328 |
+
*/
|
1329 |
+
function sucuriscan_harden_status($status=0, $type='', $messageok='', $messagewarn='', $desc = NULL, $updatemsg = NULL){
|
1330 |
+
if($desc != NULL)
|
1331 |
+
{
|
1332 |
+
echo "<p>$desc</p>";
|
1333 |
+
}
|
1334 |
+
|
1335 |
+
if($status == 1)
|
1336 |
+
{
|
1337 |
+
echo '<h4>'.
|
1338 |
+
'<img style="position:relative;top:5px" height="22" width="22"'.
|
1339 |
+
'src="'.SUCURI_URL.'inc/images/ok.png" /> '.
|
1340 |
+
$messageok.'.</h4>';
|
1341 |
+
|
1342 |
+
if($updatemsg != NULL){ echo $updatemsg; }
|
1343 |
+
|
1344 |
+
if($type != NULL)
|
1345 |
+
{
|
1346 |
+
echo "<input type='submit' name='{$type}_unharden' value='Revert hardening' class='button-secondary' />";
|
1347 |
+
echo '<br /><br />';
|
1348 |
+
}
|
1349 |
+
}
|
1350 |
+
else
|
1351 |
+
{
|
1352 |
+
echo '<h4>'.
|
1353 |
+
'<img style="position:relative;top:5px" height="22" width="22"'.
|
1354 |
+
'src="'.SUCURI_URL.'inc/images/warn.png" /> '.
|
1355 |
+
$messagewarn. '.</h4>';
|
1356 |
+
|
1357 |
+
if($updatemsg != NULL){ echo $updatemsg; }
|
1358 |
+
|
1359 |
+
if($type != NULL)
|
1360 |
+
{
|
1361 |
+
echo '<input class="button-primary" type="submit" name="'.$type.'"
|
1362 |
+
value="Harden it!" />';
|
1363 |
+
}
|
1364 |
+
}
|
1365 |
+
}
|
1366 |
+
|
1367 |
+
/**
|
1368 |
+
* Check whether the version number of the Wordpress installed is the latest
|
1369 |
+
* version available officially.
|
1370 |
+
*
|
1371 |
+
* @return void
|
1372 |
+
*/
|
1373 |
+
function sucuriscan_harden_version()
|
1374 |
+
{
|
1375 |
+
global $wp_version;
|
1376 |
+
$cp = 0;
|
1377 |
+
$updates = get_core_updates();
|
1378 |
+
if (!is_array($updates))
|
1379 |
+
{
|
1380 |
+
$cp = 1;
|
1381 |
+
}
|
1382 |
+
else if(empty($updates))
|
1383 |
+
{
|
1384 |
+
$cp = 1;
|
1385 |
+
}
|
1386 |
+
else if($updates[0]->response == 'latest')
|
1387 |
+
{
|
1388 |
+
$cp = 1;
|
1389 |
+
}
|
1390 |
+
if(strcmp($wp_version, "3.7") < 0)
|
1391 |
+
{
|
1392 |
+
$cp = 0;
|
1393 |
+
}
|
1394 |
+
$wp_version = htmlspecialchars($wp_version);
|
1395 |
+
|
1396 |
+
|
1397 |
+
sucuriscan_wrapper_open("Verify WordPress Version");
|
1398 |
+
|
1399 |
+
|
1400 |
+
sucuriscan_harden_status($cp, NULL,
|
1401 |
+
"WordPress is updated", "WordPress is not updated",
|
1402 |
+
NULL);
|
1403 |
+
|
1404 |
+
if($cp == 0)
|
1405 |
+
{
|
1406 |
+
echo "<p>Your current version ($wp_version) is not current.</p><p><a class='button-primary' href='update-core.php'>Update now!</a></p>";
|
1407 |
+
}
|
1408 |
+
else
|
1409 |
+
{
|
1410 |
+
echo "<p>Your WordPress installation ($wp_version) is current.</p>";
|
1411 |
+
}
|
1412 |
+
sucuriscan_wrapper_close();
|
1413 |
+
}
|
1414 |
+
|
1415 |
+
/**
|
1416 |
+
* Notify the state of the hardening for the removal of the Generator tag in
|
1417 |
+
* HTML code printed by Wordpress to show the current version number of the
|
1418 |
+
* installation.
|
1419 |
+
*
|
1420 |
+
* @return void
|
1421 |
+
*/
|
1422 |
+
function sucuri_harden_removegenerator()
|
1423 |
+
{
|
1424 |
+
/* Enabled by default with this plugin. */
|
1425 |
+
$cp = 1;
|
1426 |
+
|
1427 |
+
sucuriscan_wrapper_open("Remove WordPress Version");
|
1428 |
+
|
1429 |
+
sucuriscan_harden_status($cp, NULL,
|
1430 |
+
"WordPress version properly hidden", NULL,
|
1431 |
+
"It checks if your WordPress version is being hidden".
|
1432 |
+
" from being displayed in the generator tag ".
|
1433 |
+
"(enabled by default with this plugin).");
|
1434 |
+
|
1435 |
+
sucuriscan_wrapper_close();
|
1436 |
+
}
|
1437 |
+
|
1438 |
+
/**
|
1439 |
+
* Check whether the Wordpress upload folder is protected or not.
|
1440 |
+
*
|
1441 |
+
* A htaccess file is placed in the upload folder denying the access to any php
|
1442 |
+
* file that could be uploaded through a vulnerability in a Plugin, Theme or
|
1443 |
+
* Wordpress itself.
|
1444 |
+
*
|
1445 |
+
* @return void
|
1446 |
+
*/
|
1447 |
+
function sucuriscan_harden_upload()
|
1448 |
+
{
|
1449 |
+
$cp = 1;
|
1450 |
+
$upmsg = NULL;
|
1451 |
+
$htaccess_upload = dirname(sucuriscan_dir_filepath())."/.htaccess";
|
1452 |
+
|
1453 |
+
if(!is_readable($htaccess_upload))
|
1454 |
+
{
|
1455 |
+
$cp = 0;
|
1456 |
+
}
|
1457 |
+
else
|
1458 |
+
{
|
1459 |
+
$cp = 0;
|
1460 |
+
$fcontent = file($htaccess_upload);
|
1461 |
+
foreach($fcontent as $fline)
|
1462 |
+
{
|
1463 |
+
if(strpos($fline, "deny from all") !== FALSE)
|
1464 |
+
{
|
1465 |
+
$cp = 1;
|
1466 |
+
break;
|
1467 |
+
}
|
1468 |
+
}
|
1469 |
+
}
|
1470 |
+
|
1471 |
+
if( isset($_POST['wpsucuri-doharden']) ){
|
1472 |
+
if( isset($_POST['sucuriscan_harden_upload']) && $cp == 0 )
|
1473 |
+
{
|
1474 |
+
if(@file_put_contents($htaccess_upload,
|
1475 |
+
"\n<Files *.php>\ndeny from all\n</Files>")===FALSE)
|
1476 |
+
{
|
1477 |
+
$upmsg = sucuriscan_harden_error("ERROR: Unable to create <code>.htaccess</code> file, folder destination is not writable.");
|
1478 |
+
}
|
1479 |
+
else
|
1480 |
+
{
|
1481 |
+
$upmsg = sucuriscan_harden_ok("COMPLETE: Upload directory successfully hardened");
|
1482 |
+
$cp = 1;
|
1483 |
+
}
|
1484 |
+
}
|
1485 |
+
|
1486 |
+
elseif( isset($_POST['sucuriscan_harden_upload_unharden']) ){
|
1487 |
+
$htaccess_upload_writable = ( file_exists($htaccess_upload) && is_writable($htaccess_upload) ) ? TRUE : FALSE;
|
1488 |
+
$htaccess_content = $htaccess_upload_writable ? file_get_contents($htaccess_upload) : '';
|
1489 |
+
|
1490 |
+
if( $htaccess_upload_writable ){
|
1491 |
+
$cp = 0;
|
1492 |
+
if( preg_match('/<Files \*\.php>\ndeny from all\n<\/Files>/', $htaccess_content, $match) ){
|
1493 |
+
$htaccess_content = str_replace("<Files *.php>\ndeny from all\n</Files>", '', $htaccess_content);
|
1494 |
+
@file_put_contents($htaccess_upload, $htaccess_content, LOCK_EX);
|
1495 |
+
}
|
1496 |
+
sucuriscan_admin_notice('updated', '<strong>OK.</strong> WP-Content Uploads directory protection reverted.');
|
1497 |
+
}else{
|
1498 |
+
$harden_process = '<strong>Error.</strong> The <code>wp-content/uploads/.htaccess</code> does
|
1499 |
+
not exists or is not writable, you will need to remove the following code manually there:
|
1500 |
+
<code><Files *.php>deny from all</Files></code>';
|
1501 |
+
sucuriscan_admin_notice('error', $harden_process);
|
1502 |
+
}
|
1503 |
+
}
|
1504 |
+
}
|
1505 |
+
|
1506 |
+
sucuriscan_wrapper_open("Protect Uploads Directory");
|
1507 |
+
sucuriscan_harden_status($cp, "sucuriscan_harden_upload",
|
1508 |
+
"Upload directory properly hardened",
|
1509 |
+
"Upload directory not hardened",
|
1510 |
+
"It checks if your upload directory allows PHP ".
|
1511 |
+
"execution or if it is browsable.", $upmsg);
|
1512 |
+
sucuriscan_wrapper_close();
|
1513 |
+
}
|
1514 |
+
|
1515 |
+
/**
|
1516 |
+
* Check whether the Wordpress content folder is protected or not.
|
1517 |
+
*
|
1518 |
+
* A htaccess file is placed in the content folder denying the access to any php
|
1519 |
+
* file that could be uploaded through a vulnerability in a Plugin, Theme or
|
1520 |
+
* Wordpress itself.
|
1521 |
+
*
|
1522 |
+
* @return void
|
1523 |
+
*/
|
1524 |
+
function sucuriscan_harden_wpcontent()
|
1525 |
+
{
|
1526 |
+
$cp = 1;
|
1527 |
+
$upmsg = NULL;
|
1528 |
+
$htaccess_upload = ABSPATH."/wp-content/.htaccess";
|
1529 |
+
|
1530 |
+
if(!is_readable($htaccess_upload))
|
1531 |
+
{
|
1532 |
+
$cp = 0;
|
1533 |
+
}
|
1534 |
+
else
|
1535 |
+
{
|
1536 |
+
$cp = 0;
|
1537 |
+
$fcontent = file($htaccess_upload);
|
1538 |
+
foreach($fcontent as $fline)
|
1539 |
+
{
|
1540 |
+
if(strpos($fline, "deny from all") !== FALSE)
|
1541 |
+
{
|
1542 |
+
$cp = 1;
|
1543 |
+
break;
|
1544 |
+
}
|
1545 |
+
}
|
1546 |
+
}
|
1547 |
+
|
1548 |
+
if( isset($_POST['wpsucuri-doharden']) ){
|
1549 |
+
if( isset($_POST['sucuriscan_harden_wpcontent']) && $cp == 0 )
|
1550 |
+
{
|
1551 |
+
if(@file_put_contents($htaccess_upload,
|
1552 |
+
"\n<Files *.php>\ndeny from all\n</Files>")===FALSE)
|
1553 |
+
{
|
1554 |
+
$upmsg = sucuriscan_harden_error("ERROR: Unable to create <code>.htaccess</code> file, folder destination is not writable.");
|
1555 |
+
}
|
1556 |
+
else
|
1557 |
+
{
|
1558 |
+
$upmsg = sucuriscan_harden_ok("COMPLETE: wp-content directory successfully hardened");
|
1559 |
+
$cp = 1;
|
1560 |
+
}
|
1561 |
+
}
|
1562 |
|
1563 |
+
elseif( isset($_POST['sucuriscan_harden_wpcontent_unharden']) ){
|
1564 |
+
$htaccess_upload_writable = ( file_exists($htaccess_upload) && is_writable($htaccess_upload) ) ? TRUE : FALSE;
|
1565 |
+
$htaccess_content = $htaccess_upload_writable ? file_get_contents($htaccess_upload) : '';
|
1566 |
|
1567 |
+
if( $htaccess_upload_writable ){
|
1568 |
+
$cp = 0;
|
1569 |
+
if( preg_match('/<Files \*\.php>\ndeny from all\n<\/Files>/', $htaccess_content, $match) ){
|
1570 |
+
$htaccess_content = str_replace("<Files *.php>\ndeny from all\n</Files>", '', $htaccess_content);
|
1571 |
+
@file_put_contents($htaccess_upload, $htaccess_content, LOCK_EX);
|
1572 |
+
}
|
1573 |
+
sucuriscan_admin_notice('updated', '<strong>OK.</strong> WP-Content directory protection reverted.');
|
1574 |
+
}else{
|
1575 |
+
$harden_process = '<strong>Error.</strong> The <code>wp-content/.htaccess</code> does
|
1576 |
+
not exists or is not writable, you will need to remove the following code manually there:
|
1577 |
+
<code><Files *.php>deny from all</Files></code>';
|
1578 |
+
sucuriscan_admin_notice('error', $harden_process);
|
1579 |
+
}
|
1580 |
}
|
1581 |
}
|
|
|
|
|
1582 |
|
1583 |
+
sucuriscan_wrapper_open("Restrict wp-content Access");
|
1584 |
+
sucuriscan_harden_status($cp, "sucuriscan_harden_wpcontent",
|
1585 |
+
"WP-content directory properly hardened",
|
1586 |
+
"WP-content directory not hardened",
|
1587 |
+
"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 ".
|
1588 |
+
"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);
|
1589 |
+
sucuriscan_wrapper_close();
|
1590 |
}
|
1591 |
|
1592 |
+
/**
|
1593 |
+
* Check whether the Wordpress includes folder is protected or not.
|
1594 |
+
*
|
1595 |
+
* A htaccess file is placed in the includes folder denying the access to any php
|
1596 |
+
* file that could be uploaded through a vulnerability in a Plugin, Theme or
|
1597 |
+
* Wordpress itself, there are some exceptions for some specific files that must
|
1598 |
+
* be available publicly.
|
1599 |
+
*
|
1600 |
+
* @return void
|
1601 |
+
*/
|
1602 |
+
function sucuriscan_harden_wpincludes()
|
1603 |
{
|
1604 |
+
$cp = 1;
|
1605 |
+
$upmsg = NULL;
|
1606 |
+
$htaccess_upload = ABSPATH."/wp-includes/.htaccess";
|
1607 |
+
|
1608 |
+
if(!is_readable($htaccess_upload))
|
1609 |
+
{
|
1610 |
+
$cp = 0;
|
1611 |
+
}
|
1612 |
+
else
|
1613 |
+
{
|
1614 |
+
$cp = 0;
|
1615 |
+
$fcontent = file($htaccess_upload);
|
1616 |
+
foreach($fcontent as $fline)
|
1617 |
+
{
|
1618 |
+
if(strpos($fline, "deny from all") !== FALSE)
|
1619 |
+
{
|
1620 |
+
$cp = 1;
|
1621 |
+
break;
|
1622 |
}
|
|
|
1623 |
}
|
1624 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1625 |
|
1626 |
+
if( isset($_POST['wpsucuri-doharden']) ){
|
1627 |
+
if( isset($_POST['sucuriscan_harden_wpincludes']) && $cp == 0 )
|
1628 |
+
{
|
1629 |
+
if(@file_put_contents($htaccess_upload,
|
1630 |
+
"\n<Files *.php>\ndeny from all\n</Files>\n<Files wp-tinymce.php>\nallow from all\n</Files>\n")===FALSE)
|
1631 |
+
{
|
1632 |
+
$upmsg = sucuriscan_harden_error("ERROR: Unable to create <code>.htaccess</code> file, folder destination is not writable.");
|
1633 |
+
}
|
1634 |
+
else
|
1635 |
+
{
|
1636 |
+
$upmsg = sucuriscan_harden_ok("COMPLETE: wp-includes directory successfully hardened.");
|
1637 |
+
$cp = 1;
|
1638 |
+
}
|
1639 |
+
}
|
1640 |
|
1641 |
+
elseif( isset($_POST['sucuriscan_harden_wpincludes_unharden']) ){
|
1642 |
+
$htaccess_upload_writable = ( file_exists($htaccess_upload) && is_writable($htaccess_upload) ) ? TRUE : FALSE;
|
1643 |
+
$htaccess_content = $htaccess_upload_writable ? file_get_contents($htaccess_upload) : '';
|
|
|
|
|
|
|
1644 |
|
1645 |
+
if( $htaccess_upload_writable ){
|
1646 |
+
$cp = 0;
|
1647 |
+
if( preg_match_all('/<Files (\*|wp-tinymce|ms-files)\.php>\n(deny|allow) from all\n<\/Files>/', $htaccess_content, $match) ){
|
1648 |
+
foreach($match[0] as $restriction){
|
1649 |
+
$htaccess_content = str_replace($restriction, '', $htaccess_content);
|
1650 |
+
}
|
1651 |
+
@file_put_contents($htaccess_upload, $htaccess_content, LOCK_EX);
|
1652 |
}
|
1653 |
+
sucuriscan_admin_notice('updated', '<strong>OK.</strong> WP-Includes directory protection reverted.');
|
1654 |
+
}else{
|
1655 |
+
$harden_process = '<strong>Error.</strong> The <code>wp-includes/.htaccess</code> does
|
1656 |
+
not exists or is not writable, you will need to remove the following code manually there:
|
1657 |
+
<code><Files *.php>deny from all</Files></code>';
|
1658 |
+
sucuriscan_admin_notice('error', $harden_process);
|
1659 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1660 |
}
|
|
|
1661 |
}
|
1662 |
+
|
1663 |
+
sucuriscan_wrapper_open("Restrict wp-includes Access");
|
1664 |
+
sucuriscan_harden_status($cp, "sucuriscan_harden_wpincludes",
|
1665 |
+
"wp-includes directory properly hardened",
|
1666 |
+
"wp-includes directory not hardened",
|
1667 |
+
"This option blocks direct PHP access to any file inside wp-includes. ", $upmsg);
|
1668 |
+
sucuriscan_wrapper_close();
|
1669 |
}
|
1670 |
|
1671 |
+
/**
|
1672 |
+
* Check the version number of the PHP interpreter set to work with the site,
|
1673 |
+
* is considered that old versions of the PHP interpreter are insecure.
|
1674 |
+
*
|
1675 |
+
* @return void
|
1676 |
+
*/
|
1677 |
+
function sucuriscan_harden_phpversion()
|
1678 |
{
|
1679 |
+
$phpv = phpversion();
|
|
|
|
|
|
|
|
|
|
|
1680 |
|
1681 |
+
if(strncmp($phpv, "5.", 2) < 0)
|
1682 |
+
{
|
1683 |
+
$cp = 0;
|
1684 |
+
}
|
1685 |
+
else
|
1686 |
+
{
|
1687 |
+
$cp = 1;
|
1688 |
+
}
|
1689 |
|
1690 |
+
sucuriscan_wrapper_open("Verify PHP Version");
|
1691 |
+
sucuriscan_harden_status($cp, NULL,
|
1692 |
+
"Using an updated version of PHP (v $phpv)",
|
1693 |
+
"The version of PHP you are using ($phpv) is not current, not recommended, and/or not supported",
|
1694 |
+
"This checks if you have the latest version of PHP installed.", NULL);
|
1695 |
+
sucuriscan_wrapper_close();
|
1696 |
+
}
|
1697 |
|
1698 |
+
/**
|
1699 |
+
* Check whether the site is behind a secure proxy server or not.
|
1700 |
+
*
|
1701 |
+
* @return void
|
1702 |
+
*/
|
1703 |
+
function sucuriscan_cloudproxy_enabled(){
|
1704 |
+
$enabled = sucuriscan_is_behind_cloudproxy();
|
1705 |
+
|
1706 |
+
sucuriscan_wrapper_open('Verify if your site is protected by a Web Firewall');
|
1707 |
+
sucuriscan_harden_status(
|
1708 |
+
$enabled, NULL,
|
1709 |
+
'Your website is protected by a Website Firewall (WAF)',
|
1710 |
+
'Your website is not protected by a Website Firewall (WAF)',
|
1711 |
+
'A WAF is a protection layer for your web site, blocking all sort of attacks (brute force attempts, DDoS, SQL injections, etc) and helping it remain
|
1712 |
+
malware and blacklist free. This test checks if your site is using <a href="http://cloudproxy.sucuri.net/" target="_blank">Sucuri\'s CloudProxy WAF</a> to protect your site. ',
|
1713 |
+
NULL
|
1714 |
+
);
|
1715 |
+
if( $enabled!==TRUE ){
|
1716 |
+
echo '<a href="http://cloudproxy.sucuri.net" target="_blank" class="button button-primary">Harden it!</a>';
|
1717 |
}
|
1718 |
+
sucuriscan_wrapper_close();
|
1719 |
}
|
1720 |
|
1721 |
+
/**
|
1722 |
+
* Generate and print the HTML code for the Post-Hack page.
|
1723 |
+
*
|
1724 |
+
* @return void
|
1725 |
+
*/
|
1726 |
function sucuriscan_posthack_page()
|
1727 |
{
|
1728 |
if( !current_user_can('manage_options') )
|
1824 |
echo sucuriscan_get_template('posthack.html.tpl', $template_variables);
|
1825 |
}
|
1826 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1827 |
/**
|
1828 |
+
* Generate and print the HTML code for the Last Logins page.
|
1829 |
+
*
|
1830 |
+
* This page will contains information of all the logins of the registered users.
|
1831 |
+
*
|
1832 |
+
* @return void
|
1833 |
*/
|
|
|
1834 |
function sucuriscan_lastlogins_page()
|
1835 |
{
|
1836 |
if( !current_user_can('manage_options') )
|
1871 |
echo sucuriscan_get_template('lastlogins.html.tpl', $template_variables);
|
1872 |
}
|
1873 |
|
1874 |
+
/**
|
1875 |
+
* Get the filepath where the information of the last logins of all users is stored.
|
1876 |
+
*
|
1877 |
+
* @return string Absolute filepath where the user's last login information is stored.
|
1878 |
+
*/
|
1879 |
function sucuriscan_lastlogins_datastore_filepath(){
|
1880 |
$plugin_upload_folder = sucuriscan_dir_filepath();
|
1881 |
$datastore_filepath = rtrim($plugin_upload_folder,'/').'/sucuri-lastlogins.php';
|
1882 |
return $datastore_filepath;
|
1883 |
}
|
1884 |
|
1885 |
+
/**
|
1886 |
+
* Check whether the user's last login datastore file exists or not, if not then
|
1887 |
+
* we try to create the file and check again the success of the operation.
|
1888 |
+
*
|
1889 |
+
* @return string Absolute filepath where the user's last login information is stored.
|
1890 |
+
*/
|
1891 |
function sucuriscan_lastlogins_datastore_exists(){
|
1892 |
$datastore_filepath = sucuriscan_lastlogins_datastore_filepath();
|
1893 |
|
1900 |
return file_exists($datastore_filepath) ? $datastore_filepath : FALSE;
|
1901 |
}
|
1902 |
|
1903 |
+
/**
|
1904 |
+
* Check whether the user's last login datastore file is writable or not, if not
|
1905 |
+
* we try to set the right permissions and check again the success of the operation.
|
1906 |
+
*
|
1907 |
+
* @return boolean Whether the user's last login datastore file is writable or not.
|
1908 |
+
*/
|
1909 |
function sucuriscan_lastlogins_datastore_is_writable(){
|
1910 |
$datastore_filepath = sucuriscan_lastlogins_datastore_exists();
|
1911 |
if($datastore_filepath){
|
1917 |
return FALSE;
|
1918 |
}
|
1919 |
|
1920 |
+
/**
|
1921 |
+
* Check whether the user's last login datastore file is readable or not, if not
|
1922 |
+
* we try to set the right permissions and check again the success of the operation.
|
1923 |
+
*
|
1924 |
+
* @return boolean Whether the user's last login datastore file is readable or not.
|
1925 |
+
*/
|
1926 |
function sucuriscan_lastlogins_datastore_is_readable(){
|
1927 |
$datastore_filepath = sucuriscan_lastlogins_datastore_exists();
|
1928 |
if( $datastore_filepath && is_readable($datastore_filepath) ){
|
1932 |
}
|
1933 |
|
1934 |
if( !function_exists('sucuri_set_lastlogin') ){
|
1935 |
+
/**
|
1936 |
+
* Add a new user session to the list of last user logins.
|
1937 |
+
*
|
1938 |
+
* @param string $user_login The name of the user account involved in the operation.
|
1939 |
+
* @return void
|
1940 |
+
*/
|
1941 |
function sucuriscan_set_lastlogin($user_login=''){
|
1942 |
$datastore_filepath = sucuriscan_lastlogins_datastore_is_writable();
|
1943 |
|
1959 |
add_action('wp_login', 'sucuriscan_set_lastlogin', 50);
|
1960 |
}
|
1961 |
|
1962 |
+
/**
|
1963 |
+
* Retrieve the list of all the user logins from the datastore file.
|
1964 |
+
*
|
1965 |
+
* The results of this operation can be filtered by specific user identifiers,
|
1966 |
+
* or limiting the quantity of entries.
|
1967 |
+
*
|
1968 |
+
* @param integer $limit How many entries will be returned from the operation.
|
1969 |
+
* @param integer $user_id Optional user identifier to filter the results.
|
1970 |
+
* @return array The list of all the user logins through the time until now.
|
1971 |
+
*/
|
1972 |
function sucuriscan_get_logins($limit=10, $user_id=0){
|
1973 |
$lastlogins = array();
|
1974 |
$datastore_filepath = sucuriscan_lastlogins_datastore_is_readable();
|
2011 |
}
|
2012 |
|
2013 |
if( !function_exists('sucuri_login_redirect') ){
|
2014 |
+
/**
|
2015 |
+
* Hook for the wp-login action to redirect the user to a specific URL after
|
2016 |
+
* his successfully login to the administrator interface.
|
2017 |
+
*
|
2018 |
+
* @param string $redirect_to URL where the browser must be originally redirected to, set by Wordpress itself.
|
2019 |
+
* @param object $request Optional parameter set by Wordpress itself through the event triggered.
|
2020 |
+
* @param boolean $user Wordpress user object with the information of the account involved in the operation.
|
2021 |
+
* @return string URL where the browser must be redirected to.
|
2022 |
+
*/
|
2023 |
function sucuriscan_login_redirect($redirect_to='', $request=NULL, $user=FALSE){
|
2024 |
$login_url = !empty($redirect_to) ? $redirect_to : admin_url();
|
2025 |
if( $user instanceof WP_User && $user->ID ){
|
2031 |
}
|
2032 |
|
2033 |
if( !function_exists('sucuri_get_user_lastlogin') ){
|
2034 |
+
/**
|
2035 |
+
* Display the last user login at the top of the admin interface.
|
2036 |
+
*
|
2037 |
+
* @return void
|
2038 |
+
*/
|
2039 |
function sucuriscan_get_user_lastlogin(){
|
2040 |
if( isset($_GET['sucuriscan_lastlogin_message']) && current_user_can('manage_options') ){
|
2041 |
$current_user = wp_get_current_user();
|
2055 |
add_action('admin_notices', 'sucuriscan_get_user_lastlogin');
|
2056 |
}
|
2057 |
|
|
|
2058 |
/**
|
2059 |
+
* Generate and print the HTML code for the InfoSys page.
|
2060 |
+
*
|
2061 |
+
* This page will contains information of the system where the site is hosted,
|
2062 |
+
* also information about users in session, htaccess rules and configuration
|
2063 |
+
* options.
|
2064 |
+
*
|
2065 |
+
* @return void
|
2066 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2067 |
function sucuriscan_infosys_page(){
|
2068 |
if( !current_user_can('manage_options') )
|
2069 |
{
|
2078 |
);
|
2079 |
|
2080 |
$template_variables['LoggedInUsers'] = sucuriscan_infosys_loggedin();
|
2081 |
+
$template_variables['Cronjobs'] = sucuriscan_show_cronjobs();
|
2082 |
$template_variables['HTAccessIntegrity'] = sucuriscan_infosys_htaccess();
|
2083 |
$template_variables['WordpressConfig'] = sucuriscan_infosys_wpconfig();
|
2084 |
|
2085 |
echo sucuriscan_get_template('infosys.html.tpl', $template_variables);
|
2086 |
}
|
2087 |
|
2088 |
+
/**
|
2089 |
+
* Find the main htaccess file for the site and check whether the rules of the
|
2090 |
+
* main htaccess file of the site are the default rules generated by Wordpress.
|
2091 |
+
*
|
2092 |
+
* @return string The HTML code displaying the information about the HTAccess rules.
|
2093 |
+
*/
|
2094 |
function sucuriscan_infosys_htaccess(){
|
2095 |
$htaccess_path = sucuriscan_get_htaccess_path();
|
2096 |
+
|
2097 |
$template_variables = array(
|
2098 |
'HTAccess.Content' => '',
|
2099 |
'HTAccess.Message' => '',
|
2104 |
|
2105 |
if( $htaccess_path ){
|
2106 |
$htaccess_rules = file_get_contents($htaccess_path);
|
2107 |
+
|
2108 |
+
$template_variables['HTAccess.MessageType'] = 'updated';
|
2109 |
+
$template_variables['HTAccess.MessageVisible'] = 'visible';
|
2110 |
$template_variables['HTAccess.TextareaVisible'] = 'visible';
|
2111 |
$template_variables['HTAccess.Content'] = $htaccess_rules;
|
2112 |
+
$template_variables['HTAccess.Message'] .= 'HTAccess file found in this path <code>'.$htaccess_path.'</code>';
|
2113 |
|
2114 |
+
if( empty($htaccess_rules) ){
|
2115 |
+
$template_variables['HTAccess.TextareaVisible'] = 'hidden';
|
2116 |
+
$template_variables['HTAccess.Message'] .= '</p><p>The HTAccess file found is completely empty.';
|
2117 |
+
}
|
2118 |
if( sucuriscan_htaccess_is_standard($htaccess_rules) ){
|
2119 |
+
$template_variables['HTAccess.Message'] .= '</p><p>
|
2120 |
The main <code>.htaccess</code> file in your site has the standard rules for a WordPress installation. You can customize it to improve the
|
2121 |
performance and change the behaviour of the redirections for pages and posts in your site. To get more information visit the official documentation at
|
2122 |
<a href="http://codex.wordpress.org/Using_Permalinks#Creating_and_editing_.28.htaccess.29" target="_blank">Codex WordPrexx - Creating and editing (.htaccess)</a>';
|
|
|
|
|
2123 |
}
|
|
|
2124 |
}else{
|
2125 |
$template_variables['HTAccess.Message'] = 'Your website does not contains a <code>.htaccess</code> file or it was not found in the default location.';
|
2126 |
$template_variables['HTAccess.MessageType'] = 'error';
|
2130 |
return sucuriscan_get_template('infosys-htaccess.html.tpl', $template_variables);
|
2131 |
}
|
2132 |
|
2133 |
+
/**
|
2134 |
+
* Check whether the rules in a htaccess file are the default options generated
|
2135 |
+
* by Wordpress or if the file has custom options added by other Plugins.
|
2136 |
+
*
|
2137 |
+
* @param string $rules Optional parameter containing a text string with the content of the main htaccess file.
|
2138 |
+
* @return boolean Either TRUE or FALSE if the rules found in the htaccess file specified are the default ones or not.
|
2139 |
+
*/
|
2140 |
function sucuriscan_htaccess_is_standard($rules=FALSE){
|
2141 |
if( $rules===FALSE ){
|
2142 |
$htaccess_path = sucuriscan_get_htaccess_path();
|
2175 |
return FALSE;
|
2176 |
}
|
2177 |
|
2178 |
+
/**
|
2179 |
+
* Retrieve all the constants and variables with their respective values defined
|
2180 |
+
* in the Wordpress configuration file, only the database password constant is
|
2181 |
+
* omitted for security reasons.
|
2182 |
+
*
|
2183 |
+
* @return string The HTML code displaying the constants and variables found in the wp-config file.
|
2184 |
+
*/
|
2185 |
function sucuriscan_infosys_wpconfig(){
|
2186 |
$template_variables = array(
|
2187 |
'WordpressConfig.Rules' => '',
|
2188 |
'WordpressConfig.Total' => 0,
|
2189 |
'WordpressConfig.Content' => '',
|
2190 |
);
|
2191 |
+
$ignore_wp_rules = array('DB_PASSWORD');
|
2192 |
|
2193 |
$wp_config_path = sucuriscan_get_wpconfig_path();
|
2194 |
if( $wp_config_path ){
|
2204 |
// Ignore useless lines and append to the clean string the important lines.
|
2205 |
if( preg_match('/^define\(/', $line) ){
|
2206 |
$line = str_replace('define(', '', $line);
|
2207 |
+
$line = preg_replace('/\);.*/', '', $line);
|
2208 |
$line_parts = explode(',', $line, 2);
|
2209 |
}
|
2210 |
else if( preg_match('/^\$[a-zA-Z_]+/', $line) ){
|
2230 |
if( $i==0 ){ $key_name = $line_part; }
|
2231 |
if( $i==1 ){ $key_value = $line_part; }
|
2232 |
}
|
2233 |
+
|
2234 |
+
if( !in_array($key_name, $ignore_wp_rules) ){
|
2235 |
+
$wp_config_rules[$key_name] = $key_value;
|
2236 |
+
}
|
2237 |
}
|
2238 |
}
|
2239 |
|
2250 |
return sucuriscan_get_template('infosys-wpconfig.html.tpl', $template_variables);
|
2251 |
}
|
2252 |
|
2253 |
+
/**
|
2254 |
+
* Print a list of all the registered users that are currently in session.
|
2255 |
+
*
|
2256 |
+
* @return string The HTML code displaying a list of all the users logged in at the moment.
|
2257 |
+
*/
|
2258 |
function sucuriscan_infosys_loggedin(){
|
2259 |
// Get user logged in list.
|
2260 |
$template_variables = array(
|
2262 |
'LoggedInUsers.Total' => 0,
|
2263 |
);
|
2264 |
|
2265 |
+
$logged_in_users = sucuriscan_get_online_users(TRUE);
|
2266 |
if( is_array($logged_in_users) && !empty($logged_in_users) ){
|
2267 |
$template_variables['LoggedInUsers.Total'] = count($logged_in_users);
|
2268 |
|
2285 |
return sucuriscan_get_template('infosys-loggedin.html.tpl', $template_variables);
|
2286 |
}
|
2287 |
|
2288 |
+
/**
|
2289 |
+
* Get a list of all the registered users that are currently in session.
|
2290 |
+
*
|
2291 |
+
* @param boolean $add_current_user Whether the current user should be added to the list or not.
|
2292 |
+
* @return array List of registered users currently in session.
|
2293 |
+
*/
|
2294 |
+
function sucuriscan_get_online_users($add_current_user=FALSE){
|
2295 |
+
$users = array();
|
2296 |
|
|
|
2297 |
if( sucuriscan_is_multisite() ){
|
2298 |
+
$users = get_site_transient('online_users');
|
2299 |
}else{
|
2300 |
+
$users = get_transient('online_users');
|
2301 |
+
}
|
2302 |
+
|
2303 |
+
// If not online users but current user is logged in, add it to the list.
|
2304 |
+
if( empty($users) && $add_current_user ){
|
2305 |
+
$current_user = wp_get_current_user();
|
2306 |
+
if( $current_user->ID > 0 ){
|
2307 |
+
sucuriscan_set_online_user($current_user->user_login, $current_user);
|
2308 |
+
return sucuriscan_get_online_users();
|
2309 |
+
}
|
2310 |
}
|
|
|
2311 |
|
2312 |
+
return $users;
|
2313 |
+
}
|
2314 |
|
2315 |
+
/**
|
2316 |
+
* Update the list of the registered users currently in session.
|
2317 |
+
*
|
2318 |
+
* Useful when you are removing users and need the list of the remaining users.
|
2319 |
+
*
|
2320 |
+
* @param array $logged_in_users List of registered users currently in session.
|
2321 |
+
* @return boolean Either TRUE or FALSE representing the success or fail of the operation.
|
2322 |
+
*/
|
2323 |
function sucuriscan_save_online_users($logged_in_users=array()){
|
2324 |
$expiration = 30 * 60;
|
2325 |
if( sucuriscan_is_multisite() ){
|
2329 |
}
|
2330 |
}
|
2331 |
|
|
|
2332 |
if( !function_exists('sucuriscan_unset_online_user_on_logout') ){
|
2333 |
+
/**
|
2334 |
+
* Remove a logged in user from the list of registered users in session when
|
2335 |
+
* the logout page is requested.
|
2336 |
+
*
|
2337 |
+
* @return void
|
2338 |
+
*/
|
2339 |
function sucuriscan_unset_online_user_on_logout(){
|
2340 |
$current_user = wp_get_current_user();
|
2341 |
$user_id = $current_user->ID;
|
2347 |
add_action('wp_logout', 'sucuriscan_unset_online_user_on_logout');
|
2348 |
}
|
2349 |
|
2350 |
+
/**
|
2351 |
+
* Remove a logged in user from the list of registered users in session using
|
2352 |
+
* the user identifier and the ip address of the last computer used to login.
|
2353 |
+
*
|
2354 |
+
* @param integer $user_id User identifier of the account that will be logged out.
|
2355 |
+
* @param integer $remote_addr IP address of the computer where the user logged in.
|
2356 |
+
* @return boolean Either TRUE or FALSE representing the success or fail of the operation.
|
2357 |
+
*/
|
2358 |
function sucuriscan_unset_online_user($user_id=0, $remote_addr=0){
|
2359 |
$logged_in_users = sucuriscan_get_online_users();
|
2360 |
|
2374 |
return sucuriscan_save_online_users($logged_in_users);
|
2375 |
}
|
2376 |
|
|
|
2377 |
if( !function_exists('sucuriscan_set_online_user') ){
|
2378 |
+
/**
|
2379 |
+
* Add an user account to the list of registered users in session.
|
2380 |
+
*
|
2381 |
+
* @param string $user_login The name of the user account that just logged in the site.
|
2382 |
+
* @param boolean $user The Wordpress object containing all the information associated to the user.
|
2383 |
+
* @return void
|
2384 |
+
*/
|
2385 |
function sucuriscan_set_online_user($user_login='', $user=FALSE){
|
2386 |
if( $user ){
|
2387 |
// Get logged in user information.
|
2442 |
add_action('wp_login', 'sucuriscan_set_online_user', 10, 2);
|
2443 |
}
|
2444 |
|
2445 |
+
/**
|
2446 |
+
* Retrieve a list with the scheduled tasks configured for the site.
|
2447 |
+
*
|
2448 |
+
* @return array A list of pseudo-variables and values that will replace them in the HTML template.
|
2449 |
+
*/
|
2450 |
+
function sucuriscan_show_cronjobs(){
|
2451 |
+
$template_variables = array(
|
2452 |
+
'Cronjobs.List' => '',
|
2453 |
+
'Cronjobs.Total' => 0,
|
2454 |
+
);
|
2455 |
+
|
2456 |
+
$cronjobs = _get_cron_array();
|
2457 |
+
$schedules = wp_get_schedules();
|
2458 |
+
$date_format = _x('M j, Y - H:i', 'Publish box date format', 'cron-view' );
|
2459 |
+
|
2460 |
+
foreach( $cronjobs as $timestamp=>$cronhooks ){
|
2461 |
+
foreach( (array)$cronhooks as $hook=>$events ){
|
2462 |
+
foreach( (array)$events as $key=>$event ){
|
2463 |
+
$cronjob_snippet = '';
|
2464 |
+
$template_variables['Cronjobs.Total'] += 1;
|
2465 |
+
$template_variables['Cronjobs.List'] .= sucuriscan_get_template('infosys-cronjobs.snippet.tpl', array(
|
2466 |
+
'Cronjob.Task' => ucwords(str_replace('_',chr(32),$hook)),
|
2467 |
+
'Cronjob.Schedule' => $event['schedule'],
|
2468 |
+
'Cronjob.Nexttime' => date_i18n($date_format, $timestamp),
|
2469 |
+
'Cronjob.Hook' => $hook,
|
2470 |
+
'Cronjob.Arguments' => implode(', ', $event['args'])
|
2471 |
+
));
|
2472 |
+
}
|
2473 |
+
}
|
2474 |
+
}
|
2475 |
+
|
2476 |
+
return sucuriscan_get_template('infosys-cronjobs.html.tpl', $template_variables);
|
2477 |
+
}
|
2478 |
+
|
2479 |
+
|
2480 |
+
/**
|
2481 |
+
* Print the HTML code for the plugin about page with information of the plugin,
|
2482 |
+
* the scheduled tasks, and some settings from the PHP environment and server.
|
2483 |
+
*
|
2484 |
+
* @return void
|
2485 |
+
*/
|
2486 |
+
function sucuriscan_about_page()
|
2487 |
+
{
|
2488 |
+
if( !current_user_can('manage_options') )
|
2489 |
+
{
|
2490 |
+
wp_die(__('You do not have sufficient permissions to access this page: Sucuri Last-Logins') );
|
2491 |
+
}
|
2492 |
+
|
2493 |
+
// Page pseudo-variables initialization.
|
2494 |
+
$template_variables = array(
|
2495 |
+
'SucuriURL'=>SUCURI_URL,
|
2496 |
+
'SucuriWPSidebar'=>sucuriscan_wp_sidebar_gen(),
|
2497 |
+
'CurrentURL'=>site_url().'/wp-admin/admin.php?page='.$_GET['page'],
|
2498 |
+
'SettingsDisplay'=>'hidden'
|
2499 |
+
);
|
2500 |
+
|
2501 |
+
$template_variables = sucuriscan_about_information($template_variables);
|
2502 |
+
|
2503 |
+
echo sucuriscan_get_template('about.html.tpl', $template_variables);
|
2504 |
+
}
|
2505 |
+
|
2506 |
+
/**
|
2507 |
+
* Gather information from the server, database engine and PHP interpreter.
|
2508 |
+
*
|
2509 |
+
* @param array $template_variables The hash for the template system, keys are pseudo-variables.
|
2510 |
+
* @return array A list of pseudo-variables and values that will replace them in the HTML template.
|
2511 |
+
*/
|
2512 |
+
function sucuriscan_about_information($template_variables=array())
|
2513 |
+
{
|
2514 |
+
global $wpdb;
|
2515 |
+
|
2516 |
+
if( current_user_can('manage_options') ){
|
2517 |
+
$memory_usage = function_exists('memory_get_usage') ? round(memory_get_usage()/1024/1024,2).' MB' : 'N/A';
|
2518 |
+
$mysql_version = $wpdb->get_var('SELECT VERSION() AS version');
|
2519 |
+
$mysql_info = $wpdb->get_results('SHOW VARIABLES LIKE "sql_mode"');
|
2520 |
+
$sql_mode = ( is_array($mysql_info) && !empty($mysql_info[0]->Value) ) ? $mysql_info[0]->Value : 'Not set';
|
2521 |
+
$plugin_runtime_filepath = sucuriscan_dir_filepath('.runtime');
|
2522 |
+
$plugin_runtime_datetime = file_exists($plugin_runtime_filepath) ? date('r',filemtime($plugin_runtime_filepath)) : 'N/A';
|
2523 |
+
|
2524 |
+
$template_variables = array_merge($template_variables, array(
|
2525 |
+
'SettingsDisplay'=>'block',
|
2526 |
+
'PluginVersion'=>SUCURISCAN_VERSION,
|
2527 |
+
'PluginForceUpdate'=>admin_url('admin.php?page=sucurisec_settings&sucuri_force_update=1'),
|
2528 |
+
'PluginMD5'=>md5_file(SUCURISCAN_PLUGIN_FILEPATH),
|
2529 |
+
'PluginRuntimeDatetime'=>$plugin_runtime_datetime,
|
2530 |
+
'OperatingSystem'=>sprintf('%s (%d Bit)', PHP_OS, PHP_INT_SIZE*8),
|
2531 |
+
'Server'=>isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'Unknown',
|
2532 |
+
'MemoryUsage'=>$memory_usage,
|
2533 |
+
'MySQLVersion'=>$mysql_version,
|
2534 |
+
'SQLMode'=>$sql_mode,
|
2535 |
+
'PHPVersion'=>PHP_VERSION,
|
2536 |
+
));
|
2537 |
+
|
2538 |
+
foreach(array(
|
2539 |
+
'safe_mode',
|
2540 |
+
'allow_url_fopen',
|
2541 |
+
'memory_limit',
|
2542 |
+
'upload_max_filesize',
|
2543 |
+
'post_max_size',
|
2544 |
+
'max_execution_time',
|
2545 |
+
'max_input_time',
|
2546 |
+
) as $php_flag){
|
2547 |
+
$php_flag_name = ucwords(str_replace('_', chr(32), $php_flag) );
|
2548 |
+
$tpl_varname = str_replace(chr(32), '', $php_flag_name);
|
2549 |
+
$php_flag_value = ini_get($php_flag);
|
2550 |
+
$template_variables[$tpl_varname] = $php_flag_value ? $php_flag_value : 'N/A';
|
2551 |
+
}
|
2552 |
+
}
|
2553 |
+
|
2554 |
+
return $template_variables;
|
2555 |
+
}
|
2556 |
+
|
sucuriscan_core_integrity.php
DELETED
@@ -1,152 +0,0 @@
|
|
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, $stitle, $description){ ?>
|
16 |
-
<div class="postbox">
|
17 |
-
<div class="inside">
|
18 |
-
<form method="post">
|
19 |
-
<input type="hidden" name="<?php echo $function_name; ?>nonce" value="<?php echo wp_create_nonce($function_name.'nonce'); ?>" />
|
20 |
-
<input type="hidden" name="<?php echo $function_name; ?>" value="1" />
|
21 |
-
<h4><?php echo $stitle; ?></h4>
|
22 |
-
<p><?php echo $description; ?></p>
|
23 |
-
<input class="button-primary" type="submit" name="<?php echo $function_name; ?>" value="Check" />
|
24 |
-
</form>
|
25 |
-
<br />
|
26 |
-
<?php
|
27 |
-
if (isset($_POST[$function_name.'nonce']) && isset($_POST[$function_name])) {
|
28 |
-
if( function_exists($function_name) ){
|
29 |
-
$function_name();
|
30 |
-
}
|
31 |
-
}
|
32 |
-
?>
|
33 |
-
</div>
|
34 |
-
</div>
|
35 |
-
<?php }
|
36 |
-
|
37 |
-
function sucuriscan_core_integrity_wp_content_wrapper(){ ?>
|
38 |
-
<div class="postbox">
|
39 |
-
<h3>Latest modified files</h3>
|
40 |
-
<div class="inside">
|
41 |
-
<form method="post">
|
42 |
-
<input type="hidden" name="sucuriwp_content_checknonce" value="<?php echo wp_create_nonce('sucuriwp_content_checknonce'); ?>" />
|
43 |
-
<input type="hidden" name="sucuriwp_content_check" value="sucuriwp_content_check" />
|
44 |
-
<p>
|
45 |
-
This test will list all files inside wp-content that have been modified in the past
|
46 |
-
<select name="sucuriwp_content_check_back">
|
47 |
-
<?php foreach(array( 1,3,7,30 ) as $days): ?>
|
48 |
-
<?php $selected =
|
49 |
-
( isset($_POST['sucuriwp_content_check_back']) && $_POST['sucuriwp_content_check_back']==$days )
|
50 |
-
? 'selected="selected"' : ''; ?>
|
51 |
-
<option value="<?php echo $days; ?>" <?php echo $selected; ?>><?php echo $days; ?></option>
|
52 |
-
<?php endforeach; ?>
|
53 |
-
</select> days. (select the number of days first)
|
54 |
-
</p>
|
55 |
-
<input class="button-primary" type="submit" name="sucuriwp_content_check" value="Check">
|
56 |
-
</form>
|
57 |
-
|
58 |
-
<?php if (
|
59 |
-
isset($_POST['sucuriwp_content_checknonce'])
|
60 |
-
// && wp_verify_nonce($_POST['sucuriwp_content_checknonce'], 'sucuriwp_content_checknonce')
|
61 |
-
&& isset($_POST['sucuriwp_content_check'])
|
62 |
-
): ?>
|
63 |
-
<br />
|
64 |
-
<table class="wp-list-table widefat sucuriscan-lastmodified">
|
65 |
-
<thead>
|
66 |
-
<tr>
|
67 |
-
<th colspan="2">wp_content latest modified files</th>
|
68 |
-
</tr>
|
69 |
-
<tr>
|
70 |
-
<th class="manage-column">Filepath</th>
|
71 |
-
<th class="manage-column">Modification date/time</th>
|
72 |
-
</tr>
|
73 |
-
</thead>
|
74 |
-
<tbody>
|
75 |
-
<?php
|
76 |
-
$wp_content_hashes = read_dir_r(ABSPATH.'wp-content', true);
|
77 |
-
$days = htmlspecialchars(trim((int)$_POST['sucuriwp_content_check_back']));
|
78 |
-
$back_days = current_time( 'timestamp' ) - ( $days * 86400);
|
79 |
-
|
80 |
-
foreach ( $wp_content_hashes as $key => $value) {
|
81 |
-
if ($value['time'] >= $back_days ){
|
82 |
-
$date = date('d-m-Y H:i:s', $value['time']);
|
83 |
-
printf('<tr><td>%s</td><td>%s</td></tr>', $key, $date);
|
84 |
-
}
|
85 |
-
}
|
86 |
-
?>
|
87 |
-
</tbody>
|
88 |
-
</table>
|
89 |
-
<?php endif; ?>
|
90 |
-
</div>
|
91 |
-
</div>
|
92 |
-
<?php }
|
93 |
-
|
94 |
-
function sucuriscan_core_integrity_lib()
|
95 |
-
{
|
96 |
-
echo '<h2 id="warnings_hook"></h2>';
|
97 |
-
echo '<div class="postbox-container" style="width:75%;">';
|
98 |
-
echo '<div class="sucuriscan-maincontent">';
|
99 |
-
|
100 |
-
echo '<div class="postbox">';
|
101 |
-
echo '<div class="inside">';
|
102 |
-
echo '<h2 align="center">Sucuri WordPress Integrity Checks</h2>';
|
103 |
-
echo '</div>';
|
104 |
-
echo '</div>';
|
105 |
-
|
106 |
-
include_once("lib/core_integrity.php");
|
107 |
-
|
108 |
-
if(isset($_POST['wpsucuri-core-integrity']))
|
109 |
-
{
|
110 |
-
if(!wp_verify_nonce($_POST['sucuriscan_core_integritynonce'], 'sucuriscan_core_integritynonce'))
|
111 |
-
{
|
112 |
-
unset($_POST['wpsucuri-core_integrity']);
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
?>
|
117 |
-
|
118 |
-
<div id="poststuff">
|
119 |
-
|
120 |
-
<?php
|
121 |
-
|
122 |
-
sucuriscan_core_integrity_function_wrapper(
|
123 |
-
'sucuriwp_core_integrity_check',
|
124 |
-
'Verify Integrity of WordPress Core Files',
|
125 |
-
'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.'
|
126 |
-
);
|
127 |
-
|
128 |
-
sucuriscan_core_integrity_wp_content_wrapper();
|
129 |
-
|
130 |
-
sucuriscan_core_integrity_function_wrapper(
|
131 |
-
'sucuriwp_list_admins',
|
132 |
-
'Admin User Dump',
|
133 |
-
'List all administrator users and their latest login time.'
|
134 |
-
);
|
135 |
-
sucuriscan_core_integrity_function_wrapper(
|
136 |
-
'sucuriwp_check_plugins',
|
137 |
-
'Outdated Plugin list',
|
138 |
-
'This test will list any outdated (active) plugins.'
|
139 |
-
);
|
140 |
-
sucuriscan_core_integrity_function_wrapper(
|
141 |
-
'sucuriwp_check_themes',
|
142 |
-
'Outdated Theme List',
|
143 |
-
'This test will list any outdated theme.'
|
144 |
-
);
|
145 |
-
?>
|
146 |
-
|
147 |
-
</div>
|
148 |
-
|
149 |
-
<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>
|
150 |
-
|
151 |
-
<?php
|
152 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sucuriscan_hardening.php
DELETED
@@ -1,57 +0,0 @@
|
|
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 |
-
<h2 id="warnings_hook"></h2>
|
17 |
-
<div class="postbox-container" style="width:75%">
|
18 |
-
<div class="sucuriscan-maincontent">
|
19 |
-
<div class="postbox">
|
20 |
-
<div class="inside">
|
21 |
-
<h2 align="center">Help secure your WordPress install with <a href="http://sucuri.net/signup">Sucuri</a> 1-Click Hardening Options.</h2>
|
22 |
-
</div>
|
23 |
-
</div>
|
24 |
-
|
25 |
-
<?php
|
26 |
-
include_once('lib/hardening.php');
|
27 |
-
if( isset($_POST['wpsucuri-doharden']) ){
|
28 |
-
if(!wp_verify_nonce($_POST['sucuriscan_wphardeningnonce'], 'sucuriscan_wphardeningnonce'))
|
29 |
-
{
|
30 |
-
unset($_POST['wpsucuri-doharden']);
|
31 |
-
}
|
32 |
-
}
|
33 |
-
?>
|
34 |
-
|
35 |
-
<div id="poststuff">
|
36 |
-
<form method="post">
|
37 |
-
<input type="hidden" name="sucuriscan_wphardeningnonce" value="<?php echo wp_create_nonce('sucuriscan_wphardeningnonce'); ?>" />
|
38 |
-
<input type="hidden" name="wpsucuri-doharden" value="wpsucuri-doharden" />
|
39 |
-
<?php
|
40 |
-
sucuriscan_harden_version();
|
41 |
-
sucuriscan_cloudproxy_enabled();
|
42 |
-
sucuri_harden_removegenerator();
|
43 |
-
sucuriscan_harden_upload();
|
44 |
-
sucuriscan_harden_wpcontent();
|
45 |
-
sucuriscan_harden_wpincludes();
|
46 |
-
sucuriscan_harden_phpversion();
|
47 |
-
?>
|
48 |
-
</form>
|
49 |
-
|
50 |
-
<p align="center">
|
51 |
-
<strong>If you have any questions about these checks or this plugin, contact us at
|
52 |
-
<a href="mailto:info@sucuri.net">info@sucuri.net</a> or visit <a href="http://sucuri.net">
|
53 |
-
Sucuri Security</a></strong>
|
54 |
-
</p>
|
55 |
-
</div><!-- End poststuff -->
|
56 |
-
<?php
|
57 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|