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

Version Description

  • A new dashboard to welcome users to the new features of the plugin.
  • Overall design of the interface of all the pages were modified.
  • SiteCheck scanner results were filled with more information.
  • SiteCheck scanner results markers when the site is infected/clean.
  • System Info page were simplified with tabulation containers.
  • Integrity check for administrator accounts was optimized.
  • Integrity check for outdated plugins/themes was optimized and merged.
  • IPv6 support in last logins statistics.
Download this release

Release Info

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

Code changes from version 1.5.7 to 1.6.0

inc/css/index.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Avoid directory listing.
5
+ *
6
+ * @package Sucuri Plugin - SiteCheck Malware Scanner
7
+ * @author Yorman Arias <yorman.arias@sucuri.net>
8
+ * @author Daniel Cid <dcid@sucuri.net>
9
+ * @copyright Since 2010-2014 Sucuri Inc.
10
+ * @license Released under the GPL - see LICENSE file for details.
11
+ * @link https://wordpress.sucuri.net/
12
+ * @since File available since Release 0.1
13
+ */
14
+
15
+ if( !defined('SUCURISCAN') ){ exit(0); }
inc/css/sucuriscan-default-css.css CHANGED
@@ -1,22 +1,64 @@
1
  /**
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
- .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{min-width:initial;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}
@@ -29,25 +71,8 @@
29
  .sucuriscan-maincontent hr{border:none;border-top:1px solid #999}
30
  .sucuriscan-maincontent table td > table{background:#fff}
31
  .sucuriscan-maincontent table td > table th{padding:4px 8px}
32
- .sucuriscan-maincontent .sucuriscan-lastmodified td, .sucuriscan-maincontent .sucuriscan-corefiles td{font-family:Monaco, Monspace, Courier;font-weight:bold}
33
- .sucuriscan-maincontent .sucuriscan-corefiles tr > th{background:#f1f1f1;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}
34
- .sucuriscan-maincontent .thead-with-button span{line-height:24px}
35
- .sucuriscan-maincontent .thead-with-button .input-text{line-height:22px}
36
- .sucuriscan-maincontent .thead-topright-action{display:inline-block;float:right}
37
- .sucuriscan-monospace{font-family: Monaco, Monospace, Courier;line-height:26px}
38
- .sucuriscan-maincontent .sucuri-infosys-htaccess{margin:20px 0 0 0}
39
- .sucuriscan-maincontent .sucuri-full-textarea{width:100%;height:400px;line-height:normal;resize:vertical;padding:10px}
40
- .sucuriscan-wpconfig-textarea{width:600px;height:525px;background:#f5f5f5;line-height:1.4em;resize:none;margin:15px 0 0 0;padding:10px}
41
- .sucuriscan-maincontent .sucuriscan-about-list{margin:20px 0}
42
- .sucuriscan-maincontent .sucuriscan-about-list td+td{font-family:Monaco, Monspace, Courier;font-weight:bold}
43
- .sucuriscan-maincontent .sucuriscan-wpcron-list{margin:20px 0 15px 0}
44
- .sucuriscan-maincontent .sucuriscan-wpcron-list td+td+td+td{font-family:Monaco, Monspace, Courier;font-weight:bold}
45
  .sucuriscan-results .icon-ok, .sucuriscan-results .icon-warn, .sucuriscan-results .icon-error{position:relative;top:5px;width:22px;height:22px}
46
- .sucuriscan-last-logins .sucuriscan-time-ago{}
47
- .sucuriscan-last-logins .sucuriscan-datetime{font-style:italic;color:#999}
48
  .sucuriscan-scanner-video{width:100%;background:#fff;border:1px solid #ddd}
49
- .sucuriscan-clearfix:before, .sucuriscan-clearfix:after{display:table;content:' '}
50
- .sucuriscan-clearfix:after{clear:both}
51
  .sucuriscan-column-left, .sucuriscan-column-right{width:49%;min-width:initial !important}
52
  .sucuriscan-column-left{float:left}
53
  .sucuriscan-column-right{float:right}
@@ -55,3 +80,12 @@
55
  .sucuriscan-hstatus-1{background-color:#dff0d8;color:#3c763d;border-color:#d6e9c6}
56
  .sucuriscan-hstatus-0{background-color:#f2dede;color:#a94442;border-color:#ebccd1}
57
  .sucuriscan-hstatus .button-primary, .sucuriscan-hstatus .button-secondary{position:absolute;top:5px;right:5px}
 
 
 
 
 
 
 
 
 
1
  /**
2
  * Sucuri Security - SiteCheck Malware Scanner
3
+ * Copyright (C) 2010-2014 Sucuri Security - http://sucuri.net
4
  * Released under the GPL - see LICENSE file for details.
5
  */
6
+ /* New styles */
7
+ .sucuriscan-wrap *, .sucuriscan-wrap *:before, .sucuriscan-wrap *:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
8
+ .sucuriscan-clearfix:before, .sucuriscan-clearfix:after{display:table;content:' '}
9
+ .sucuriscan-clearfix:after{clear:both}
10
+ .sucuriscan-visible{}
11
+ .sucuriscan-hidden{display:none !important}
12
+ .sucuriscan-monospace{font-family:Monospace, Courier}
13
+ .sucuriscan-wrap .sucuriscan-maincontent{margin:20px 0}
14
+ .sucuriscan-wrap .sucuriscan-leftside{width:68%;float:left}
15
+ .sucuriscan-wrap .sucuriscan-sidebar{width:30%;float:right}
16
+ .sucuriscan-header, .sucuriscan-footer{position:relative;min-width:255px;background:#333;margin:0;padding:10px;border-radius:4px}
17
+ .sucuriscan-footer .sucuriscan-help{color:#fff;float:right;text-align:right}
18
+ .sucuriscan-footer .sucuriscan-help p{line-height:38px;margin:0 10px 0 0;padding:0}
19
+ .sucuriscan-wrap .sucuriscan-header img, .sucuriscan-wrap .sucuriscan-footer img, .sucuriscan-wrap .sucuriscan-header h2, .sucuriscan-wrap .sucuriscan-footer h2{float:left;margin:0;padding:0}
20
+ .sucuriscan-wrap .sucuriscan-header h2, .sucuriscan-wrap .sucuriscan-footer h2{color:#fff;line-height:38px;margin-left:10px;text-shadow:#000 0 1px 0}
21
+ .sucuriscan-leftside #poststuff .postbox:last-child{margin-bottom:0}
22
+ .sucuriscan-sidebar .sucuriscan-ad{border:1px solid #ccc;margin:0 0 20px 0;padding:20px;border-radius:4px}
23
+ .sucuriscan-sidebar .sucuriscan-ad h2{padding:0}
24
+ .sucuriscan-sidebar .sucuriscan-ad p:last-child{margin-bottom:0}
25
+ .sucuriscan-sidebar .sucuriscan-ad:nth-child(odd){background-color:#bbe8f5;border-color:#4393ac}
26
+ .sucuriscan-sidebar .sucuriscan-ad:nth-child(even){background-color:#ececec;border-color:#999}
27
+ .sucuriscan-maincontent .sucuriscan-border{border-left:4px solid #ddd}
28
+ .sucuriscan-maincontent .sucuriscan-border-good{border-left-color:#7ad03a}
29
+ .sucuriscan-maincontent .sucuriscan-border-bad{border-left-color:#dd3d36}
30
+ .sucuriscan-maincontent .sucuriscan-table{margin-top:12px}
31
+ .sucuriscan-maincontent .sucuriscan-table tr > th{background:#f1f1f1;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9);border-top:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5}
32
+ .sucuriscan-maincontent .sucuriscan-table tr:first-child th{border-top:0}
33
+ .sucuriscan-maincontent .sucuriscan-table td.check-column{padding:8px 10px}
34
+ .sucuriscan-table-doubletitle tr:first-child th{border-bottom:0}
35
+ .sucuriscan-maincontent .sucuriscan-corefiles td,
36
+ .sucuriscan-maincontent .sucuriscan-lastmodified td,
37
+ .sucuriscan-maincontent .sucuriscan-adminusers table td{font-family:Monospace, Courier, serif;font-weight:bold}
38
+ .sucuriscan_wpconfig_keys_updated textarea{width:100%;height:250px;background:#f5f5f5;font-family:monospace;font-size:12px;resize:vertical;margin:20px 0 0 0}
39
+ .sucuriscan-ellipsis{overflow:hidden;display:inline-block;white-space:nowrap;text-overflow:ellipsis}
40
+ .sucuriscan-maincontent .sucuriscan-last-logins{margin-top:0}
41
+ .sucuriscan-maincontent .sucuriscan-last-logins .sucuriscan-ellipsis{width:150px;line-height:inherit}
42
+ .sucuriscan-maincontent .thead-with-button span{display:inline-block;line-height:28px}
43
+ .sucuriscan-maincontent .thead-with-button .input-text{line-height:26px}
44
+ .sucuriscan-maincontent .thead-topright-action{display:inline-block;float:right}
45
+ .sucuriscan-tabs{}
46
+ .sucuriscan-tabs > ul{margin:0}
47
+ .sucuriscan-tabs > ul li, .sucuriscan-tabs > ul li > a{display:inline-block}
48
+ .sucuriscan-tabs > ul li{margin-bottom:0}
49
+ .sucuriscan-tabs > ul li > a{background:#e5e5e5;font-size:13px;font-weight:bold;color:#333;line-height:38px;text-decoration:none;padding:0 10px}
50
+ .sucuriscan-tabs > ul li > a.sucuriscan-tab-active{background:#fff;border:1px solid #e1e1e1;border-bottom:0}
51
+ .sucuriscan-maincontent .sucuriscan-tab-containers > div > table{margin-top:0}
52
+ .sucuriscan-maincontent .sucuriscan-tab-containers > div > #poststuff{margin-top:0}
53
+ .sucuriscan-maincontent .sucuriscan-full-textarea{width:100%;height:400px;line-height:normal;resize:vertical;padding:10px}
54
+ .sucuriscan-wpconfig-textarea{width:600px;height:525px;background:#f5f5f5;font-size:12px;line-height:1.4em;resize:none;margin:15px 0 0 0;padding:10px}
55
+ .sucuriscan-scanner-results table tr:nth-child(even){background:#f5f5f5}
56
+ .sucuriscan-maincontent .sucuriscan-cleanup-btn{display:block;text-align:center;margin:20px 0 0 0}
57
+ /* Old styles */
58
  .sucuriscan-maincontent #poststuff{min-width:initial;padding-top:0}
59
  .sucuriscan-maincontent .widefat tbody th.check-column{padding:6px 0 3px 0}
60
  .sucuriscan-maincontent .hardening-box .primary-secondary{margin:0 0 0 10px}
61
  .sucuriscan-maincontent a.lastlogins-showall{display:inline-block;float:right}
 
 
62
  .sucuri-alert{position:relative}
63
  .sucuri-alert>a.close{position:absolute;top:8px;right:10px;font-size:18px;text-decoration:none}
64
  .sucuri-alert-updated, .sucuri-alert-error{background:#fff;margin:5px 0 15px;padding:1px 12px;border:1px solid #e5e5e5;border-left:4px solid #ccc}
71
  .sucuriscan-maincontent hr{border:none;border-top:1px solid #999}
72
  .sucuriscan-maincontent table td > table{background:#fff}
73
  .sucuriscan-maincontent table td > table th{padding:4px 8px}
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  .sucuriscan-results .icon-ok, .sucuriscan-results .icon-warn, .sucuriscan-results .icon-error{position:relative;top:5px;width:22px;height:22px}
 
 
75
  .sucuriscan-scanner-video{width:100%;background:#fff;border:1px solid #ddd}
 
 
76
  .sucuriscan-column-left, .sucuriscan-column-right{width:49%;min-width:initial !important}
77
  .sucuriscan-column-left{float:left}
78
  .sucuriscan-column-right{float:right}
80
  .sucuriscan-hstatus-1{background-color:#dff0d8;color:#3c763d;border-color:#d6e9c6}
81
  .sucuriscan-hstatus-0{background-color:#f2dede;color:#a94442;border-color:#ebccd1}
82
  .sucuriscan-hstatus .button-primary, .sucuriscan-hstatus .button-secondary{position:absolute;top:5px;right:5px}
83
+ .sucuriscan-initial-page{}
84
+ .sucuriscan-initial-page a{text-decoration:none}
85
+ .sucuriscan-initial-page .sucuriscan-column-left{width:70%}
86
+ .sucuriscan-initial-page .sucuriscan-column-right{width:29%;text-align:right}
87
+ .sucuriscan-initial-page #poststuff .inside, .sucuriscan-initial-page #poststuff .inside p{font-size:16px;margin:0;padding:0}
88
+ .sucuriscan-initial-page #poststuff .inside{padding:20px}
89
+ .sucuriscan-initial-page #poststuff .button.button-hero{width:202px;text-align:center;padding:0}
90
+ .sucuriscan-initial-page .sucuriscan-disclaimer{padding:20px;padding-top:0}
91
+ .sucuriscan-initial-page .sucuriscan-disclaimer p{font-size:10px;margin:0}
inc/images/index.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Avoid directory listing.
5
+ *
6
+ * @package Sucuri Plugin - SiteCheck Malware Scanner
7
+ * @author Yorman Arias <yorman.arias@sucuri.net>
8
+ * @author Daniel Cid <dcid@sucuri.net>
9
+ * @copyright Since 2010-2014 Sucuri Inc.
10
+ * @license Released under the GPL - see LICENSE file for details.
11
+ * @link https://wordpress.sucuri.net/
12
+ * @since File available since Release 0.1
13
+ */
14
+
15
+ if( !defined('SUCURISCAN') ){ exit(0); }
inc/index.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Avoid directory listing.
5
+ *
6
+ * @package Sucuri Plugin - SiteCheck Malware Scanner
7
+ * @author Yorman Arias <yorman.arias@sucuri.net>
8
+ * @author Daniel Cid <dcid@sucuri.net>
9
+ * @copyright Since 2010-2014 Sucuri Inc.
10
+ * @license Released under the GPL - see LICENSE file for details.
11
+ * @link https://wordpress.sucuri.net/
12
+ * @since File available since Release 0.1
13
+ */
14
+
15
+ if( !defined('SUCURISCAN') ){ exit(0); }
inc/js/index.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Avoid directory listing.
5
+ *
6
+ * @package Sucuri Plugin - SiteCheck Malware Scanner
7
+ * @author Yorman Arias <yorman.arias@sucuri.net>
8
+ * @author Daniel Cid <dcid@sucuri.net>
9
+ * @copyright Since 2010-2014 Sucuri Inc.
10
+ * @license Released under the GPL - see LICENSE file for details.
11
+ * @link https://wordpress.sucuri.net/
12
+ * @since File available since Release 0.1
13
+ */
14
+
15
+ if( !defined('SUCURISCAN') ){ exit(0); }
inc/js/sucuriscan-scripts.js ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Sucuri Security - SiteCheck Malware Scanner
3
+ * Copyright (C) 2010-2014 Sucuri Security - http://sucuri.net
4
+ * Released under the GPL - see LICENSE file for details.
5
+ */
6
+
7
+ function sucuriscan_alert_close(id){
8
+ var element = document.getElementById('sucuri-alert-'+id);
9
+ element.parentNode.removeChild(element);
10
+ }
11
+
12
+ jQuery(document).ready(function($){
13
+ if( $('.sucuriscan-tabs').length ){
14
+ var hidden_class = 'sucuriscan-hidden';
15
+ var active_class = 'sucuriscan-tab-active';
16
+
17
+ $('.sucuriscan-tabs > ul a').on('click', function(e){
18
+ e.preventDefault();
19
+
20
+ var button = $(this);
21
+ var container_id = button.data('tabname');
22
+ var container = $('.sucuriscan-tab-containers > #sucuriscan-'+container_id);
23
+
24
+ if( container.length ){
25
+ $('.sucuriscan-tabs > ul a').removeClass(active_class);
26
+ $('.sucuriscan-tab-containers > div').addClass(hidden_class);
27
+ button.addClass(active_class);
28
+ container.removeClass(hidden_class)
29
+ }
30
+ });
31
+
32
+ $('.sucuriscan-tab-containers > div').addClass(hidden_class);
33
+ $('.sucuriscan-tabs > ul li:first-child a').trigger('click');
34
+ }
35
+ });
inc/tpl/about.html.tpl CHANGED
@@ -1,160 +1,111 @@
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 class="alternate"><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 class="alternate"><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 class="alternate"><td>Server</td><td>%%SUCURI.Server%%</td></li>
39
- <tr><td>Memory usage</td><td>%%SUCURI.MemoryUsage%%</td></li>
40
- <tr class="alternate"><td>MYSQL Version</td><td>%%SUCURI.MySQLVersion%%</td></li>
41
- <tr><td>SQL Mode</td><td>%%SUCURI.SQLMode%%</td></li>
42
- <tr class="alternate"><td>PHP Version</td><td>%%SUCURI.PHPVersion%%</td></li>
43
- <tr><td>PHP Safe Mode</td><td>%%SUCURI.SafeMode%%</td></li>
44
- <tr class="alternate"><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 class="alternate"><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 class="alternate"><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 -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
+ <div id="poststuff">
3
+ <div class="postbox">
4
+ <h3>About</h3>
5
+ <div class="inside">
6
+ <p>
7
+ Our WordPress Security Plugin will monitor your site from the inside, creating
8
+ a complete audit trail, alerting you of possible security issues (file changes,
9
+ password guessing attacks, etc) and blocking the attackers. This is the perfect
10
+ complement for our external security scans.
11
+ </p>
12
+ </div>
13
+ </div>
 
 
 
14
 
 
 
 
 
 
 
15
 
16
+ <div class="postbox">
17
+ <h3>How does it work?</h3>
18
+ <div class="inside">
19
+ <ul>
20
+ <li>Web Application Firewall. Block attacks before they reach your site.</li>
21
+ <li>Integrity Monitoring. Receive notifications if any of your files are modified.</li>
22
+ <li>Audit Logs. Keep track of everything that happens inside WordPress, including new users, posts, login failures and successful logins.</li>
23
+ <li>Activity Reporting</li>
24
+ <li>1-Click Hardening. Easy-to-use hardening options for your site.</li>
25
+ </ul>
26
+ </div>
27
+ </div>
 
 
 
 
 
 
 
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ <div class="postbox">
31
+ <h3>Web Application Firewall (WAF)</h3>
32
+ <div class="inside">
33
+ <p>
34
+ The WAF is a unique feature that is designed to intelligently protect your sites
35
+ from brute-force attacks like dictionary attacks and other similar unauthorized
36
+ access attempts. When a bad IP is identified it is blacklisted in your admin
37
+ dashboard. If it was an unintentional block, you have the ability to white-list
38
+ access to any IP.
39
+ </p>
40
+ <p>
41
+ The WAF is not tied to your application, it communicates with our servers and
42
+ allows us to see malicious attacks across the network. When one client gets attacked
43
+ by one bad IP in Croatia, we are able to push preventive measures to every plugin
44
+ to protect against that IP.
45
+ </p>
46
+ </div>
47
+ </div>
 
 
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ <div class="postbox">
51
+ <h3>Integrity Monitoring</h3>
52
+ <div class="inside">
53
+ <p>
54
+ This feature compares your core install against a clean version of core. In other
55
+ words, if it is not a 1-to-1 match with core you will be notified of a problem.
56
+ Future add-ons include:
57
+ </p>
58
+ <ul>
59
+ <li>Theme Integrity Checks</li>
60
+ <li>Plugin Integrity Checks</li>
61
+ <li>Third-party Integrity Checks</li>
62
+ </ul>
63
+ </div>
64
+ </div>
 
 
 
 
 
 
 
 
 
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ <div class="postbox">
68
+ <h3>Audit Trails</h3>
69
+ <div class="inside">
70
+ <p>
71
+ This feature is great for proactive webmasters who want to monitor their website
72
+ to ensure no unauthorized access or changes are made without prior approval.
73
+ Monitor your site for changes. This feature monitors for a large number of actions,
74
+ including:
75
+ </p>
76
+ <ul>
77
+ <li>Login attempts</li>
78
+ <li>New Posts</li>
79
+ <li>Failed Logins</li>
80
+ <li>New Plugins</li>
81
+ <li>File Changes</li>
82
+ <li>New Users</li>
83
+ <li>New Attachments</li>
84
+ <li>Delete Actions (users and posts)</li>
85
+ <li>Revisions</li>
86
+ </ul>
87
+ </div>
88
+ </div>
89
 
 
90
 
91
+ <div class="postbox">
92
+ <h3>1-Click Hardening</h3>
93
+ <div class="inside">
94
+ <p>
95
+ In our experience a high-percentage of the infections we see every day come from
96
+ poor management on the end-user’s part. This feature uses common hardening
97
+ measures that can be taken at any time and helps reduce infection risk. This
98
+ feature performs the following:
99
+ </p>
100
+ <ul>
101
+ <li>Checks software core version</li>
102
+ <li>Hides your version (security through obscurity)</li>
103
+ <li>Upload directory protected</li>
104
+ <li>Secret keys and salts created</li>
105
+ <li>Configuration file hardening/location verification</li>
106
+ <li>Hardening of readme file</li>
107
+ <li>PHP verification</li>
108
+ </ul>
109
+ </div>
110
+ </div>
111
+ </div><!-- End poststuff -->
inc/tpl/base.html.tpl ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <div class="wrap sucuriscan-wrap">
3
+
4
+ <h2 id="warnings_hook"></h2>
5
+
6
+ <div class="sucuriscan-header sucuriscan-clearfix">
7
+ <a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">
8
+ <img src="%%SUCURI.SucuriURL%%/inc/images/logo.png" alt="Sucuri Security" />
9
+ </a>
10
+ <h2>SiteCheck Scanner %%SUCURI.PageTitle%%</h2>
11
+ </div>
12
+
13
+ <div class="sucuriscan-maincontent sucuriscan-clearfix">
14
+
15
+ <div class="sucuriscan-leftside sucuriscan-%%SUCURI.PageStyleClass%%">
16
+
17
+ %%SUCURI.PageContent%%
18
+
19
+ </div>
20
+
21
+ <div class="sucuriscan-sidebar">
22
+
23
+ <div class="sucuriscan-ad">
24
+ <h2>Is your website infected with malware? Blacklisted by Google?</h2>
25
+ <p>Don't know where to start? Get cleared today by <a href="http://sucuri.net/signup">Sucuri Security</a>!</p>
26
+ <p><a class="button-primary" href="http://sucuri.net/tour">Read more &#187;</a></p>
27
+ </div>
28
+
29
+ <div class="sucuriscan-ad">
30
+ <h2>Preventive website security in the cloud!</h2>
31
+ <ul class="sucuri-list">
32
+ <li>Web Application Firewall (WAF) Protection</li>
33
+ <li>Virtual Website Patching</li>
34
+ <li>Cloud Intrusion Prevention System (IPS)</li>
35
+ <li>High Security Website Monitoring</li>
36
+ <li>Malicious Traffic Filtering</li>
37
+ </ul>
38
+ <p>
39
+ <a href="http://cloudproxy.sucuri.net/signup" target="_blank" class="button button-primary">Sign up now</a>
40
+ <a href="http://cloudproxy.sucuri.net/" target="_blank" class="button button-primary">Read more</a>
41
+ </p>
42
+ </div>
43
+
44
+ <iframe src="https://www.youtube-nocookie.com/embed/QV3OfHmEq5c" height="250" class="sucuriscan-scanner-video"></iframe>
45
+
46
+ </div>
47
+
48
+ </div>
49
+
50
+ <div class="sucuriscan-footer sucuriscan-clearfix">
51
+ <a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">
52
+ <img src="%%SUCURI.SucuriURL%%/inc/images/logo.png" alt="Sucuri Security" />
53
+ </a>
54
+ <div class="sucuriscan-help">
55
+ <p>
56
+ If you have any questions about these checks or this plugin, contact us at
57
+ <a href="mailto:info@sucuri.net">info@sucuri.net</a> or visit
58
+ <a href="http://sucuri.net/" target="_blank">sucuri.net</a>
59
+ </p>
60
+ </div>
61
+ </div>
62
+ </div>
inc/tpl/index.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Avoid directory listing.
5
+ *
6
+ * @package Sucuri Plugin - SiteCheck Malware Scanner
7
+ * @author Yorman Arias <yorman.arias@sucuri.net>
8
+ * @author Daniel Cid <dcid@sucuri.net>
9
+ * @copyright Since 2010-2014 Sucuri Inc.
10
+ * @license Released under the GPL - see LICENSE file for details.
11
+ * @link https://wordpress.sucuri.net/
12
+ * @since File available since Release 0.1
13
+ */
14
+
15
+ if( !defined('SUCURISCAN') ){ exit(0); }
inc/tpl/infosys-cronjobs.html.tpl CHANGED
@@ -2,13 +2,13 @@
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>
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>
inc/tpl/infosys-cronjobs.snippet.tpl CHANGED
@@ -2,6 +2,6 @@
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>
2
  <td>%%SUCURI.Cronjob.Task%%</td>
3
  <td>%%SUCURI.Cronjob.Schedule%%</td>
4
  <td>%%SUCURI.Cronjob.Nexttime%%</td>
5
+ <td><span class="sucuriscan-monospace">%%SUCURI.Cronjob.Hook%%</span></td>
6
  <!-- <td>%%SUCURI.Cronjob.Arguments%%</td> -->
7
  </tr>
inc/tpl/infosys-htaccess.html.tpl CHANGED
@@ -14,7 +14,7 @@
14
  <p>%%SUCURI.HTAccess.Message%%</p>
15
  </div>
16
 
17
- <textarea class="sucuri-full-textarea sucuriscan-monospace %%SUCURI.HTAccess.TextareaVisible%%">%%SUCURI.HTAccess.Content%%</textarea>
18
 
19
  <p>
20
  <small>Source <a href="http://codex.wordpress.org/htaccess" target="_blank">Codex WordPress HTAccess</a></small>
14
  <p>%%SUCURI.HTAccess.Message%%</p>
15
  </div>
16
 
17
+ <textarea class="sucuriscan-full-textarea sucuriscan-monospace %%SUCURI.HTAccess.TextareaVisible%%">%%SUCURI.HTAccess.Content%%</textarea>
18
 
19
  <p>
20
  <small>Source <a href="http://codex.wordpress.org/htaccess" target="_blank">Codex WordPress HTAccess</a></small>
inc/tpl/infosys-serverinfo.html.tpl ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <table class="wp-list-table widefat sucuri-%%SUCURI.SettingsDisplay%%">
3
+ <tbody>
4
+ <tr class="alternate">
5
+ <td>Sucuri Plugin version</td>
6
+ <td><span class="sucuriscan-monospace">%%SUCURI.PluginVersion%%</span></td>
7
+ </tr>
8
+ <tr>
9
+ <td>Sucuri Plugin MD5Sum (sucuri.php)</td>
10
+ <td><span class="sucuriscan-monospace">%%SUCURI.PluginMD5%%</span></td>
11
+ </tr>
12
+ <tr class="alternate">
13
+ <td>Sucuri Plugin Last-time scan</td>
14
+ <td><span class="sucuriscan-monospace">%%SUCURI.PluginRuntimeDatetime%%</span></td>
15
+ </tr>
16
+ <tr>
17
+ <td>Operating System</td>
18
+ <td><span class="sucuriscan-monospace">%%SUCURI.OperatingSystem%%</span></td>
19
+ </tr>
20
+ <tr class="alternate">
21
+ <td>Server</td>
22
+ <td><span class="sucuriscan-monospace">%%SUCURI.Server%%</span></td>
23
+ </tr>
24
+ <tr>
25
+ <td>Memory usage</td>
26
+ <td><span class="sucuriscan-monospace">%%SUCURI.MemoryUsage%%</span></td>
27
+ </tr>
28
+ <tr class="alternate">
29
+ <td>MYSQL Version</td>
30
+ <td><span class="sucuriscan-monospace">%%SUCURI.MySQLVersion%%</span></td>
31
+ </tr>
32
+ <tr>
33
+ <td>SQL Mode</td>
34
+ <td><span class="sucuriscan-monospace">%%SUCURI.SQLMode%%</span></td>
35
+ </tr>
36
+ <tr class="alternate">
37
+ <td>PHP Version</td>
38
+ <td><span class="sucuriscan-monospace">%%SUCURI.PHPVersion%%</span></td>
39
+ </tr>
40
+ <tr>
41
+ <td>PHP Safe Mode</td>
42
+ <td><span class="sucuriscan-monospace">%%SUCURI.SafeMode%%</span></td>
43
+ </tr>
44
+ <tr class="alternate">
45
+ <td>PHP Allow URL fopen</td>
46
+ <td><span class="sucuriscan-monospace">%%SUCURI.AllowUrlFopen%%</span></td>
47
+ </tr>
48
+ <tr>
49
+ <td>PHP Memory Limit</td>
50
+ <td><span class="sucuriscan-monospace">%%SUCURI.MemoryLimit%%</span></td>
51
+ </tr>
52
+ <tr class="alternate">
53
+ <td>PHP Max Upload Size</td>
54
+ <td><span class="sucuriscan-monospace">%%SUCURI.UploadMaxFilesize%%</span></td>
55
+ </tr>
56
+ <tr>
57
+ <td>PHP Max Post Size</td>
58
+ <td><span class="sucuriscan-monospace">%%SUCURI.PostMaxSize%%</span></td>
59
+ </tr>
60
+ <tr class="alternate">
61
+ <td>PHP Max Script Execute Time</td>
62
+ <td><span class="sucuriscan-monospace">%%SUCURI.MaxExecutionTime%%</span></td>
63
+ </tr>
64
+ <tr>
65
+ <td>PHP Max Input Time</td>
66
+ <td><span class="sucuriscan-monospace">%%SUCURI.MaxInputTime%%</span></td>
67
+ </tr>
68
+ </tbody>
69
+ </table>
inc/tpl/infosys-wpconfig.html.tpl CHANGED
@@ -4,7 +4,7 @@
4
  <th colspan="7" class="thead-with-button">
5
  <span>WP-Config Variables</span>
6
  <div class="thead-topright-action">
7
- <a href="#TB_inline?width=800&height=550&inlineId=sucuri-wpconfig-content" class="button button-primary thickbox">View File</a>
8
  </div>
9
  </th>
10
  <tr>
@@ -17,6 +17,6 @@
17
  </tbody>
18
  </table>
19
 
20
- <div id="sucuri-wpconfig-content" style="display:none">
21
- <textarea class="sucuri-full-textarea sucuriscan-wpconfig-textarea sucuriscan-monospace">%%SUCURI.WordpressConfig.Content%%</textarea>
22
  </div>
4
  <th colspan="7" class="thead-with-button">
5
  <span>WP-Config Variables</span>
6
  <div class="thead-topright-action">
7
+ <a href="%%SUCURI.WordpressConfig.ThickboxURL%%" title="WordPress Config Variables" class="button button-primary thickbox">View File</a>
8
  </div>
9
  </th>
10
  <tr>
17
  </tbody>
18
  </table>
19
 
20
+ <div id="sucuriscan-wpconfig-content" style="display:none">
21
+ <textarea class="sucuriscan-full-textarea sucuriscan-wpconfig-textarea sucuriscan-monospace">%%SUCURI.WordpressConfig.Content%%</textarea>
22
  </div>
inc/tpl/infosys.html.tpl CHANGED
@@ -1,25 +1,42 @@
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 (Site Info)</h2>
8
- </div>
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- <div class="postbox-container" style="width:75%;">
12
- <div class="sucuriscan-maincontent">
13
  %%SUCURI.LoggedInUsers%%
 
14
 
 
15
  %%SUCURI.Cronjobs%%
 
16
 
 
17
  %%SUCURI.HTAccessIntegrity%%
 
18
 
 
19
  %%SUCURI.WordpressConfig%%
20
- </div><!-- End sucuriscan-maincontent -->
21
- </div><!-- End postbox-container -->
22
-
23
- %%SUCURI.SucuriWPSidebar%%
24
-
25
- </div><!-- End wrap -->
 
 
 
 
 
 
 
 
1
 
2
+ <div class="sucuriscan-tabs">
3
+ <ul>
4
+ <li>
5
+ <a href="#" data-tabname="server-info">Plugin & Server Info</a>
6
+ </li>
7
+ <li>
8
+ <a href="#" data-tabname="loggedin-users">Logged In Users</a>
9
+ </li>
10
+ <li>
11
+ <a href="#" data-tabname="wordpress-cronjobs">WordPress Cronjobs</a>
12
+ </li>
13
+ <li>
14
+ <a href="#" data-tabname="htaccess-integrity">HTAccess Integrity</a>
15
+ </li>
16
+ <li>
17
+ <a href="#" data-tabname="wpconfig-vars">WP Config Variables</a>
18
+ </li>
19
+ </ul>
20
+
21
+ <div class="sucuriscan-tab-containers">
22
+ <div id="sucuriscan-server-info">
23
+ %%SUCURI.ServerInfo%%
24
+ </div>
25
 
26
+ <div id="sucuriscan-loggedin-users">
 
27
  %%SUCURI.LoggedInUsers%%
28
+ </div>
29
 
30
+ <div id="sucuriscan-wordpress-cronjobs">
31
  %%SUCURI.Cronjobs%%
32
+ </div>
33
 
34
+ <div id="sucuriscan-htaccess-integrity">
35
  %%SUCURI.HTAccessIntegrity%%
36
+ </div>
37
 
38
+ <div id="sucuriscan-wpconfig-vars">
39
  %%SUCURI.WordpressConfig%%
40
+ </div>
41
+ </div>
42
+ </div>
 
 
 
inc/tpl/initial-page.html.tpl CHANGED
@@ -1,47 +1,97 @@
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.PluginURL%%/inc/images/logo.png" alt="Sucuri Security" />
6
- </a>
7
- <h2>Sucuri SiteCheck Malware Scanner</h2>
8
- </div>
9
 
10
- <div class="postbox-container" style="width:75%">
11
- <div class="sucuriscan-maincontent">
12
- <div class="sucuriscan-clearfix">
13
- <div id="poststuff" class="sucuriscan-column-left">
14
- <div class="postbox">
15
- <h3>Sucuri SiteCheck</h3>
16
- <div class="inside">
17
- <p>
18
- <a href="http://sitecheck.sucuri.net/" target="_blank">Sucuri SiteCheck</a> scanner will
19
- check your website for known malware, blacklisting status, website errors, and out-of-date
20
- software. <strong>Disclaimer</strong>: Sucuri SiteCheck is a free &amp; remote scanner.
21
- Although we do our best to provide the best results, 100% accuracy is not realistic, and
22
- not guaranteed.
23
- </p>
24
- </div>
25
- </div>
26
-
27
- <form method="post">
28
- <input type="hidden" name="wpsucuri-doscan" value="wpsucuri-doscan" />
29
- <input type="submit" name="wpsucuri_doscanrun" value="Scan this site now!" class="button button-primary button-hero load-customize" />
30
- </form>
31
- </div>
32
-
33
- <div class="sucuriscan-column-right">
34
- <iframe src="https://www.youtube-nocookie.com/embed/QV3OfHmEq5c?controls=0" height="350" class="sucuriscan-scanner-video"></iframe>
35
- </div>
36
- </div>
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  <p>
39
- <strong>If you have any questions about these checks or this plugin, contact us at
40
- <a href="mailto:info@sucuri.net">info@sucuri.net</a> or visit <a href="http://sucuri.net">
41
- sucuri.net</a></strong>
42
  </p>
43
  </div>
44
  </div>
45
 
46
- %%SUCURI.Sidebar%%
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  </div>
 
 
 
 
 
 
 
 
1
 
2
+ <div id="poststuff">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
+ <div class="postbox">
5
+ <h3>Sucuri SiteCheck</h3>
6
+ <div class="inside sucuriscan-clearfix">
7
+ <div class="sucuriscan-column-left">
8
+ <p>
9
+ <a href="http://sitecheck.sucuri.net/" target="_blank">Sucuri SiteCheck</a>
10
+ scanner will check your website for known malware, blacklisting status, website
11
+ errors, and out-of-date software.
12
+ </p>
13
+ </div>
14
+ <div class="sucuriscan-column-right">
15
+ <form method="post">
16
+ <input type="hidden" name="wpsucuri-doscan" value="wpsucuri-doscan" />
17
+ <input type="submit" name="wpsucuri_doscanrun" value="Scan this site now" class="button button-primary button-hero" />
18
+ </form>
19
+ </div>
20
+ </div>
21
+ <div class="sucuriscan-disclaimer">
22
  <p>
23
+ <strong>Disclaimer</strong>: Sucuri SiteCheck is a free and remote scanner.
24
+ Although we do our best to provide the best results, 100% accuracy is not
25
+ realistic, and not guaranteed.
26
  </p>
27
  </div>
28
  </div>
29
 
30
+
31
+ <div class="postbox">
32
+ <h3>1-Click Hardening</h3>
33
+ <div class="inside sucuriscan-clearfix">
34
+ <div class="sucuriscan-column-left">
35
+ <p>
36
+ In our experience a high-percentage of the infections we see every day come from
37
+ poor management on the end-user's part. This feature uses common hardening
38
+ measures that can be taken at any time and helps reduce infection risk.
39
+ </p>
40
+ </div>
41
+ <div class="sucuriscan-column-right">
42
+ <a href="%%SUCURI.URL.Hardening%%" class="button button-primary button-hero">Harden this site now</a>
43
+ </div>
44
+ </div>
45
+ </div>
46
+
47
+
48
+ <div class="postbox">
49
+ <h3>WordPress Integrity</h3>
50
+ <div class="inside sucuriscan-clearfix">
51
+ <div class="sucuriscan-column-left">
52
+ <p>
53
+ This feature compares your core install against a clean version of core. In
54
+ other words, if it is not a 1-to-1 match with core you will be notified of a
55
+ problem.
56
+ </p>
57
+ </div>
58
+ <div class="sucuriscan-column-right">
59
+ <a href="%%SUCURI.URL.CoreIntegrity%%" class="button button-primary button-hero">Check site integrity now</a>
60
+ </div>
61
+ </div>
62
+ </div>
63
+
64
+
65
+ <div class="postbox">
66
+ <h3>Post-Hack</h3>
67
+ <div class="inside sucuriscan-clearfix">
68
+ <div class="sucuriscan-column-left">
69
+ <p>
70
+ After being hacked or infected with malware, we recommend that you update your
71
+ wp-config keys, and also reset all your user passwords. Do it with ease using
72
+ Sucuri Post-Hack.
73
+ </p>
74
+ </div>
75
+ <div class="sucuriscan-column-right">
76
+ <a href="%%SUCURI.URL.PostHack%%" class="button button-primary button-hero">Run Post-Hack resets</a>
77
+ </div>
78
+ </div>
79
+ </div>
80
+
81
+
82
+ <div class="postbox">
83
+ <h3>Last Logins</h3>
84
+ <div class="inside sucuriscan-clearfix">
85
+ <div class="sucuriscan-column-left">
86
+ <p>
87
+ It's always good to know who is logging into your site. This feature allows you
88
+ to view logins, where they came from, and when they logged in.
89
+ </p>
90
+ </div>
91
+ <div class="sucuriscan-column-right">
92
+ <a href="%%SUCURI.URL.LastLogins%%" class="button button-primary button-hero">View Last Logins</a>
93
+ </div>
94
+ </div>
95
+ </div>
96
+
97
  </div>
inc/tpl/integrity-admins.html.tpl CHANGED
@@ -1,4 +1,4 @@
1
- <table class="wp-list-table widefat">
2
  <thead>
3
  <tr>
4
  <th colspan="4">Administrator Users</th>
1
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-table-doubletitle sucuriscan-adminusers">
2
  <thead>
3
  <tr>
4
  <th colspan="4">Administrator Users</th>
inc/tpl/lastlogins.html.tpl CHANGED
@@ -1,40 +1,23 @@
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 (Last Logins)</h2>
8
- </div>
9
 
10
- <div class="postbox-container" style="width:75%;">
11
- <div class="sucuriscan-maincontent">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
- <table class="wp-list-table widefat sucuriscan-last-logins">
14
- <thead>
15
- <tr>
16
- <th colspan="5">
17
- User logins (latest %%SUCURI.UserListLimit%%, newest to oldest)
18
- <a href="%%SUCURI.CurrentURL%%&limit=0" class="button button-primary lastlogins-showall sucuri-%%SUCURI.UserList.ShowAll%%">Show all results</a>
19
- </th>
20
- </tr>
21
- <tr>
22
- <th class="manage-column">No.</th>
23
- <th class="manage-column">Username</th>
24
- <th class="manage-column">Email</th>
25
- <th class="manage-column">IP Address</th>
26
- <th class="manage-column">Date/Time</th>
27
- </tr>
28
- </thead>
29
-
30
- <tbody>
31
- %%SUCURI.UserList%%
32
- </tbody>
33
- </table>
34
-
35
- </div><!-- End sucuriscan-maincontent -->
36
- </div><!-- End postbox-container -->
37
-
38
- %%SUCURI.SucuriWPSidebar%%
39
-
40
- </div><!-- End wrap -->
 
 
 
 
 
 
 
 
1
 
2
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-table-doubletitle sucuriscan-last-logins">
3
+ <thead>
4
+ <tr>
5
+ <th colspan="6" class="thead-with-button">
6
+ <span>User logins (latest %%SUCURI.UserListLimit%%, newest to oldest)</span>
7
+ <a href="%%SUCURI.CurrentURL%%&limit=0" class="button button-primary lastlogins-showall thead-topright-action sucuri-%%SUCURI.UserList.ShowAll%%">Show all results</a>
8
+ </th>
9
+ </tr>
10
+ <tr>
11
+ <th class="manage-column">No.</th>
12
+ <th class="manage-column">User</th>
13
+ <th class="manage-column">IP Address</th>
14
+ <th class="manage-column">Hostname</th>
15
+ <th class="manage-column">Date/Time</th>
16
+ <th class="manage-column">&nbsp;</th>
17
+ </tr>
18
+ </thead>
19
 
20
+ <tbody>
21
+ %%SUCURI.UserList%%
22
+ </tbody>
23
+ </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/tpl/lastlogins.snippet.tpl CHANGED
@@ -1,10 +1,8 @@
1
  <tr class="%%SUCURI.UserList.CssClass%%">
2
  <td>%%SUCURI.UserList.Number%%</td>
3
- <td>%%SUCURI.UserList.Username%%</td>
4
- <td><a href="mailto:%%SUCURI.UserList.Email%%">%%SUCURI.UserList.Email%%</a></td>
5
- <td>%%SUCURI.UserList.RemoteAddr%%</td>
6
- <td>
7
- <span class="sucuriscan-time-ago">%%SUCURI.UserList.TimeAgo%%</span>
8
- <span class="sucuriscan-datetime">(%%SUCURI.UserList.Datetime%%)</span>
9
- </td>
10
  </tr>
1
  <tr class="%%SUCURI.UserList.CssClass%%">
2
  <td>%%SUCURI.UserList.Number%%</td>
3
+ <td>%%SUCURI.UserList.Displayname%% (%%SUCURI.UserList.Username%%)</td>
4
+ <td><span class="sucuriscan-ellipsis" title="%%SUCURI.UserList.RemoteAddr%%">%%SUCURI.UserList.RemoteAddr%%</span></td>
5
+ <td><span class="sucuriscan-ellipsis" title="%%SUCURI.UserList.Hostname%%">%%SUCURI.UserList.Hostname%%</span></td>
6
+ <td><span title="%%SUCURI.UserList.Datetime%%">%%SUCURI.UserList.TimeAgo%%</span></td>
7
+ <td><a href="%%SUCURI.UserList.UserURL%%" target="_blank">Edit</a></td>
 
 
8
  </tr>
inc/tpl/posthack.html.tpl CHANGED
@@ -1,90 +1,78 @@
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 (Post-Hack)</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>Update WP-Config Keys</h3>
15
- <div class="inside">
16
- <form method="post">
17
- <input type="hidden" name="sucuri_posthack_nonce" value="%%SUCURI.PosthackNonce%%" />
18
- <input type="hidden" name="sucuri_posthack_action" value="update_wpconfig" />
19
-
20
- <p>
21
- Use this button to update the security keys stored in the <code>wp-config.php</code>
22
- file, we will use the official WordPress Secret-Key API Generator. After the
23
- update your current session will be closed and you'll need to login again.
24
- </p>
25
 
26
- <p>
27
- <input type="hidden" name="sucuri_update_wpconfig" value="0" />
28
- <input type="checkbox" name="sucuri_update_wpconfig" value="1" />
29
- <label for="sucuri_update_wpconfig">I understand that this operation can not be reverted.</label>
30
- </p>
 
 
31
 
32
- <input type="submit" value="Update WP-Config Keys" class="button button-primary" />
33
- </form>
 
 
 
34
 
35
- <div style="%%SUCURI.WPConfigUpdate.Display%%" class="sucuri_update_wpconfig_process">
36
- <textarea>%%SUCURI.WPConfigUpdate.NewConfig%%</textarea>
37
- </div>
38
- </div>
39
- </div>
 
 
40
 
41
- <div class="postbox">
42
- <h3>Reset user password</h3>
43
- <div class="inside">
44
- <form method="post">
45
- <input type="hidden" name="sucuri_posthack_nonce" value="%%SUCURI.PosthackNonce%%" />
46
- <input type="hidden" name="sucuri_posthack_action" value="reset_password" />
47
 
48
- <p>
49
- Use this button to reset the current password for some specific users or for all
50
- of them. We will send an email to each of those users adivising the password change
51
- that includes the new password automatically generated by WordPress. After the
52
- password reset your current session will be closed and you'll need to login again.
53
- </p>
54
-
55
- <table class="wp-list-table widefat">
56
- <thead>
57
- <tr>
58
- <th class="manage-column column-cb check-column">
59
- <label class="screen-reader-text" for="cb-select-all-1">Select All</label>
60
- <input id="cb-select-all-1" type="checkbox">
61
- </th>
62
- <th class="manage-column column-name">Username</th>
63
- <th class="manage-column column-description">Display name</th>
64
- <th class="manage-column column-description">Email address</th>
65
- </tr>
66
- </thead>
67
 
68
- <tbody>
69
- %%SUCURI.ResetPassword.UserList%%
70
- </tbody>
71
- </table>
 
 
72
 
73
- <p>
74
- <input type="hidden" name="sucuri_reset_password" value="0" />
75
- <input type="checkbox" name="sucuri_reset_password" value="1" />
76
- <label for="sucuri_reset_password">I understand that this operation can not be reverted.</label>
77
- </p>
 
78
 
79
- <input type="submit" value="Reset User Password" class="button button-primary" />
80
- </form>
81
- </div>
82
- </div>
83
- </div><!-- End poststuff -->
 
 
 
 
 
 
 
 
84
 
85
- </div><!-- End sucuriscan-maincontent -->
86
- </div><!-- End postbox-container -->
 
 
87
 
88
- %%SUCURI.SucuriWPSidebar%%
 
 
 
 
 
 
89
 
90
- </div><!-- End wrap -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
+ <div id="poststuff">
3
+ <div class="postbox">
4
+ <h3>Update WP-Config Keys</h3>
5
+ <div class="inside">
6
+ <form method="post">
7
+ <input type="hidden" name="sucuri_posthack_nonce" value="%%SUCURI.PosthackNonce%%" />
8
+ <input type="hidden" name="sucuri_posthack_action" value="update_wpconfig" />
9
 
10
+ <p>
11
+ Use this button to update the security keys stored in the <code>wp-config.php</code>
12
+ file, we will use the official WordPress Secret-Key API Generator. After the
13
+ update your current session will be closed and you'll need to login again.
14
+ </p>
15
 
16
+ <p>
17
+ <label>
18
+ <input type="hidden" name="sucuri_update_wpconfig" value="0" />
19
+ <input type="checkbox" name="sucuri_update_wpconfig" value="1" />
20
+ <span>I understand that this operation can not be reverted.</span>
21
+ </label>
22
+ </p>
23
 
24
+ <input type="submit" value="Update WP-Config Keys" class="button button-primary" />
25
+ </form>
 
 
 
 
26
 
27
+ <div style="%%SUCURI.WPConfigUpdate.Display%%" class="sucuriscan_wpconfig_keys_updated">
28
+ <textarea>%%SUCURI.WPConfigUpdate.NewConfig%%</textarea>
29
+ </div>
30
+ </div>
31
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ <div class="postbox">
34
+ <h3>Reset user password</h3>
35
+ <div class="inside">
36
+ <form method="post">
37
+ <input type="hidden" name="sucuri_posthack_nonce" value="%%SUCURI.PosthackNonce%%" />
38
+ <input type="hidden" name="sucuri_posthack_action" value="reset_password" />
39
 
40
+ <p>
41
+ Use this button to reset the current password for some specific users or for all
42
+ of them. We will send an email to each of those users adivising the password change
43
+ that includes the new password automatically generated by WordPress. After the
44
+ password reset your current session will be closed and you'll need to login again.
45
+ </p>
46
 
47
+ <table class="wp-list-table widefat sucuriscan-table">
48
+ <thead>
49
+ <tr>
50
+ <th class="manage-column column-cb check-column">
51
+ <label class="screen-reader-text" for="cb-select-all-1">Select All</label>
52
+ <input id="cb-select-all-1" type="checkbox">
53
+ </th>
54
+ <th class="manage-column">User</th>
55
+ <th class="manage-column">Email address</th>
56
+ <th class="manage-column">Registered</th>
57
+ <th class="manage-column">Roles</th>
58
+ </tr>
59
+ </thead>
60
 
61
+ <tbody>
62
+ %%SUCURI.ResetPassword.UserList%%
63
+ </tbody>
64
+ </table>
65
 
66
+ <p>
67
+ <label>
68
+ <input type="hidden" name="sucuri_reset_password" value="0" />
69
+ <input type="checkbox" name="sucuri_reset_password" value="1" />
70
+ <span>I understand that this operation can not be reverted.</span>
71
+ </label>
72
+ </p>
73
 
74
+ <input type="submit" value="Reset User Password" class="button button-primary" />
75
+ </form>
76
+ </div>
77
+ </div>
78
+ </div><!-- End poststuff -->
inc/tpl/resetpassword.snippet.tpl CHANGED
@@ -1,8 +1,9 @@
1
  <tr class="%%SUCURI.ResetPassword.CssClass%%">
2
- <th class="check-column">
3
- <input type="checkbox" name="user_ids[]" value="%%SUCURI.ResetPassword.UserId%%" />
4
- </th>
5
- <td>%%SUCURI.ResetPassword.Username%%</td>
6
- <td>%%SUCURI.ResetPassword.Displayname%%</td>
7
  <td><a href="mailto:%%SUCURI.ResetPassword.Email%%">%%SUCURI.ResetPassword.Email%%</a></td>
 
 
8
  </tr>
1
  <tr class="%%SUCURI.ResetPassword.CssClass%%">
2
+ <td class="check-column">
3
+ <input type="checkbox" name="user_ids[]" value="%%SUCURI.ResetPassword.UserId%%" />
4
+ </td>
5
+ <td>%%SUCURI.ResetPassword.Displayname%% (%%SUCURI.ResetPassword.Username%%)</td>
 
6
  <td><a href="mailto:%%SUCURI.ResetPassword.Email%%">%%SUCURI.ResetPassword.Email%%</a></td>
7
+ <td>%%SUCURI.ResetPassword.Registered%%</td>
8
+ <td>%%SUCURI.ResetPassword.Roles%%</td>
9
  </tr>
inc/tpl/sidebar.html.tpl DELETED
@@ -1,24 +0,0 @@
1
- <div class="postbox-container" style="width:25%">
2
- <div id="sidebar">
3
- <div id="sitecleanup" class="sucuriscan-sidebar">
4
- <h2><span class="promo">Is your website infected with malware? Blacklisted by Google?</span></h2>
5
- <p>Don't know where to start? Get cleared today by <a href="http://sucuri.net/signup">Sucuri Security</a>!</p>
6
- <p>
7
- <a class="button-primary" href="http://sucuri.net/tour">Read more &#187;</a>
8
- </p>
9
- </div>
10
-
11
- <div id="sucuri-latest-posts" class="sucuriscan-sidebar">
12
- <h2><span class="promo">Preventive website security in the cloud!</span></h2>
13
- <ul class="sucuri-list">
14
- <li>Web Application Firewall (WAF) Protection</li>
15
- <li>Virtual Website Patching</li>
16
- <li>Cloud Intrusion Prevention System (IPS)</li>
17
- <li>High Security Website Monitoring</li>
18
- <li>Malicious Traffic Filtering</li>
19
- </ul>
20
- <a href="http://cloudproxy.sucuri.net/signup" target="_blank" class="button button-primary">Sign up now</a>
21
- <a href="http://cloudproxy.sucuri.net/" target="_blank" class="button button-primary">Read more</a>
22
- </div>
23
- </div>
24
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
index.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Avoid directory listing.
5
+ *
6
+ * @package Sucuri Plugin - SiteCheck Malware Scanner
7
+ * @author Yorman Arias <yorman.arias@sucuri.net>
8
+ * @author Daniel Cid <dcid@sucuri.net>
9
+ * @copyright Since 2010-2014 Sucuri Inc.
10
+ * @license Released under the GPL - see LICENSE file for details.
11
+ * @link https://wordpress.sucuri.net/
12
+ * @since File available since Release 0.1
13
+ */
14
+
15
+ if( !defined('SUCURISCAN') ){ exit(0); }
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Sucuri Security - SiteCheck Malware Scanner ===
2
- Contributors: dd@sucuri.net, dremeda
3
  Donate Link: http://sitecheck.sucuri.net
4
- Tags: malware, security, scan, spam, virus, sucuri, WordPress,
5
  Requires at least:3.2
6
- Stable tag:1.5.7
7
- Tested up to: 3.9
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
 
@@ -66,6 +66,17 @@ the compromise on your site).
66
 
67
  == Changelog ==
68
 
 
 
 
 
 
 
 
 
 
 
 
69
  = 1.5.7 =
70
  * WordPress 3.9 compatibility
71
 
1
  === Sucuri Security - SiteCheck Malware Scanner ===
2
+ Contributors: dd@sucuri.net
3
  Donate Link: http://sitecheck.sucuri.net
4
+ Tags: malware, security, firewall, scan, spam, virus, sucuri, protection
5
  Requires at least:3.2
6
+ Stable tag:1.6.0
7
+ Tested up to: 3.9.1
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
 
66
 
67
  == Changelog ==
68
 
69
+ = 1.6.0 =
70
+ * A new dashboard to welcome users to the new features of the plugin.
71
+ * Overall design of the interface of all the pages were modified.
72
+ * SiteCheck scanner results were filled with more information.
73
+ * SiteCheck scanner results markers when the site is infected/clean.
74
+ * System Info page were simplified with tabulation containers.
75
+ * Integrity check for administrator accounts was optimized.
76
+ * Integrity check for outdated plugins/themes was optimized and merged.
77
+ * IPv6 support in last logins statistics.
78
+
79
+
80
  = 1.5.7 =
81
  * WordPress 3.9 compatibility
82
 
sucuri.php CHANGED
@@ -7,7 +7,7 @@ Description: The <a href="http://sucuri.net">Sucuri Security</a> - SiteCheck Mal
7
  You can also scan your site at <a href="http://sitecheck.sucuri.net">SiteCheck.Sucuri.net</a>.
8
 
9
  Author: Sucuri, INC
10
- Version: 1.5.7
11
  Author URI: http://sucuri.net
12
  */
13
 
@@ -18,7 +18,7 @@ Author URI: http://sucuri.net
18
  * @package Sucuri Plugin - SiteCheck Malware Scanner
19
  * @author Yorman Arias <yorman.arias@sucuri.net>
20
  * @author Daniel Cid <dcid@sucuri.net>
21
- * @copyright Since 2010 Sucuri Inc.
22
  * @license Released under the GPL - see LICENSE file for details.
23
  * @link https://wordpress.sucuri.net/
24
  * @since File available since Release 0.1
@@ -39,7 +39,7 @@ define('SUCURISCAN','sucuriscan');
39
  /**
40
  * Current version of the plugin's code.
41
  */
42
- define('SUCURISCAN_VERSION','1.5.7');
43
 
44
  /**
45
  * The local URL where the plugin's files and assets are served.
@@ -73,7 +73,7 @@ define('SUCURISCAN_LASTLOGINS_USERSLIMIT', 50);
73
 
74
  if( !function_exists('sucuriscan_create_uploaddir') ){
75
  /**
76
- * Create a folder in the Wordpress upload directory where the plugin will
77
  * store all the temporal or dynamic information.
78
  *
79
  * @return void
@@ -98,15 +98,13 @@ if( !function_exists('sucuriscan_create_uploaddir') ){
98
  * Define which javascript and css files will be loaded in the header of the page.
99
  * @return void
100
  */
101
- function sucuriscan_admin_script_style_registration() { ?>
102
- <link rel="stylesheet" href="<?php echo SUCURI_URL; ?>/inc/css/sucuriscan-default-css.css" type="text/css" media="all" />
103
- <script type="text/javascript">
104
- function sucuriscan_alert_close(id){
105
- var element = document.getElementById('sucuri-alert-'+id);
106
- element.parentNode.removeChild(element);
107
- }
108
- </script>
109
- <?php }
110
  add_action( 'admin_enqueue_scripts', 'sucuriscan_admin_script_style_registration', 1 );
111
 
112
  /**
@@ -135,7 +133,7 @@ function sucuriscan_menu()
135
  add_submenu_page('sucuriscan', 'Sucuri Scanner', 'Sucuri Scanner', 'manage_options',
136
  'sucuriscan', 'sucuri_scan_page');
137
 
138
- add_submenu_page('sucuriscan', '1-click Hardening', '1-click Hardening', 'manage_options',
139
  'sucuriscan_hardening', 'sucuriscan_hardening_page');
140
 
141
  add_submenu_page('sucuriscan', 'WordPress Integrity', 'WordPress Integrity', 'manage_options',
@@ -204,7 +202,7 @@ function sucuriscan_send_mail($to='', $subject='', $message='', $data_set=array(
204
  }
205
 
206
  /**
207
- * Prints a HTML alert in the Wordpress admin interface.
208
  *
209
  * @param string $type The type of alert, it can be either Updated or Error.
210
  * @param string $message The message that will be printed in the alert.
@@ -257,38 +255,107 @@ function sucuriscan_prettify_mail($subject='', $message='', $data_set=array())
257
  * by the dynamic variables provided by the developer through one of the parameters
258
  * of the function.
259
  *
260
- * @param string $template Filename of the template that will be used to generate the page.
261
- * @param array $template_variables A hash containing the pseudo-variable name as the key and the value that will replace it.
262
- * @return string The formatted HTML page after replace all the pseudo-variables.
 
263
  */
264
- function sucuriscan_get_template($template='', $template_variables=array()){
 
 
 
 
 
 
 
 
 
 
265
  $template_content = '';
266
- $template_path = WP_PLUGIN_DIR.'/'.SUCURISCAN_PLUGIN_FOLDER."/inc/tpl/{$template}";
 
267
 
268
  if( file_exists($template_path) && is_readable($template_path) ){
269
  $template_content = file_get_contents($template_path);
270
- foreach($template_variables as $tpl_key=>$tpl_value){
 
 
 
 
 
 
271
  $template_content = str_replace("%%SUCURI.{$tpl_key}%%", $tpl_value, $template_content);
272
  }
273
  }
274
- return $template_content;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  }
276
 
277
  /**
278
- * Get the HTML content of the sidebar for the plugin interface.
 
 
279
  *
280
- * @return string HTML of the side for the plugin interface.
 
 
281
  */
282
- function sucuriscan_wp_sidebar_gen()
283
- {
284
- return sucuriscan_get_template('sidebar.html.tpl');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  }
286
 
287
  /**
288
- * Retrieve a new set of keys for the Wordpress configuration file using the
289
- * official API provided by Wordpress itself.
290
  *
291
- * @return array A list of the new set of keys generated by Wordpress API.
292
  */
293
  function sucuriscan_get_new_config_keys()
294
  {
@@ -306,8 +373,8 @@ function sucuriscan_get_new_config_keys()
306
  }
307
 
308
  /**
309
- * Modify the Wordpress configuration file and change the keys that were defined
310
- * by a new random-generated list of keys retrieved from the official Wordpress
311
  * API. The result of the operation will be either FALSE in case of error, or an
312
  * array containing multiple indexes explaining the modification, among them you
313
  * will find the old and new keys.
@@ -439,7 +506,7 @@ function sucuriscan_is_behind_cloudproxy(){
439
  /**
440
  * Check whether the current site is working as a multi-site instance.
441
  *
442
- * @return boolean Either TRUE or FALSE in case Wordpress is being used as a multi-site instance.
443
  */
444
  function sucuriscan_is_multisite(){
445
  if( function_exists('is_multisite') && is_multisite() ){ return TRUE; }
@@ -447,9 +514,9 @@ function sucuriscan_is_multisite(){
447
  }
448
 
449
  /**
450
- * Find and retrieve the absolute path of the Wordpress configuration file.
451
  *
452
- * @return string Absolute path of the Wordpress configuration file.
453
  */
454
  function sucuriscan_get_wpconfig_path(){
455
  $wp_config_path = ABSPATH.'wp-config.php';
@@ -462,9 +529,9 @@ function sucuriscan_get_wpconfig_path(){
462
  }
463
 
464
  /**
465
- * Find and retrieve the absolute path of the main Wordpress htaccess file.
466
  *
467
- * @return string Absolute path of the main Wordpress htaccess file.
468
  */
469
  function sucuriscan_get_htaccess_path(){
470
  $base_dirs = array(
@@ -518,24 +585,18 @@ function sucuriscan_time_ago($timestamp=0){
518
  *
519
  * @return void
520
  */
521
- function sucuri_scan_page()
522
- {
523
  $U_ERROR = NULL;
524
  if( !current_user_can('manage_options') ){
525
  wp_die(__('You do not have sufficient permissions to access this page: Sucuri Malware Scanner') );
526
  }
527
 
528
- $template_variables = array(
529
- 'PluginURL'=>SUCURI_URL,
530
- 'Sidebar'=>sucuriscan_get_template('sidebar.html.tpl')
531
- );
532
-
533
  if( isset($_POST['wpsucuri-doscan']) ){
534
  sucuriscan_print_scan();
535
  return(1);
536
  }
537
 
538
- echo sucuriscan_get_template('initial-page.html.tpl', $template_variables);
539
  }
540
 
541
  /**
@@ -543,53 +604,81 @@ function sucuri_scan_page()
543
  *
544
  * @return void
545
  */
546
- function sucuriscan_print_scan()
547
- {
548
  $website_scanned = home_url();
549
  $remote_url = 'http://sitecheck.sucuri.net/scanner/?serialized&clear&fromwp&scan='.$website_scanned;
550
- $myresults = wp_remote_get($remote_url, array('timeout' => 180));
 
551
  ?>
552
- <div class="wrap">
553
- <h2 id="warnings_hook"></h2>
554
- <div class="sucuriscan_header">
555
- <a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">
556
- <img src="<?php echo SUCURI_URL; ?>/inc/images/logo.png" alt="Sucuri Security" />
557
- </a>
558
- <?php sucuriscan_pagestop('Sucuri SiteCheck Malware Scanner'); ?>
 
 
 
 
559
  </div>
560
 
561
- <div class="postbox-container sucuriscan-results" style="width:75%;">
562
- <div class="sucuriscan-maincontent">
563
- <?php if( is_wp_error($myresults) ){ ?>
564
- <div id="poststuff">
565
- <div class="postbox">
566
- <h3>Error retrieving the scan report</h3>
567
- <div class="inside">
568
- <?php print_r($myresults); ?>
569
- </div>
570
- </div>
571
- </div>
572
- <?php
573
- }else if( preg_match('/^ERROR:/', $myresults['body']) ){
574
- sucuriscan_admin_notice('error', $myresults['body'].' The URL scanned was: <code>'.$website_scanned.'</code>');
575
- }else{
576
- $res = unserialize($myresults['body']);
577
 
578
- // Check for general warnings, and return the information for Infected/Clean site.
579
- $malware_warns_exists = isset($res['MALWARE']['WARN']) ? TRUE : FALSE;
580
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
581
  <div id="poststuff">
582
- <div class="postbox">
583
  <h3>
584
- <?php if( !$malware_warns_exists ): ?>
585
- <img src="<?php echo SUCURI_URL; ?>/inc/images/ok.png" class="icon-ok" /> &nbsp;
586
- No malware was identified
587
- <?php else: ?>
588
- <img src="<?php echo SUCURI_URL; ?>/inc/images/warn.png" class="icon-warn" /> &nbsp;
589
  Site compromised (malware was identified)
 
 
590
  <?php endif; ?>
591
  </h3>
 
592
  <div class="inside">
 
593
  <?php if( !$malware_warns_exists ): ?>
594
  <span><strong>Malware:</strong> No.</span><br>
595
  <span><strong>Malicious javascript:</strong> No.</span><br>
@@ -609,34 +698,140 @@ function sucuriscan_print_scan()
609
  }
610
  ?>
611
  <?php endif; ?>
612
- <br />
613
- <i>
614
- More details here: <a href="http://sitecheck.sucuri.net/scanner/?scan=<?php echo $website_scanned; ?>">
615
- http://sitecheck.sucuri.net/scanner/?scan=<?php echo $website_scanned; ?></a>
616
- </i>
617
- <hr />
618
- <i>
619
- If our free scanner did not detect any issue, you may have a more complicated and hidden
620
- problem. You can try our <a href="admin.php?page=sucuriscan_core_integrity">WordPress integrity
621
- checks</a> or sign up with Sucuri <a target="_blank" href="http://sucuri.net/signup">here</a>
622
- for a complete and in depth scan+cleanup (not included in the free checks).
623
- </i>
624
- <hr />
 
 
625
  </div>
626
  </div>
627
  </div>
 
628
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
629
  <div id="poststuff">
630
- <div class="postbox">
631
  <h3>
632
- <?php if( isset($res['BLACKLIST']['WARN']) ): ?>
633
- <img src="<?php echo SUCURI_URL; ?>/inc/images/warn.png" class="icon-warn" /> &nbsp;
634
  Site blacklisted
635
  <?php else: ?>
636
- <img src="<?php echo SUCURI_URL; ?>/inc/images/ok.png" class="icon-ok" /> &nbsp;
637
  Site blacklist-free
638
  <?php endif; ?>
639
  </h3>
 
640
  <div class="inside">
641
  <?php
642
  foreach(array(
@@ -655,142 +850,88 @@ function sucuriscan_print_scan()
655
  </div>
656
  </div>
657
  </div>
 
 
 
658
 
659
- <?php
660
- global $wp_version;
661
- $wordpress_updated = FALSE;
662
- $updates = function_exists('get_core_updates') ? get_core_updates() : array();
663
- if( !is_array($updates) || empty($updates) || $updates[0]->response=='latest' ){
664
- $wordpress_updated = TRUE;
665
- }
666
- ?>
667
- <div id="poststuff">
668
- <div class="postbox">
669
- <h3>
670
- <?php if($wordpress_updated): ?>
671
- <img src="<?php echo SUCURI_URL; ?>/inc/images/ok.png" class="icon-ok" /> &nbsp;
672
- System info (WordPress upgraded)
673
- <?php else: ?>
674
- <img src="<?php echo SUCURI_URL; ?>/inc/images/warn.png" class="icon-warn" /> &nbsp;
675
- System info (WordPress outdated)
676
- <?php endif; ?>
677
- </h3>
678
- <div class="inside">
679
- <b>Site:</b> <?php echo $res['SCAN']['SITE'][0]; ?> (<?php echo $res['SCAN']['IP'][0]; ?>)<br />
680
- <b>PHP (version installed): </b> <?php echo phpversion(); ?><br />
681
- <b>WordPress (installed):</b> <?php echo $wp_version; ?><br />
682
- <?php if( !$wordpress_updated ): ?>
683
- <b>WordPress (update):</b> <?php echo $updates[0]->version; ?><br />
684
- <a href="<?php echo admin_url('update-core.php'); ?>" class="button button-primary">Update</a>
685
- <?php endif; ?>
686
- <?php
687
- if( isset($res['SYSTEM']['NOTICE']) ){
688
- foreach( $res['SYSTEM']['NOTICE'] as $notres ){
689
- if( is_array($notres) ){
690
- echo htmlspecialchars($notres[0]).chr(32).htmlspecialchars($notres[1]);
691
- }else{
692
- echo htmlspecialchars($notres)."<br />\n";
693
- }
694
- }
695
- }
696
- ?>
697
- </div>
698
- </div>
699
- </div>
700
- <?php } ?>
701
-
702
- <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>
703
- </div><!-- End sucuriscan-maincontent -->
704
- </div><!-- End postbox-container -->
705
 
706
- <?php echo sucuriscan_get_template('sidebar.html.tpl') ?>
707
 
708
- </div><!-- End Wrap -->
709
 
710
  <?php
 
 
 
 
 
 
 
 
711
  }
712
 
713
  /**
714
- * Wordpress core integrity page.
715
  *
716
- * It checks whether the Wordpress core files are the original ones, and the state
717
  * of the themes and plugins reporting the availability of updates. It also checks
718
  * the user accounts under the administrator group.
719
  *
720
  * @return void
721
  */
722
- function sucuriscan_core_integrity_page(){ ?>
723
 
724
- <div class="wrap">
725
- <h2 id="warnings_hook"></h2>
726
- <div class="sucuriscan_header">
727
- <a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">
728
- <img src="<?php echo SUCURI_URL; ?>/inc/images/logo.png" alt="Sucuri Security" />
729
- </a>
730
- <h2>Sucuri Security WordPress Plugin (WordPress Integrity)</h2>
731
- </div>
732
 
733
- <?php
734
- if(!current_user_can('manage_options'))
735
- {
736
- wp_die(__('You do not have sufficient permissions to access this page: Sucuri Integrity Check') );
737
  }
738
- ?>
739
 
740
- <div class="postbox-container" style="width:75%;">
741
- <div class="sucuriscan-maincontent">
742
- <?php
743
- if( isset($_POST['wpsucuri-core-integrity']) ){
744
- if(!wp_verify_nonce($_POST['sucuriscan_core_integritynonce'], 'sucuriscan_core_integritynonce'))
745
- {
746
- unset($_POST['wpsucuri-core_integrity']);
747
- }
748
- }
749
- ?>
750
 
751
- <div id="poststuff">
752
- <?php
753
- sucuriscan_core_integrity_function_wrapper(
754
- 'sucuriwp_core_integrity_check',
755
- 'Verify Integrity of WordPress Core Files',
756
- 'This test will check wp-includes, wp-admin, and the top directory files against the latest WordPress
757
- hashing database. If any of those files were modified, it is a big sign of a possible compromise.'
758
- );
759
-
760
- sucuriscan_core_integrity_wp_content_wrapper();
761
-
762
- sucuriscan_core_integrity_function_wrapper(
763
- 'sucuriwp_list_admins',
764
- 'Admin User Dump',
765
- 'List all administrator users and their latest login time.'
766
- );
767
-
768
- sucuriscan_core_integrity_function_wrapper(
769
- 'sucuriwp_check_plugins',
770
- 'Outdated Plugin list',
771
- 'This test will list any outdated (active) plugins.'
772
- );
773
-
774
- sucuriscan_core_integrity_function_wrapper(
775
- 'sucuriwp_check_themes',
776
- 'Outdated Theme List',
777
- 'This test will list any outdated theme.'
778
- );
779
- ?>
780
- </div>
781
 
782
- <p align="center">
783
- <strong>If you have any questions about these tests or this plugin, contact us at <a href="mailto:info@sucuri.net">
784
- info@sucuri.net</a> or visit <a href="http://sucuri.net">Sucuri Security</a></strong>
785
- </p>
786
- </div><!-- End sucuriscan-maincontent -->
787
- </div><!-- End postbox-container -->
788
 
789
- <?php echo sucuriscan_get_template('sidebar.html.tpl') ?>
 
 
 
 
790
 
791
- </div><!-- End Wrap -->
 
 
 
 
 
 
792
 
793
  <?php
 
 
 
 
 
 
 
 
794
  }
795
 
796
  /**
@@ -804,17 +945,18 @@ function sucuriscan_core_integrity_page(){ ?>
804
  */
805
  function sucuriscan_core_integrity_function_wrapper($function_name='', $stitle='', $description=''){ ?>
806
  <div class="postbox">
807
- <h3><?php echo $stitle; ?></h3>
 
808
  <div class="inside">
809
  <form method="post">
810
- <input type="hidden" name="<?php echo $function_name; ?>nonce" value="<?php echo wp_create_nonce($function_name.'nonce'); ?>" />
811
- <input type="hidden" name="<?php echo $function_name; ?>" value="1" />
812
- <p><?php echo $description; ?></p>
813
- <input class="button-primary" type="submit" name="<?php echo $function_name; ?>" value="Check" />
814
  </form>
815
- <br />
816
  <?php
817
- if (isset($_POST[$function_name.'nonce']) && isset($_POST[$function_name])) {
818
  if( function_exists($function_name) ){
819
  $function_name();
820
  }
@@ -855,8 +997,7 @@ function sucuriscan_core_integrity_wp_content_wrapper(){ ?>
855
  // && wp_verify_nonce($_POST['sucuriwp_content_checknonce'], 'sucuriwp_content_checknonce')
856
  && isset($_POST['sucuriwp_content_check'])
857
  ): ?>
858
- <br />
859
- <table class="wp-list-table widefat sucuriscan-lastmodified">
860
  <thead>
861
  <tr>
862
  <th colspan="2">wp_content latest modified files</th>
@@ -871,11 +1012,14 @@ function sucuriscan_core_integrity_wp_content_wrapper(){ ?>
871
  $wp_content_hashes = read_dir_r(ABSPATH.'wp-content', true);
872
  $days = htmlspecialchars(trim((int)$_POST['sucuriwp_content_check_back']));
873
  $back_days = current_time( 'timestamp' ) - ( $days * 86400);
 
874
 
875
  foreach ( $wp_content_hashes as $key => $value) {
876
  if ($value['time'] >= $back_days ){
 
877
  $date = date('d-m-Y H:i:s', $value['time']);
878
- printf('<tr><td>%s</td><td>%s</td></tr>', $key, $date);
 
879
  }
880
  }
881
  ?>
@@ -894,8 +1038,7 @@ function sucuriscan_core_integrity_wp_content_wrapper(){ ?>
894
  * @param boolean $recursiv Either TRUE or FALSE if the scan should be performed recursively.
895
  * @return array List of arrays containing the md5sum and last modification time of the files found.
896
  */
897
- function read_dir_r($dir = "./", $recursiv = false)
898
- {
899
  $skipname = basename(__FILE__);
900
  $skipname .= ",_sucuribackup,wp-config.php";
901
 
@@ -904,31 +1047,32 @@ function read_dir_r($dir = "./", $recursiv = false)
904
  $dir_handler = opendir($dir);
905
 
906
  while(($entry = readdir($dir_handler)) !== false) {
907
- if ($entry != "." && $entry != "..") {
908
- $dir = preg_replace("/^(.*)(\/)+$/", "$1", $dir);
909
- $item = $dir . "/" . $entry;
910
- if (is_file($item)) {
911
-
912
- $skip_parts = explode(",", $skipname);
913
- foreach ($skip_parts as $skip) {
914
- if (strpos($item,$skip) !== false) {
915
- continue 2;
 
 
916
  }
917
- }
918
 
919
- $md5 = @md5_file($item);
920
- $time_stamp = @filectime($item);
921
- $item_name = str_replace(ABSPATH, "./", $item);
922
- $files_info[$item_name] = array(
923
- 'md5' => $md5,
924
- 'time' => $time_stamp
925
- );
 
926
 
927
- }
928
- elseif (is_dir($item) && $recursiv) {
929
- $files_info = array_merge( $files_info , read_dir_r($item) );
930
- }
931
- }
932
  }
933
 
934
  closedir($dir_handler);
@@ -938,12 +1082,11 @@ function read_dir_r($dir = "./", $recursiv = false)
938
  /**
939
  * Compare the md5sum of the core files in the current site with the hashes hosted
940
  * remotely in Sucuri servers. These hashes are updated every time a new version
941
- * of Wordpress is released.
942
  *
943
  * @return void
944
  */
945
- function sucuriwp_core_integrity_check()
946
- {
947
 
948
  global $wp_version;
949
 
@@ -983,20 +1126,23 @@ function sucuriwp_core_integrity_check()
983
  }
984
 
985
  /**
986
- * List all the Wordpress core files modified until now.
987
  *
988
- * @param array $list List of Wordpress core files modified.
989
  * @return void
990
  */
991
  function sucuriscan_draw_corefiles_status($list=array()){
992
  if( is_array($list) && !empty($list) ): ?>
993
- <table class="wp-list-table widefat sucuriscan-corefiles">
994
  <tbody>
995
  <?php
996
- foreach($list as $diff_type=>$file_list){
 
997
  printf('<tr><th>Core File %s: %d</th></tr>', ucwords($diff_type), sizeof($file_list));
998
  foreach($file_list as $filepath){
999
- printf('<tr><td>%s</td></tr>', $filepath);
 
 
1000
  }
1001
  }
1002
  ?>
@@ -1006,47 +1152,40 @@ function sucuriscan_draw_corefiles_status($list=array()){
1006
  <?php }
1007
 
1008
  /**
1009
- * List all the user accounts under the user level specified, by default the
1010
- * users analyzed are the administrator accounts.
 
1011
  *
1012
- * @param string $userlevel Identifier of the user level that will be filtered in the search.
1013
  * @return void
1014
  */
1015
- function sucuriwp_list_admins($userlevel = '10') {
1016
 
1017
  global $wpdb;
1018
- /*
1019
- 1 = subscriber
1020
- 2 = editor
1021
- 3 = author
1022
- 7 = publisher
1023
- 10 = administrator
1024
- */
1025
 
1026
  // Page pseudo-variables initialization.
1027
  $template_variables = array(
1028
- 'SucuriURL'=>SUCURI_URL,
1029
  'AdminUsers.UserList'=>''
1030
  );
1031
 
1032
- $admins = $wpdb->get_results("SELECT DISTINCT(user_id) AS user_id FROM `$wpdb->usermeta` WHERE meta_value = '$userlevel'");
1033
- foreach ( (array) $admins as $user ) {
1034
- $admin = get_userdata( $user->user_id );
1035
- $admin->lastlogins = sucuriscan_get_logins(4, $admin->ID);
1036
- $userlevel = $admin->wp2_user_level;
1037
- $name = $admin->nickname;
1038
 
1039
  $user_snippet = array(
1040
  'AdminUsers.Username'=>$admin->user_login,
1041
  'AdminUsers.Email'=>$admin->user_email,
1042
  'AdminUsers.LastLogins'=>'',
1043
- 'AdminUsers.UserURL'=>admin_url('user-edit.php?user_id='.$user->user_id)
1044
  );
 
1045
  if( !empty($admin->lastlogins) ){
1046
  $user_snippet['AdminUsers.NoLastLogins'] = 'hidden';
1047
  $user_snippet['AdminUsers.NoLastLoginsTable'] = 'visible';
 
1048
  foreach($admin->lastlogins as $lastlogin){
1049
- $user_snippet['AdminUsers.LastLogins'] .= sucuriscan_get_template('integrity-admins-lastlogin.snippet.tpl', array(
1050
  'AdminUsers.RemoteAddr'=>$lastlogin->user_remoteaddr,
1051
  'AdminUsers.Datetime'=>$lastlogin->user_lastlogin
1052
  ));
@@ -1056,91 +1195,106 @@ function sucuriwp_list_admins($userlevel = '10') {
1056
  $user_snippet['AdminUsers.NoLastLoginsTable'] = 'hidden';
1057
  }
1058
 
1059
- $template_variables['AdminUsers.UserList'] .= sucuriscan_get_template('integrity-admins.snippet.tpl', $user_snippet);
1060
  }
1061
 
1062
- echo sucuriscan_get_template('integrity-admins.html.tpl', $template_variables);
1063
  }
1064
 
1065
  /**
1066
- * Check if any installed plugin has an update available.
1067
  *
1068
  * @return void
1069
  */
1070
- function sucuriwp_check_plugins()
1071
- {
1072
- do_action("wp_update_plugins"); // force WP to check plugins for updates
1073
- wp_update_plugins();
1074
- $update_plugins = get_site_transient('update_plugins'); // get information of updates
1075
- $plugins_need_update = $update_plugins->response; // plugins that need updating
1076
-
1077
- echo '<div class="postbox">';
1078
- echo "<h3>Outdated Plugins</h3>";
1079
- echo '<div class="inside">';
1080
- if (!empty($update_plugins->response)) { // any plugin updates available?
1081
- $plugins_need_update = $update_plugins->response; // plugins that need updating
1082
- $active_plugins = array_flip(get_option('active_plugins')); // find which plugins are active
1083
- $plugins_need_update = array_intersect_key($plugins_need_update, $active_plugins); // only keep plugins that are active
1084
- if(count($plugins_need_update) >= 1) { // any plugins need updating after all the filtering gone on above?
1085
- require_once(ABSPATH . 'wp-admin/includes/plugin-install.php'); // Required for plugin API
1086
- require_once(ABSPATH . WPINC . '/version.php' ); // Required for WP core version
1087
- foreach($plugins_need_update as $key => $data) { // loop through the plugins that need updating
1088
- $plugin_info = get_plugin_data(WP_PLUGIN_DIR . "/" . $key); // get local plugin info
1089
- $info = plugins_api('plugin_information', array('slug' => $data->slug )); // get repository plugin info
1090
- $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";
1091
- echo "<p>$message</p>";
1092
- }
1093
- }
1094
- else
1095
- {
1096
- echo "<p>All plugins are up-to-date!</p>";
1097
- }
1098
- }
1099
- else
1100
- {
1101
- echo "<p>All plugins are up-to-date!</p>";
1102
- }
1103
- echo '</div>';
1104
- echo '</div>';
1105
- }
1106
 
1107
- /**
1108
- * Check if any installed theme has an update available.
1109
- *
1110
- * @return void
1111
- */
1112
- function sucuriwp_check_themes()
1113
- {
1114
- do_action("wp_update_themes"); // force WP to check for theme updates
1115
- wp_update_themes();
1116
- $update_themes = get_site_transient('update_themes'); // get information of updates
1117
-
1118
- echo '<div class="postbox">';
1119
- echo "<h3>Outdated Themes</h3>";
1120
- echo '<div class="inside">';
1121
- if (!empty($update_themes->response)) { // any theme updates available?
1122
- $themes_need_update = $update_themes->response; // themes that need updating
1123
-
1124
- if(count($themes_need_update) >= 1) { // any themes need updating after all the filtering gone on above?
1125
- foreach($themes_need_update as $key => $data) { // loop through the themes that need updating
1126
- $theme_info = get_theme_data(WP_CONTENT_DIR . "/themes/" . $key . "/style.css"); // get theme info
1127
- $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";
1128
- echo "<p>$message</p>";
1129
- }
1130
- }
1131
- }
1132
- else
1133
- {
1134
- echo "<p>All themes are up-to-date!</p>";
1135
- }
1136
- echo '</div>';
1137
- echo '</div>';
1138
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1139
 
1140
  /**
1141
- * Retrieve a list with the checksums of the files in a specific version of Wordpress.
1142
  *
1143
- * @param integer $version Valid version number of the Wordpress project.
1144
  * @return object Associative object with the relative filepath and the checksums of the project files.
1145
  */
1146
  function sucuriscan_get_official_checksums($version=0){
@@ -1158,18 +1312,18 @@ function sucuriscan_get_official_checksums($version=0){
1158
  }
1159
 
1160
  /**
1161
- * Check whether the core Wordpress files where modified, removed or if any file
1162
  * was added to the core folders. This function returns an associative array with
1163
  * these keys:
1164
  *
1165
  * <ul>
1166
- * <li>bad: Files with a different checksum according to the official files of the Wordpress version filtered,</li>
1167
  * <li>good: Files with the same checksums than the official files,</li>
1168
  * <li>removed: Official files which are not present in the local project,</li>
1169
- * <li>added: Files present in the local project but not in the official Wordpress packages.</li>
1170
  * </ul>
1171
  *
1172
- * @param integer $version Valid version number of the Wordpress project.
1173
  * @return array Associative array with these keys: bad, good, removed, added.
1174
  */
1175
  function sucuriscan_check_wp_integrity($version=0){
@@ -1219,64 +1373,47 @@ function sucuriscan_check_wp_integrity($version=0){
1219
  *
1220
  * @return void
1221
  */
1222
- function sucuriscan_hardening_page(){ ?>
1223
 
1224
- <div class="wrap">
1225
- <h2 id="warnings_hook"></h2>
1226
- <div class="sucuriscan_header">
1227
- <a href="http://sucuri.net/signup" target="_blank" title="Sucuri Security">
1228
- <img src="<?php echo SUCURI_URL; ?>/inc/images/logo.png" alt="Sucuri Security" />
1229
- </a>
1230
- <h2>Sucuri Security WordPress Plugin (1-Click Hardening)</h2>
1231
- </div>
1232
 
1233
- <?php
1234
- if(!current_user_can('manage_options'))
1235
- {
1236
- wp_die(__('You do not have sufficient permissions to access this page: Sucuri Hardening') );
1237
  }
1238
- ?>
1239
-
1240
- <div class="postbox-container" style="width:75%">
1241
- <div class="sucuriscan-maincontent">
1242
- <?php
1243
- if( isset($_POST['wpsucuri-doharden']) ){
1244
- if(!wp_verify_nonce($_POST['sucuriscan_wphardeningnonce'], 'sucuriscan_wphardeningnonce'))
1245
- {
1246
- unset($_POST['wpsucuri-doharden']);
1247
- }
1248
- }
1249
- ?>
1250
-
1251
- <div id="poststuff">
1252
- <form method="post">
1253
- <input type="hidden" name="sucuriscan_wphardeningnonce" value="<?php echo wp_create_nonce('sucuriscan_wphardeningnonce'); ?>" />
1254
- <input type="hidden" name="wpsucuri-doharden" value="wpsucuri-doharden" />
1255
- <?php
1256
- sucuriscan_harden_version();
1257
- sucuriscan_cloudproxy_enabled();
1258
- sucuri_harden_removegenerator();
1259
- sucuriscan_harden_upload();
1260
- sucuriscan_harden_wpcontent();
1261
- sucuriscan_harden_wpincludes();
1262
- sucuriscan_harden_phpversion();
1263
- ?>
1264
- </form>
1265
 
1266
- <p align="center">
1267
- <strong>If you have any questions about these checks or this plugin, contact us at
1268
- <a href="mailto:info@sucuri.net">info@sucuri.net</a> or visit <a href="http://sucuri.net">
1269
- Sucuri Security</a></strong>
1270
- </p>
1271
- </div><!-- End poststuff -->
1272
- </div><!-- End sucuriscan-maincontent -->
1273
- </div><!-- End postbox-container -->
1274
 
1275
- <?php echo sucuriscan_get_template('sidebar.html.tpl') ?>
 
 
 
1276
 
1277
- </div><!-- End Wrap -->
 
 
 
 
 
 
 
 
 
 
1278
 
1279
  <?php
 
 
 
 
 
 
 
 
1280
  }
1281
 
1282
  /**
@@ -1285,8 +1422,7 @@ function sucuriscan_hardening_page(){ ?>
1285
  * @param string $msg The title of the hardening option.
1286
  * @return void
1287
  */
1288
- function sucuriscan_wrapper_open($msg)
1289
- {
1290
  ?>
1291
  <div class="postbox">
1292
  <h3><?php echo $msg; ?></h3>
@@ -1299,8 +1435,7 @@ function sucuriscan_wrapper_open($msg)
1299
  *
1300
  * @return void
1301
  */
1302
- function sucuriscan_wrapper_close()
1303
- {
1304
  ?>
1305
  </div>
1306
  </div>
@@ -1313,8 +1448,7 @@ function sucuriscan_wrapper_close()
1313
  * @param string $message The text string that will be shown inside the error box.
1314
  * @return void
1315
  */
1316
- function sucuriscan_harden_error($message)
1317
- {
1318
  return('<div id="message" class="error"><p>'.$message.'</p></div>');
1319
  }
1320
 
@@ -1324,14 +1458,13 @@ function sucuriscan_harden_error($message)
1324
  * @param string $message The text string that will be shown inside the success box.
1325
  * @return void
1326
  */
1327
- function sucuriscan_harden_ok($message)
1328
- {
1329
  return( '<div id="message" class="updated"><p>'.$message.'</p></div>');
1330
  }
1331
 
1332
  /**
1333
  * Generate the HTML code necessary to show a form with the options to harden
1334
- * a specific part of the Wordpress installation, if the Status variable is
1335
  * set as a positive integer the button is shown as "unharden".
1336
  *
1337
  * @param integer $status Either one or zero representing the state of the hardening, one for secure, zero for insecure.
@@ -1365,13 +1498,12 @@ function sucuriscan_harden_status($status=0, $type='', $messageok='', $messagewa
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
 
1377
  $updates = get_core_updates();
@@ -1410,13 +1542,12 @@ function sucuriscan_harden_version()
1410
 
1411
  /**
1412
  * Notify the state of the hardening for the removal of the Generator tag in
1413
- * HTML code printed by Wordpress to show the current version number of the
1414
  * installation.
1415
  *
1416
  * @return void
1417
  */
1418
- function sucuri_harden_removegenerator()
1419
- {
1420
  /* Enabled by default with this plugin. */
1421
  $cp = 1;
1422
 
@@ -1432,16 +1563,15 @@ function sucuri_harden_removegenerator()
1432
  }
1433
 
1434
  /**
1435
- * Check whether the Wordpress upload folder is protected or not.
1436
  *
1437
  * A htaccess file is placed in the upload folder denying the access to any php
1438
  * file that could be uploaded through a vulnerability in a Plugin, Theme or
1439
- * Wordpress itself.
1440
  *
1441
  * @return void
1442
  */
1443
- function sucuriscan_harden_upload()
1444
- {
1445
  $cp = 1;
1446
  $upmsg = NULL;
1447
  $htaccess_upload = dirname(sucuriscan_dir_filepath())."/.htaccess";
@@ -1509,16 +1639,15 @@ function sucuriscan_harden_upload()
1509
  }
1510
 
1511
  /**
1512
- * Check whether the Wordpress content folder is protected or not.
1513
  *
1514
  * A htaccess file is placed in the content folder denying the access to any php
1515
  * file that could be uploaded through a vulnerability in a Plugin, Theme or
1516
- * Wordpress itself.
1517
  *
1518
  * @return void
1519
  */
1520
- function sucuriscan_harden_wpcontent()
1521
- {
1522
  $cp = 1;
1523
  $upmsg = NULL;
1524
  $htaccess_upload = ABSPATH."/wp-content/.htaccess";
@@ -1590,17 +1719,16 @@ function sucuriscan_harden_wpcontent()
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";
@@ -1674,8 +1802,7 @@ function sucuriscan_harden_wpincludes()
1674
  *
1675
  * @return void
1676
  */
1677
- function sucuriscan_harden_phpversion()
1678
- {
1679
  $phpv = phpversion();
1680
 
1681
  if(strncmp($phpv, "5.", 2) < 0)
@@ -1725,27 +1852,24 @@ function sucuriscan_cloudproxy_enabled(){
1725
  *
1726
  * @return void
1727
  */
1728
- function sucuriscan_posthack_page()
1729
- {
1730
- if( !current_user_can('manage_options') )
1731
- {
1732
  wp_die(__('You do not have sufficient permissions to access this page: Sucuri Post-Hack') );
1733
  }
1734
 
1735
  // Page pseudo-variables initialization.
1736
  $template_variables = array(
1737
- 'SucuriURL'=>SUCURI_URL,
1738
- 'PosthackNonce'=>wp_create_nonce('sucuri_posthack_nonce'),
1739
- 'SucuriWPSidebar'=>sucuriscan_wp_sidebar_gen(),
1740
- 'WPConfigUpdate.Display'=>'display:none',
1741
- 'WPConfigUpdate.NewConfig'=>'',
1742
- 'ResetPassword.UserList'=>''
1743
  );
1744
 
1745
  // Process form submission
1746
  if( isset($_POST['sucuri_posthack_action']) ){
1747
- if( !wp_verify_nonce($_POST['sucuri_posthack_nonce'], 'sucuri_posthack_nonce') )
1748
- {
1749
  wp_die(__('WordPress Nonce verification failed, try again going back and checking the form.') );
1750
  }
1751
 
@@ -1816,17 +1940,21 @@ function sucuriscan_posthack_page()
1816
  $user_list = get_users();
1817
  foreach($user_list as $user){
1818
  $counter += 1;
1819
- $user_snippet = sucuriscan_get_template('resetpassword.snippet.tpl', array(
1820
- 'ResetPassword.UserId'=>$user->ID,
1821
- 'ResetPassword.Username'=>$user->user_login,
1822
- 'ResetPassword.Displayname'=>$user->display_name,
1823
- 'ResetPassword.Email'=>$user->user_email,
1824
- 'ResetPassword.CssClass'=>( $counter%2 == 0 ) ? '' : 'alternate'
 
 
 
 
1825
  ));
1826
  $template_variables['ResetPassword.UserList'] .= $user_snippet;
1827
  }
1828
 
1829
- echo sucuriscan_get_template('posthack.html.tpl', $template_variables);
1830
  }
1831
 
1832
  /**
@@ -1836,21 +1964,17 @@ function sucuriscan_posthack_page()
1836
  *
1837
  * @return void
1838
  */
1839
- function sucuriscan_lastlogins_page()
1840
- {
1841
- if( !current_user_can('manage_options') )
1842
- {
1843
  wp_die(__('You do not have sufficient permissions to access this page: Sucuri Last-Logins') );
1844
  }
1845
 
1846
  // Page pseudo-variables initialization.
1847
  $template_variables = array(
1848
- 'SucuriURL'=>SUCURI_URL,
1849
- 'LastLoginsNonce'=>wp_create_nonce('sucuriscan_lastlogins_nonce'),
1850
- 'SucuriWPSidebar'=>sucuriscan_wp_sidebar_gen(),
1851
- 'UserList'=>'',
1852
- 'UserListLimit'=>SUCURISCAN_LASTLOGINS_USERSLIMIT,
1853
- 'CurrentURL'=>site_url().'/wp-admin/admin.php?page='.$_GET['page'],
1854
  );
1855
 
1856
  if( !sucuriscan_lastlogins_datastore_is_writable() ){
@@ -1866,20 +1990,24 @@ function sucuriscan_lastlogins_page()
1866
  $user_list = sucuriscan_get_logins($limit);
1867
  foreach($user_list as $user){
1868
  $counter += 1;
1869
- $user_snippet = sucuriscan_get_template('lastlogins.snippet.tpl', array(
1870
- 'UserList.Number'=>$counter,
1871
- 'UserList.UserId'=>intval($user->ID),
1872
- 'UserList.Username'=>( !is_null($user->user_login) ? $user->user_login : '<em>Unknown</em>' ),
1873
- 'UserList.Email'=>$user->user_email,
1874
- 'UserList.RemoteAddr'=>$user->user_remoteaddr,
1875
- 'UserList.Datetime'=>$user->user_lastlogin,
1876
- 'UserList.TimeAgo'=>sucuriscan_time_ago($user->user_lastlogin),
1877
- 'UserList.CssClass'=>( $counter%2 == 0 ) ? '' : 'alternate'
 
 
 
 
1878
  ));
1879
  $template_variables['UserList'] .= $user_snippet;
1880
  }
1881
 
1882
- echo sucuriscan_get_template('lastlogins.html.tpl', $template_variables);
1883
  }
1884
 
1885
  /**
@@ -1957,11 +2085,11 @@ if( !function_exists('sucuri_set_lastlogin') ){
1957
  $remote_addr = sucuriscan_get_remoteaddr();
1958
 
1959
  $login_info = array(
1960
- 'user_id'=>$current_user->ID,
1961
- 'user_login'=>$current_user->user_login,
1962
- 'user_remoteaddr'=>$remote_addr,
1963
- 'user_hostname'=>@gethostbyaddr($remote_addr),
1964
- 'user_lastlogin'=>current_time('mysql')
1965
  );
1966
 
1967
  @file_put_contents($datastore_filepath, serialize($login_info)."\n", FILE_APPEND);
@@ -2026,9 +2154,9 @@ if( !function_exists('sucuri_login_redirect') ){
2026
  * Hook for the wp-login action to redirect the user to a specific URL after
2027
  * his successfully login to the administrator interface.
2028
  *
2029
- * @param string $redirect_to URL where the browser must be originally redirected to, set by Wordpress itself.
2030
- * @param object $request Optional parameter set by Wordpress itself through the event triggered.
2031
- * @param boolean $user Wordpress user object with the information of the account involved in the operation.
2032
  * @return string URL where the browser must be redirected to.
2033
  */
2034
  function sucuriscan_login_redirect($redirect_to='', $request=NULL, $user=FALSE){
@@ -2076,29 +2204,26 @@ if( !function_exists('sucuri_get_user_lastlogin') ){
2076
  * @return void
2077
  */
2078
  function sucuriscan_infosys_page(){
2079
- if( !current_user_can('manage_options') )
2080
- {
2081
  wp_die(__('You do not have sufficient permissions to access this page: Sucuri Last-Logins') );
2082
  }
2083
 
2084
  // Page pseudo-variables initialization.
2085
  $template_variables = array(
2086
- 'SucuriURL'=>SUCURI_URL,
2087
- 'SucuriWPSidebar'=>sucuriscan_wp_sidebar_gen(),
2088
- 'CurrentURL'=>site_url().'/wp-admin/admin.php?page='.$_GET['page']
 
 
 
2089
  );
2090
 
2091
- $template_variables['LoggedInUsers'] = sucuriscan_infosys_loggedin();
2092
- $template_variables['Cronjobs'] = sucuriscan_show_cronjobs();
2093
- $template_variables['HTAccessIntegrity'] = sucuriscan_infosys_htaccess();
2094
- $template_variables['WordpressConfig'] = sucuriscan_infosys_wpconfig();
2095
-
2096
- echo sucuriscan_get_template('infosys.html.tpl', $template_variables);
2097
  }
2098
 
2099
  /**
2100
  * Find the main htaccess file for the site and check whether the rules of the
2101
- * main htaccess file of the site are the default rules generated by Wordpress.
2102
  *
2103
  * @return string The HTML code displaying the information about the HTAccess rules.
2104
  */
@@ -2138,12 +2263,12 @@ function sucuriscan_infosys_htaccess(){
2138
  $template_variables['HTAccess.MessageVisible'] = 'visible';
2139
  }
2140
 
2141
- return sucuriscan_get_template('infosys-htaccess.html.tpl', $template_variables);
2142
  }
2143
 
2144
  /**
2145
  * Check whether the rules in a htaccess file are the default options generated
2146
- * by Wordpress or if the file has custom options added by other Plugins.
2147
  *
2148
  * @param string $rules Optional parameter containing a text string with the content of the main htaccess file.
2149
  * @return boolean Either TRUE or FALSE if the rules found in the htaccess file specified are the default ones or not.
@@ -2188,7 +2313,7 @@ function sucuriscan_htaccess_is_standard($rules=FALSE){
2188
 
2189
  /**
2190
  * Retrieve all the constants and variables with their respective values defined
2191
- * in the Wordpress configuration file, only the database password constant is
2192
  * omitted for security reasons.
2193
  *
2194
  * @return string The HTML code displaying the constants and variables found in the wp-config file.
@@ -2198,8 +2323,14 @@ function sucuriscan_infosys_wpconfig(){
2198
  'WordpressConfig.Rules' => '',
2199
  'WordpressConfig.Total' => 0,
2200
  'WordpressConfig.Content' => '',
 
2201
  );
2202
  $ignore_wp_rules = array('DB_PASSWORD');
 
 
 
 
 
2203
 
2204
  $wp_config_path = sucuriscan_get_wpconfig_path();
2205
  if( $wp_config_path ){
@@ -2253,7 +2384,7 @@ function sucuriscan_infosys_wpconfig(){
2253
  foreach( $wp_config_rules as $var_name=>$var_value ){
2254
  $counter += 1;
2255
  $template_variables['WordpressConfig.Total'] += 1;
2256
- $template_variables['WordpressConfig.Rules'] .= sucuriscan_get_template('infosys-wpconfig.snippet.tpl', array(
2257
  'WordpressConfig.VariableName' => $var_name,
2258
  'WordpressConfig.VariableValue' => htmlentities($var_value),
2259
  'WordpressConfig.CssClass' => ( $counter%2 == 0 ) ? '' : 'alternate'
@@ -2261,7 +2392,7 @@ function sucuriscan_infosys_wpconfig(){
2261
  }
2262
  }
2263
 
2264
- return sucuriscan_get_template('infosys-wpconfig.html.tpl', $template_variables);
2265
  }
2266
 
2267
  /**
@@ -2286,7 +2417,7 @@ function sucuriscan_infosys_loggedin(){
2286
  $logged_in_user['last_activity_datetime'] = date('d/M/Y H:i', $logged_in_user['last_activity']);
2287
  $logged_in_user['user_registered_datetime'] = date('d/M/Y H:i', strtotime($logged_in_user['user_registered']));
2288
 
2289
- $template_variables['LoggedInUsers.List'] .= sucuriscan_get_template('infosys-loggedin.snippet.tpl', array(
2290
  'LoggedInUsers.Id' => $logged_in_user['user_id'],
2291
  'LoggedInUsers.UserURL' => admin_url('user-edit.php?user_id='.$logged_in_user['user_id']),
2292
  'LoggedInUsers.UserLogin' => $logged_in_user['user_login'],
@@ -2299,7 +2430,7 @@ function sucuriscan_infosys_loggedin(){
2299
  }
2300
  }
2301
 
2302
- return sucuriscan_get_template('infosys-loggedin.html.tpl', $template_variables);
2303
  }
2304
 
2305
  /**
@@ -2396,7 +2527,7 @@ if( !function_exists('sucuriscan_set_online_user') ){
2396
  * Add an user account to the list of registered users in session.
2397
  *
2398
  * @param string $user_login The name of the user account that just logged in the site.
2399
- * @param boolean $user The Wordpress object containing all the information associated to the user.
2400
  * @return void
2401
  */
2402
  function sucuriscan_set_online_user($user_login='', $user=FALSE){
@@ -2481,7 +2612,7 @@ function sucuriscan_show_cronjobs(){
2481
  $counter += 1;
2482
  $cronjob_snippet = '';
2483
  $template_variables['Cronjobs.Total'] += 1;
2484
- $template_variables['Cronjobs.List'] .= sucuriscan_get_template('infosys-cronjobs.snippet.tpl', array(
2485
  'Cronjob.Task' => ucwords(str_replace('_',chr(32),$hook)),
2486
  'Cronjob.Schedule' => $event['schedule'],
2487
  'Cronjob.Nexttime' => date_i18n($date_format, $timestamp),
@@ -2493,34 +2624,7 @@ function sucuriscan_show_cronjobs(){
2493
  }
2494
  }
2495
 
2496
- return sucuriscan_get_template('infosys-cronjobs.html.tpl', $template_variables);
2497
- }
2498
-
2499
-
2500
- /**
2501
- * Print the HTML code for the plugin about page with information of the plugin,
2502
- * the scheduled tasks, and some settings from the PHP environment and server.
2503
- *
2504
- * @return void
2505
- */
2506
- function sucuriscan_about_page()
2507
- {
2508
- if( !current_user_can('manage_options') )
2509
- {
2510
- wp_die(__('You do not have sufficient permissions to access this page: Sucuri Last-Logins') );
2511
- }
2512
-
2513
- // Page pseudo-variables initialization.
2514
- $template_variables = array(
2515
- 'SucuriURL'=>SUCURI_URL,
2516
- 'SucuriWPSidebar'=>sucuriscan_wp_sidebar_gen(),
2517
- 'CurrentURL'=>site_url().'/wp-admin/admin.php?page='.$_GET['page'],
2518
- 'SettingsDisplay'=>'hidden'
2519
- );
2520
-
2521
- $template_variables = sucuriscan_about_information($template_variables);
2522
-
2523
- echo sucuriscan_get_template('about.html.tpl', $template_variables);
2524
  }
2525
 
2526
  /**
@@ -2529,8 +2633,7 @@ function sucuriscan_about_page()
2529
  * @param array $template_variables The hash for the template system, keys are pseudo-variables.
2530
  * @return array A list of pseudo-variables and values that will replace them in the HTML template.
2531
  */
2532
- function sucuriscan_about_information($template_variables=array())
2533
- {
2534
  global $wpdb;
2535
 
2536
  if( current_user_can('manage_options') ){
@@ -2541,7 +2644,7 @@ function sucuriscan_about_information($template_variables=array())
2541
  $plugin_runtime_filepath = sucuriscan_dir_filepath('.runtime');
2542
  $plugin_runtime_datetime = file_exists($plugin_runtime_filepath) ? date('r',filemtime($plugin_runtime_filepath)) : 'N/A';
2543
 
2544
- $template_variables = array_merge($template_variables, array(
2545
  'SettingsDisplay'=>'block',
2546
  'PluginVersion'=>SUCURISCAN_VERSION,
2547
  'PluginForceUpdate'=>admin_url('admin.php?page=sucurisec_settings&sucuri_force_update=1'),
@@ -2553,9 +2656,9 @@ function sucuriscan_about_information($template_variables=array())
2553
  'MySQLVersion'=>$mysql_version,
2554
  'SQLMode'=>$sql_mode,
2555
  'PHPVersion'=>PHP_VERSION,
2556
- ));
2557
 
2558
- foreach(array(
2559
  'safe_mode',
2560
  'allow_url_fopen',
2561
  'memory_limit',
@@ -2563,7 +2666,9 @@ function sucuriscan_about_information($template_variables=array())
2563
  'post_max_size',
2564
  'max_execution_time',
2565
  'max_input_time',
2566
- ) as $php_flag){
 
 
2567
  $php_flag_name = ucwords(str_replace('_', chr(32), $php_flag) );
2568
  $tpl_varname = str_replace(chr(32), '', $php_flag_name);
2569
  $php_flag_value = ini_get($php_flag);
@@ -2571,6 +2676,26 @@ function sucuriscan_about_information($template_variables=array())
2571
  }
2572
  }
2573
 
2574
- return $template_variables;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2575
  }
2576
 
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.6.0
11
  Author URI: http://sucuri.net
12
  */
13
 
18
  * @package Sucuri Plugin - SiteCheck Malware Scanner
19
  * @author Yorman Arias <yorman.arias@sucuri.net>
20
  * @author Daniel Cid <dcid@sucuri.net>
21
+ * @copyright Since 2010-2014 Sucuri Inc.
22
  * @license Released under the GPL - see LICENSE file for details.
23
  * @link https://wordpress.sucuri.net/
24
  * @since File available since Release 0.1
39
  /**
40
  * Current version of the plugin's code.
41
  */
42
+ define('SUCURISCAN_VERSION','1.6.0');
43
 
44
  /**
45
  * The local URL where the plugin's files and assets are served.
73
 
74
  if( !function_exists('sucuriscan_create_uploaddir') ){
75
  /**
76
+ * Create a folder in the WordPress upload directory where the plugin will
77
  * store all the temporal or dynamic information.
78
  *
79
  * @return void
98
  * Define which javascript and css files will be loaded in the header of the page.
99
  * @return void
100
  */
101
+ function sucuriscan_admin_script_style_registration() {
102
+ wp_register_style( 'sucuriscan', SUCURI_URL . '/inc/css/sucuriscan-default-css.css' );
103
+ wp_register_script( 'sucuriscan', SUCURI_URL . '/inc/js/sucuriscan-scripts.js' );
104
+
105
+ wp_enqueue_style( 'sucuriscan' );
106
+ wp_enqueue_script( 'sucuriscan' );
107
+ }
 
 
108
  add_action( 'admin_enqueue_scripts', 'sucuriscan_admin_script_style_registration', 1 );
109
 
110
  /**
133
  add_submenu_page('sucuriscan', 'Sucuri Scanner', 'Sucuri Scanner', 'manage_options',
134
  'sucuriscan', 'sucuri_scan_page');
135
 
136
+ add_submenu_page('sucuriscan', '1-Click Hardening', '1-Click Hardening', 'manage_options',
137
  'sucuriscan_hardening', 'sucuriscan_hardening_page');
138
 
139
  add_submenu_page('sucuriscan', 'WordPress Integrity', 'WordPress Integrity', 'manage_options',
202
  }
203
 
204
  /**
205
+ * Prints a HTML alert in the WordPress admin interface.
206
  *
207
  * @param string $type The type of alert, it can be either Updated or Error.
208
  * @param string $message The message that will be printed in the alert.
255
  * by the dynamic variables provided by the developer through one of the parameters
256
  * of the function.
257
  *
258
+ * @param string $template Filename of the template that will be used to generate the page.
259
+ * @param array $params A hash containing the pseudo-variable name as the key and the value that will replace it.
260
+ * @param boolean $type Either page, section or snippet indicating the type of template that will be retrieved.
261
+ * @return string The formatted HTML page after replace all the pseudo-variables.
262
  */
263
+ function sucuriscan_get_template($template='', $params=array(), $type='page'){
264
+ switch( $type ){
265
+ case 'page': /* no_break */
266
+ case 'section':
267
+ $template_path_pattern = '%s/%s/inc/tpl/%s.html.tpl';
268
+ break;
269
+ case 'snippet':
270
+ $template_path_pattern = '%s/%s/inc/tpl/%s.snippet.tpl';
271
+ break;
272
+ }
273
+
274
  $template_content = '';
275
+ $template_path = sprintf( $template_path_pattern, WP_PLUGIN_DIR, SUCURISCAN_PLUGIN_FOLDER, $template );
276
+ $params = is_array($params) ? $params : array();
277
 
278
  if( file_exists($template_path) && is_readable($template_path) ){
279
  $template_content = file_get_contents($template_path);
280
+
281
+ $current_page = isset($_GET['page']) ? htmlentities($_GET['page']) : '';
282
+ $params['CurrentURL'] = sprintf( '%s/wp-admin/admin.php?page=%s', site_url(), $current_page );
283
+ $params['SucuriURL'] = SUCURI_URL;
284
+ $params['PageNonce'] = wp_create_nonce('sucuri_page_nonce');
285
+
286
+ foreach($params as $tpl_key=>$tpl_value){
287
  $template_content = str_replace("%%SUCURI.{$tpl_key}%%", $tpl_value, $template_content);
288
  }
289
  }
290
+
291
+ if( $template == 'base' || $type != 'page' ){
292
+ return $template_content;
293
+ } else {
294
+ $base_params = array(
295
+ 'PageTitle' => '',
296
+ 'PageContent' => $template_content,
297
+ 'PageStyleClass' => $template,
298
+ 'URL.Hardening' => sucuriscan_get_url('hardening'),
299
+ 'URL.CoreIntegrity' => sucuriscan_get_url('core_integrity'),
300
+ 'URL.PostHack' => sucuriscan_get_url('posthack'),
301
+ 'URL.LastLogins' => sucuriscan_get_url('lastlogins'),
302
+ );
303
+
304
+ if( isset($params['PageTitle']) ){
305
+ $base_params['PageTitle'] = '('.$params['PageTitle'].')';
306
+ }
307
+
308
+ return sucuriscan_get_template('base', $base_params);
309
+ }
310
  }
311
 
312
  /**
313
+ * Generate a HTML code using a template and replacing all the pseudo-variables
314
+ * by the dynamic variables provided by the developer through one of the parameters
315
+ * of the function.
316
  *
317
+ * @param string $template Filename of the template that will be used to generate the page.
318
+ * @param array $params A hash containing the pseudo-variable name as the key and the value that will replace it.
319
+ * @return string The formatted HTML page after replace all the pseudo-variables.
320
  */
321
+ function sucuriscan_get_section($template='', $params=array()){
322
+ return sucuriscan_get_template( $template, $params, 'section' );
323
+ }
324
+
325
+ /**
326
+ * Generate a HTML code using a template and replacing all the pseudo-variables
327
+ * by the dynamic variables provided by the developer through one of the parameters
328
+ * of the function.
329
+ *
330
+ * @param string $template Filename of the template that will be used to generate the page.
331
+ * @param array $params A hash containing the pseudo-variable name as the key and the value that will replace it.
332
+ * @return string The formatted HTML page after replace all the pseudo-variables.
333
+ */
334
+ function sucuriscan_get_snippet($template='', $params=array()){
335
+ return sucuriscan_get_template( $template, $params, 'snippet' );
336
+ }
337
+
338
+ /**
339
+ * Generate an URL pointing to the page indicated in the function and that must
340
+ * be loaded through the administrator panel.
341
+ *
342
+ * @param string $page Short name of the page that will be generated.
343
+ * @return string Full string containing the link of the page.
344
+ */
345
+ function sucuriscan_get_url($page=''){
346
+ if( !empty($page) ){
347
+ $url_path = sprintf('%s?page=sucuriscan_%s', admin_url('admin.php'), $page);
348
+ return $url_path;
349
+ }
350
+
351
+ return null;
352
  }
353
 
354
  /**
355
+ * Retrieve a new set of keys for the WordPress configuration file using the
356
+ * official API provided by WordPress itself.
357
  *
358
+ * @return array A list of the new set of keys generated by WordPress API.
359
  */
360
  function sucuriscan_get_new_config_keys()
361
  {
373
  }
374
 
375
  /**
376
+ * Modify the WordPress configuration file and change the keys that were defined
377
+ * by a new random-generated list of keys retrieved from the official WordPress
378
  * API. The result of the operation will be either FALSE in case of error, or an
379
  * array containing multiple indexes explaining the modification, among them you
380
  * will find the old and new keys.
506
  /**
507
  * Check whether the current site is working as a multi-site instance.
508
  *
509
+ * @return boolean Either TRUE or FALSE in case WordPress is being used as a multi-site instance.
510
  */
511
  function sucuriscan_is_multisite(){
512
  if( function_exists('is_multisite') && is_multisite() ){ return TRUE; }
514
  }
515
 
516
  /**
517
+ * Find and retrieve the absolute path of the WordPress configuration file.
518
  *
519
+ * @return string Absolute path of the WordPress configuration file.
520
  */
521
  function sucuriscan_get_wpconfig_path(){
522
  $wp_config_path = ABSPATH.'wp-config.php';
529
  }
530
 
531
  /**
532
+ * Find and retrieve the absolute path of the main WordPress htaccess file.
533
  *
534
+ * @return string Absolute path of the main WordPress htaccess file.
535
  */
536
  function sucuriscan_get_htaccess_path(){
537
  $base_dirs = array(
585
  *
586
  * @return void
587
  */
588
+ function sucuri_scan_page(){
 
589
  $U_ERROR = NULL;
590
  if( !current_user_can('manage_options') ){
591
  wp_die(__('You do not have sufficient permissions to access this page: Sucuri Malware Scanner') );
592
  }
593
 
 
 
 
 
 
594
  if( isset($_POST['wpsucuri-doscan']) ){
595
  sucuriscan_print_scan();
596
  return(1);
597
  }
598
 
599
+ echo sucuriscan_get_template('initial-page');
600
  }
601
 
602
  /**
604
  *
605
  * @return void
606
  */
607
+ function sucuriscan_print_scan(){
 
608
  $website_scanned = home_url();
609
  $remote_url = 'http://sitecheck.sucuri.net/scanner/?serialized&clear&fromwp&scan='.$website_scanned;
610
+ $scan_results = wp_remote_get($remote_url, array('timeout' => 180));
611
+ ob_start();
612
  ?>
613
+
614
+
615
+ <?php if( is_wp_error($scan_results) ): ?>
616
+
617
+ <div id="poststuff">
618
+ <div class="postbox">
619
+ <h3>Error retrieving the scan report</h3>
620
+ <div class="inside">
621
+ <pre><?php print_r($scan_results); ?></pre>
622
+ </div>
623
+ </div>
624
  </div>
625
 
626
+ <?php elseif( preg_match('/^ERROR:/', $scan_results['body']) ): ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
627
 
628
+ <?php sucuriscan_admin_notice('error', $scan_results['body'].' The URL scanned was: <code>'.$website_scanned.'</code>'); ?>
629
+
630
+ <?php else: ?>
631
+
632
+ <?php
633
+ $res = @unserialize($scan_results['body']);
634
+
635
+ // Check for general warnings, and return the information for Infected/Clean site.
636
+ $malware_warns_exists = isset($res['MALWARE']['WARN']) ? TRUE : FALSE;
637
+ $blacklist_warns_exists = isset($res['BLACKLIST']['WARN']) ? TRUE : FALSE;
638
+
639
+ // Check whether this WordPress installation needs an update.
640
+ global $wp_version;
641
+ $wordpress_updated = FALSE;
642
+ $updates = function_exists('get_core_updates') ? get_core_updates() : array();
643
+
644
+ if( !is_array($updates) || empty($updates) || $updates[0]->response=='latest' ){
645
+ $wordpress_updated = TRUE;
646
+ }
647
+
648
+ // Generate the CSS classes for the boxes.
649
+ $sucuriscan_css_malware = $malware_warns_exists ? 'sucuriscan-border-bad' : 'sucuriscan-border-good';
650
+ $sucuriscan_css_blacklist = $blacklist_warns_exists ? 'sucuriscan-border-bad' : 'sucuriscan-border-good';
651
+ $sucuriscan_css_wpupdate = $wordpress_updated ? 'sucuriscan-border-good' : 'sucuriscan-border-bad' ;
652
+ ?>
653
+
654
+ <div class="sucuriscan-tabs">
655
+ <ul>
656
+ <li>
657
+ <a href="#" data-tabname="sitecheck-results">SiteCheck Results</a>
658
+ </li>
659
+ <li>
660
+ <a href="#" data-tabname="website-details">Website Details</a>
661
+ </li>
662
+ <li>
663
+ <a href="#" data-tabname="blacklist-status">Blacklist Status</a>
664
+ </li>
665
+ </ul>
666
+
667
+ <div class="sucuriscan-tab-containers">
668
+
669
+ <div id="sucuriscan-sitecheck-results">
670
  <div id="poststuff">
671
+ <div class="postbox sucuriscan-border <?php _e($sucuriscan_css_malware) ?>">
672
  <h3>
673
+ <?php if( $malware_warns_exists ): ?>
 
 
 
 
674
  Site compromised (malware was identified)
675
+ <?php else: ?>
676
+ Site clean (no malware was identified)
677
  <?php endif; ?>
678
  </h3>
679
+
680
  <div class="inside">
681
+
682
  <?php if( !$malware_warns_exists ): ?>
683
  <span><strong>Malware:</strong> No.</span><br>
684
  <span><strong>Malicious javascript:</strong> No.</span><br>
698
  }
699
  ?>
700
  <?php endif; ?>
701
+
702
+ <p>
703
+ <i>
704
+ More details here: <a href="http://sitecheck.sucuri.net/results/<?php _e($website_scanned); ?>">
705
+ http://sitecheck.sucuri.net/results/<?php _e($website_scanned); ?></a>
706
+ </i>
707
+ <hr />
708
+ <i>
709
+ If our free scanner did not detect any issue, you may have a more complicated and hidden
710
+ problem. You can try our <a href="admin.php?page=sucuriscan_core_integrity">WordPress integrity
711
+ checks</a> or sign up with Sucuri <a target="_blank" href="http://sucuri.net/signup">here</a>
712
+ for a complete and in depth scan+cleanup (not included in the free checks).
713
+ </i>
714
+ </p>
715
+
716
  </div>
717
  </div>
718
  </div>
719
+ </div>
720
 
721
+ <div id="sucuriscan-website-details">
722
+ <table class="wp-list-table widefat sucuriscan-table">
723
+ <thead>
724
+ <tr>
725
+ <th colspan="2" class="thead-with-button">
726
+ <span>System Information</span>
727
+ <?php if( !$wordpress_updated ): ?>
728
+ <a href="<?php echo admin_url('update-core.php'); ?>" class="button button-primary thead-topright-action">
729
+ Update to <?php _e($updates[0]->version) ?>
730
+ </a>
731
+ <?php endif; ?>
732
+ </th>
733
+ </tr>
734
+ </thead>
735
+
736
+ <tbody>
737
+ <!-- List of generic information from the site. -->
738
+ <?php
739
+ $possible_keys = array(
740
+ 'DOMAIN' => 'Domain Scanned',
741
+ 'IP' => 'Site IP Address',
742
+ 'HOSTING' => 'Hosting Company',
743
+ 'CMS' => 'CMS Found',
744
+ );
745
+ $possible_url_keys = array(
746
+ 'JSLOCAL' => 'List of scripts included',
747
+ 'JSEXTERNAL' => 'List of external scripts included',
748
+ 'URL' => 'List of links found',
749
+ );
750
+ ?>
751
+
752
+ <?php foreach( $possible_keys as $result_key=>$result_title ): ?>
753
+ <?php if( isset($res['SCAN'][$result_key]) ): ?>
754
+ <?php $result_value = implode(', ', $res['SCAN'][$result_key]); ?>
755
+ <tr>
756
+ <td><?php _e($result_title) ?></td>
757
+ <td><span class="sucuriscan-monospace"><?php _e($result_value) ?></span></td>
758
+ </tr>
759
+ <?php endif; ?>
760
+ <?php endforeach; ?>
761
+
762
+ <tr>
763
+ <td>WordPress Version</td>
764
+ <td><span class="sucuriscan-monospace"><?php _e($wp_version) ?></span></td>
765
+ </tr>
766
+ <tr>
767
+ <td>PHP Version</td>
768
+ <td><span class="sucuriscan-monospace"><?php _e(phpversion()) ?></span></td>
769
+ </tr>
770
+
771
+ <!-- List of application details from the site. -->
772
+ <tr>
773
+ <th colspan="2">Web application details</th>
774
+ </tr>
775
+ <?php foreach( $res['WEBAPP'] as $webapp_key=>$webapp_details ): ?>
776
+ <?php if( is_array($webapp_details) ): ?>
777
+ <?php foreach( $webapp_details as $i=>$details ): ?>
778
+ <?php if( is_array($details) ){ $details = isset($details[0]) ? $details[0] : ''; } ?>
779
+ <tr>
780
+ <td colspan="2">
781
+ <span class="sucuriscan-monospace"><?php _e($details) ?></span>
782
+ </td>
783
+ </tr>
784
+ <?php endforeach; ?>
785
+ <?php endif; ?>
786
+ <?php endforeach; ?>
787
+
788
+ <?php foreach( $res['SYSTEM']['NOTICE'] as $j=>$notice ): ?>
789
+ <?php if( is_array($notice) ){ $notice = implode(', ', $notice); } ?>
790
+ <tr>
791
+ <td colspan="2">
792
+ <span class="sucuriscan-monospace"><?php _e($notice) ?></span>
793
+ </td>
794
+ </tr>
795
+ <?php endforeach; ?>
796
+
797
+ <?php foreach( $possible_url_keys as $result_url_key=>$result_url_title ): ?>
798
+
799
+ <?php if( isset($res['LINKS'][$result_url_key]) ): ?>
800
+ <tr>
801
+ <th colspan="2">
802
+ <?php printf(
803
+ '%s (%d found)',
804
+ __($result_url_title),
805
+ count($res['LINKS'][$result_url_key])
806
+ ) ?>
807
+ </th>
808
+ </tr>
809
+
810
+ <?php foreach( $res['LINKS'][$result_url_key] as $url_path ): ?>
811
+ <tr>
812
+ <td colspan="2">
813
+ <span class="sucuriscan-monospace"><?php _e($url_path) ?></span>
814
+ </td>
815
+ </tr>
816
+ <?php endforeach; ?>
817
+ <?php endif; ?>
818
+
819
+ <?php endforeach; ?>
820
+ </tbody>
821
+ </table>
822
+ </div>
823
+
824
+ <div id="sucuriscan-blacklist-status">
825
  <div id="poststuff">
826
+ <div class="postbox sucuriscan-border <?php _e($sucuriscan_css_blacklist) ?>">
827
  <h3>
828
+ <?php if( $blacklist_warns_exists ): ?>
 
829
  Site blacklisted
830
  <?php else: ?>
 
831
  Site blacklist-free
832
  <?php endif; ?>
833
  </h3>
834
+
835
  <div class="inside">
836
  <?php
837
  foreach(array(
850
  </div>
851
  </div>
852
  </div>
853
+ </div>
854
+ </div>
855
+ </div>
856
 
857
+ <?php if( $malware_warns_exists || $blacklist_warns_exists ): ?>
858
+ <a href="http://sucuri.net/signup/" target="_blank" class="button button-primary button-hero sucuriscan-cleanup-btn">
859
+ Get your site protected with Sucuri
860
+ </a>
861
+ <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
862
 
863
+ <?php endif; ?>
864
 
 
865
 
866
  <?php
867
+ $_html = ob_get_contents();
868
+ ob_end_clean();
869
+ echo sucuriscan_get_template('base', array(
870
+ 'PageTitle' => '(Results)',
871
+ 'PageContent' => $_html,
872
+ 'PageStyleClass' => 'scanner-results',
873
+ ));
874
+ return;
875
  }
876
 
877
  /**
878
+ * WordPress core integrity page.
879
  *
880
+ * It checks whether the WordPress core files are the original ones, and the state
881
  * of the themes and plugins reporting the availability of updates. It also checks
882
  * the user accounts under the administrator group.
883
  *
884
  * @return void
885
  */
886
+ function sucuriscan_core_integrity_page(){
887
 
888
+ if( !current_user_can('manage_options') ){
889
+ wp_die(__('You do not have sufficient permissions to access this page: Sucuri Integrity Check') );
890
+ }
 
 
 
 
 
891
 
892
+ if( isset($_POST['wpsucuri-core-integrity']) ){
893
+ if( !wp_verify_nonce($_POST['sucuriscan_core_integritynonce'], 'sucuriscan_core_integritynonce') ){
894
+ unset($_POST['wpsucuri-core_integrity']);
 
895
  }
896
+ }
897
 
898
+ ob_start();
899
+ ?>
 
 
 
 
 
 
 
 
900
 
901
+ <div id="poststuff">
902
+ <?php
903
+ sucuriscan_core_integrity_function_wrapper(
904
+ 'sucuriwp_core_integrity_check',
905
+ 'Verify Integrity of WordPress Core Files',
906
+ 'This test will check wp-includes, wp-admin, and the top directory files against the latest WordPress
907
+ hashing database. If any of those files were modified, it is a big sign of a possible compromise.'
908
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
909
 
910
+ sucuriscan_core_integrity_wp_content_wrapper();
 
 
 
 
 
911
 
912
+ sucuriscan_core_integrity_function_wrapper(
913
+ 'sucuriwp_list_admins',
914
+ 'Admin User Dump',
915
+ 'List all administrator users and their latest login time.'
916
+ );
917
 
918
+ sucuriscan_core_integrity_function_wrapper(
919
+ 'sucuriwp_check_addons',
920
+ 'Outdated Addon list',
921
+ 'This test will list any outdated plugins and themes (not active addons may not be shown).'
922
+ );
923
+ ?>
924
+ </div>
925
 
926
  <?php
927
+ $_html = ob_get_contents();
928
+ ob_end_clean();
929
+ echo sucuriscan_get_template('base', array(
930
+ 'PageTitle' => '(WordPress Integrity)',
931
+ 'PageContent' => $_html,
932
+ 'PageStyleClass' => 'core-integrity'
933
+ ));
934
+ return;
935
  }
936
 
937
  /**
945
  */
946
  function sucuriscan_core_integrity_function_wrapper($function_name='', $stitle='', $description=''){ ?>
947
  <div class="postbox">
948
+ <h3><?php _e($stitle); ?></h3>
949
+
950
  <div class="inside">
951
  <form method="post">
952
+ <input type="hidden" name="<?php _e($function_name) ?>nonce" value="<?php echo wp_create_nonce($function_name.'nonce'); ?>" />
953
+ <input type="hidden" name="<?php _e($function_name) ?>" value="1" />
954
+ <p><?php _e($description) ?></p>
955
+ <input class="button-primary" type="submit" name="<?php _e($function_name) ?>" value="Check" />
956
  </form>
957
+
958
  <?php
959
+ if( isset($_POST[$function_name.'nonce']) && isset($_POST[$function_name]) ){
960
  if( function_exists($function_name) ){
961
  $function_name();
962
  }
997
  // && wp_verify_nonce($_POST['sucuriwp_content_checknonce'], 'sucuriwp_content_checknonce')
998
  && isset($_POST['sucuriwp_content_check'])
999
  ): ?>
1000
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-table-doubletitle sucuriscan-lastmodified">
 
1001
  <thead>
1002
  <tr>
1003
  <th colspan="2">wp_content latest modified files</th>
1012
  $wp_content_hashes = read_dir_r(ABSPATH.'wp-content', true);
1013
  $days = htmlspecialchars(trim((int)$_POST['sucuriwp_content_check_back']));
1014
  $back_days = current_time( 'timestamp' ) - ( $days * 86400);
1015
+ $counter = 0;
1016
 
1017
  foreach ( $wp_content_hashes as $key => $value) {
1018
  if ($value['time'] >= $back_days ){
1019
+ $css_class = ( $counter % 2 == 0 ) ? '' : 'alternate';
1020
  $date = date('d-m-Y H:i:s', $value['time']);
1021
+ printf('<tr class="%s"><td>%s</td><td>%s</td></tr>', $css_class, $key, $date);
1022
+ $counter += 1;
1023
  }
1024
  }
1025
  ?>
1038
  * @param boolean $recursiv Either TRUE or FALSE if the scan should be performed recursively.
1039
  * @return array List of arrays containing the md5sum and last modification time of the files found.
1040
  */
1041
+ function read_dir_r($dir = "./", $recursiv = false){
 
1042
  $skipname = basename(__FILE__);
1043
  $skipname .= ",_sucuribackup,wp-config.php";
1044
 
1047
  $dir_handler = opendir($dir);
1048
 
1049
  while(($entry = readdir($dir_handler)) !== false) {
1050
+ if ($entry != "." && $entry != "..") {
1051
+ $dir = preg_replace("/^(.*)(\/)+$/", "$1", $dir);
1052
+ $item = sprintf( '%s/%s', $dir, $entry );
1053
+
1054
+ if (is_file($item)) {
1055
+ $skip_parts = explode(",", $skipname);
1056
+
1057
+ foreach ($skip_parts as $skip) {
1058
+ if (strpos($item,$skip) !== false) {
1059
+ continue 2;
1060
+ }
1061
  }
 
1062
 
1063
+ $md5 = @md5_file($item);
1064
+ $time_stamp = @filectime($item);
1065
+ $item_name = str_replace(ABSPATH, "./", $item);
1066
+ $files_info[$item_name] = array(
1067
+ 'md5' => $md5,
1068
+ 'time' => $time_stamp
1069
+ );
1070
+ }
1071
 
1072
+ elseif (is_dir($item) && $recursiv) {
1073
+ $files_info = array_merge( $files_info , read_dir_r($item) );
1074
+ }
1075
+ }
 
1076
  }
1077
 
1078
  closedir($dir_handler);
1082
  /**
1083
  * Compare the md5sum of the core files in the current site with the hashes hosted
1084
  * remotely in Sucuri servers. These hashes are updated every time a new version
1085
+ * of WordPress is released.
1086
  *
1087
  * @return void
1088
  */
1089
+ function sucuriwp_core_integrity_check(){
 
1090
 
1091
  global $wp_version;
1092
 
1126
  }
1127
 
1128
  /**
1129
+ * List all the WordPress core files modified until now.
1130
  *
1131
+ * @param array $list List of WordPress core files modified.
1132
  * @return void
1133
  */
1134
  function sucuriscan_draw_corefiles_status($list=array()){
1135
  if( is_array($list) && !empty($list) ): ?>
1136
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-corefiles">
1137
  <tbody>
1138
  <?php
1139
+ foreach( $list as $diff_type=>$file_list ){
1140
+ $counter = 0;
1141
  printf('<tr><th>Core File %s: %d</th></tr>', ucwords($diff_type), sizeof($file_list));
1142
  foreach($file_list as $filepath){
1143
+ $css_class = ( $counter % 2 == 0 ) ? '' : 'alternate';
1144
+ printf('<tr class="%s"><td>%s</td></tr>', $css_class, $filepath);
1145
+ $counter += 1;
1146
  }
1147
  }
1148
  ?>
1152
  <?php }
1153
 
1154
  /**
1155
+ * List all the user administrator accounts.
1156
+ *
1157
+ * @see http://codex.wordpress.org/Class_Reference/WP_User_Query
1158
  *
 
1159
  * @return void
1160
  */
1161
+ function sucuriwp_list_admins(){
1162
 
1163
  global $wpdb;
 
 
 
 
 
 
 
1164
 
1165
  // Page pseudo-variables initialization.
1166
  $template_variables = array(
 
1167
  'AdminUsers.UserList'=>''
1168
  );
1169
 
1170
+ $user_query = new WP_User_Query(array( 'role' => 'Administrator' ));
1171
+ $admins = $user_query->get_results();
1172
+
1173
+ foreach( (array)$admins as $admin ){
1174
+ $admin->lastlogins = sucuriscan_get_logins(5, $admin->ID);
 
1175
 
1176
  $user_snippet = array(
1177
  'AdminUsers.Username'=>$admin->user_login,
1178
  'AdminUsers.Email'=>$admin->user_email,
1179
  'AdminUsers.LastLogins'=>'',
1180
+ 'AdminUsers.UserURL'=>admin_url('user-edit.php?user_id='.$admin->ID)
1181
  );
1182
+
1183
  if( !empty($admin->lastlogins) ){
1184
  $user_snippet['AdminUsers.NoLastLogins'] = 'hidden';
1185
  $user_snippet['AdminUsers.NoLastLoginsTable'] = 'visible';
1186
+
1187
  foreach($admin->lastlogins as $lastlogin){
1188
+ $user_snippet['AdminUsers.LastLogins'] .= sucuriscan_get_snippet('integrity-admins-lastlogin', array(
1189
  'AdminUsers.RemoteAddr'=>$lastlogin->user_remoteaddr,
1190
  'AdminUsers.Datetime'=>$lastlogin->user_lastlogin
1191
  ));
1195
  $user_snippet['AdminUsers.NoLastLoginsTable'] = 'hidden';
1196
  }
1197
 
1198
+ $template_variables['AdminUsers.UserList'] .= sucuriscan_get_snippet('integrity-admins', $user_snippet);
1199
  }
1200
 
1201
+ echo sucuriscan_get_section('integrity-admins', $template_variables);
1202
  }
1203
 
1204
  /**
1205
+ * Check if any installed plugin and theme has an update available.
1206
  *
1207
  * @return void
1208
  */
1209
+ function sucuriwp_check_addons(){ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1210
 
1211
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-table-doubletitle sucuriscan-plugins-update">
1212
+ <tbody>
1213
+ <tr>
1214
+ <th colspan="4">Outdated Plugins</th>
1215
+ </tr>
1216
+
1217
+ <?php
1218
+ // Check plugins.
1219
+ do_action('wp_update_plugins');
1220
+ wp_update_plugins();
1221
+ $update_plugins = get_site_transient('update_plugins');
1222
+ $plugins_need_update = (bool) !empty($update_plugins->response);
1223
+ ?>
1224
+
1225
+ <tr>
1226
+ <th>Plugin</th>
1227
+ <th>Installed Version</th>
1228
+ <th>New Version</th>
1229
+ <th>&nbsp;</th>
1230
+ </tr>
1231
+
1232
+ <?php if( $plugins_need_update ): ?>
1233
+ <?php
1234
+ $counter = 0;
1235
+ foreach( $update_plugins->response as $rel_path => $plugin_info ):
1236
+ $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $rel_path );
1237
+ $css_class = ( $counter % 2 == 0 ) ? '' : 'alternate';
1238
+ $counter += 1;
1239
+ ?>
1240
+
1241
+ <tr class="<?php _e($css_class) ?>">
1242
+ <td><?php _e($plugin_data['Title']) ?></td>
1243
+ <td><?php _e($plugin_data['Version']) ?></td>
1244
+ <td><?php _e($plugin_info->new_version) ?></td>
1245
+ <td><a href="<?php _e($plugin_info->package) ?>" target="_blank">Download</a></td>
1246
+ </tr>
1247
+ <?php endforeach; ?>
1248
+ <?php else: ?>
1249
+ <tr>
1250
+ <td colspan="4">All plugins are up-to-date.</td>
1251
+ </tr>
1252
+ <?php endif; ?>
1253
+
1254
+ <?php
1255
+ // Check themes.
1256
+ do_action('wp_update_themes');
1257
+ wp_update_themes();
1258
+ $update_themes = get_theme_updates();
1259
+ $themes_need_update = (bool) !empty($update_themes);
1260
+ ?>
1261
+
1262
+ <tr>
1263
+ <th>Theme</th>
1264
+ <th>Installed Version</th>
1265
+ <th>New Version</th>
1266
+ <th>&nbsp;</th>
1267
+ </tr>
1268
+
1269
+ <?php if( $themes_need_update ): ?>
1270
+ <?php
1271
+ $counter = 0;
1272
+ foreach( $update_themes as $stylesheet => $theme ):
1273
+ $css_class = ( $counter % 2 == 0 ) ? '' : 'alternate';
1274
+ $counter += 1;
1275
+ ?>
1276
+
1277
+ <tr class="<?php _e($css_class) ?>">
1278
+ <td><?php _e($theme->display('Name')) ?></td>
1279
+ <td><?php _e($theme->display('Version')) ?></td>
1280
+ <td><?php _e($theme->update['new_version']) ?></td>
1281
+ <td><a href="<?php _e($theme->update['package']) ?>" target="_blank">Download</a></td>
1282
+ </tr>
1283
+ <?php endforeach; ?>
1284
+ <?php else: ?>
1285
+ <tr>
1286
+ <td colspan="4">All themes are up-to-date.</td>
1287
+ </tr>
1288
+ <?php endif; ?>
1289
+ </tbody>
1290
+ </table>
1291
+
1292
+ <?php }
1293
 
1294
  /**
1295
+ * Retrieve a list with the checksums of the files in a specific version of WordPress.
1296
  *
1297
+ * @param integer $version Valid version number of the WordPress project.
1298
  * @return object Associative object with the relative filepath and the checksums of the project files.
1299
  */
1300
  function sucuriscan_get_official_checksums($version=0){
1312
  }
1313
 
1314
  /**
1315
+ * Check whether the core WordPress files where modified, removed or if any file
1316
  * was added to the core folders. This function returns an associative array with
1317
  * these keys:
1318
  *
1319
  * <ul>
1320
+ * <li>bad: Files with a different checksum according to the official files of the WordPress version filtered,</li>
1321
  * <li>good: Files with the same checksums than the official files,</li>
1322
  * <li>removed: Official files which are not present in the local project,</li>
1323
+ * <li>added: Files present in the local project but not in the official WordPress packages.</li>
1324
  * </ul>
1325
  *
1326
+ * @param integer $version Valid version number of the WordPress project.
1327
  * @return array Associative array with these keys: bad, good, removed, added.
1328
  */
1329
  function sucuriscan_check_wp_integrity($version=0){
1373
  *
1374
  * @return void
1375
  */
1376
+ function sucuriscan_hardening_page(){
1377
 
1378
+ if( !current_user_can('manage_options') ){
1379
+ wp_die(__('You do not have sufficient permissions to access this page: Sucuri Hardening') );
1380
+ }
 
 
 
 
 
1381
 
1382
+ if( isset($_POST['wpsucuri-doharden']) ){
1383
+ if( !wp_verify_nonce($_POST['sucuriscan_hardening_nonce'], 'sucuriscan_hardening_nonce') ){
1384
+ unset($_POST['wpsucuri-doharden']);
 
1385
  }
1386
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1387
 
1388
+ ob_start();
1389
+ ?>
 
 
 
 
 
 
1390
 
1391
+ <div id="poststuff">
1392
+ <form method="post">
1393
+ <input type="hidden" name="sucuriscan_hardening_nonce" value="<?php echo wp_create_nonce('sucuriscan_hardening_nonce'); ?>" />
1394
+ <input type="hidden" name="wpsucuri-doharden" value="wpsucuri-doharden" />
1395
 
1396
+ <?php
1397
+ sucuriscan_harden_version();
1398
+ sucuriscan_cloudproxy_enabled();
1399
+ sucuri_harden_removegenerator();
1400
+ sucuriscan_harden_upload();
1401
+ sucuriscan_harden_wpcontent();
1402
+ sucuriscan_harden_wpincludes();
1403
+ sucuriscan_harden_phpversion();
1404
+ ?>
1405
+ </form>
1406
+ </div>
1407
 
1408
  <?php
1409
+ $_html = ob_get_contents();
1410
+ ob_end_clean();
1411
+ echo sucuriscan_get_template('base', array(
1412
+ 'PageTitle' => '(1-Click Hardening)',
1413
+ 'PageContent' => $_html,
1414
+ 'PageStyleClass' => 'hardening'
1415
+ ));
1416
+ return;
1417
  }
1418
 
1419
  /**
1422
  * @param string $msg The title of the hardening option.
1423
  * @return void
1424
  */
1425
+ function sucuriscan_wrapper_open($msg){
 
1426
  ?>
1427
  <div class="postbox">
1428
  <h3><?php echo $msg; ?></h3>
1435
  *
1436
  * @return void
1437
  */
1438
+ function sucuriscan_wrapper_close(){
 
1439
  ?>
1440
  </div>
1441
  </div>
1448
  * @param string $message The text string that will be shown inside the error box.
1449
  * @return void
1450
  */
1451
+ function sucuriscan_harden_error($message){
 
1452
  return('<div id="message" class="error"><p>'.$message.'</p></div>');
1453
  }
1454
 
1458
  * @param string $message The text string that will be shown inside the success box.
1459
  * @return void
1460
  */
1461
+ function sucuriscan_harden_ok($message){
 
1462
  return( '<div id="message" class="updated"><p>'.$message.'</p></div>');
1463
  }
1464
 
1465
  /**
1466
  * Generate the HTML code necessary to show a form with the options to harden
1467
+ * a specific part of the WordPress installation, if the Status variable is
1468
  * set as a positive integer the button is shown as "unharden".
1469
  *
1470
  * @param integer $status Either one or zero representing the state of the hardening, one for secure, zero for insecure.
1498
  }
1499
 
1500
  /**
1501
+ * Check whether the version number of the WordPress installed is the latest
1502
  * version available officially.
1503
  *
1504
  * @return void
1505
  */
1506
+ function sucuriscan_harden_version(){
 
1507
  global $wp_version;
1508
 
1509
  $updates = get_core_updates();
1542
 
1543
  /**
1544
  * Notify the state of the hardening for the removal of the Generator tag in
1545
+ * HTML code printed by WordPress to show the current version number of the
1546
  * installation.
1547
  *
1548
  * @return void
1549
  */
1550
+ function sucuri_harden_removegenerator(){
 
1551
  /* Enabled by default with this plugin. */
1552
  $cp = 1;
1553
 
1563
  }
1564
 
1565
  /**
1566
+ * Check whether the WordPress upload folder is protected or not.
1567
  *
1568
  * A htaccess file is placed in the upload folder denying the access to any php
1569
  * file that could be uploaded through a vulnerability in a Plugin, Theme or
1570
+ * WordPress itself.
1571
  *
1572
  * @return void
1573
  */
1574
+ function sucuriscan_harden_upload(){
 
1575
  $cp = 1;
1576
  $upmsg = NULL;
1577
  $htaccess_upload = dirname(sucuriscan_dir_filepath())."/.htaccess";
1639
  }
1640
 
1641
  /**
1642
+ * Check whether the WordPress content folder is protected or not.
1643
  *
1644
  * A htaccess file is placed in the content folder denying the access to any php
1645
  * file that could be uploaded through a vulnerability in a Plugin, Theme or
1646
+ * WordPress itself.
1647
  *
1648
  * @return void
1649
  */
1650
+ function sucuriscan_harden_wpcontent(){
 
1651
  $cp = 1;
1652
  $upmsg = NULL;
1653
  $htaccess_upload = ABSPATH."/wp-content/.htaccess";
1719
  }
1720
 
1721
  /**
1722
+ * Check whether the WordPress includes folder is protected or not.
1723
  *
1724
  * A htaccess file is placed in the includes folder denying the access to any php
1725
  * file that could be uploaded through a vulnerability in a Plugin, Theme or
1726
+ * WordPress itself, there are some exceptions for some specific files that must
1727
  * be available publicly.
1728
  *
1729
  * @return void
1730
  */
1731
+ function sucuriscan_harden_wpincludes(){
 
1732
  $cp = 1;
1733
  $upmsg = NULL;
1734
  $htaccess_upload = ABSPATH."/wp-includes/.htaccess";
1802
  *
1803
  * @return void
1804
  */
1805
+ function sucuriscan_harden_phpversion(){
 
1806
  $phpv = phpversion();
1807
 
1808
  if(strncmp($phpv, "5.", 2) < 0)
1852
  *
1853
  * @return void
1854
  */
1855
+ function sucuriscan_posthack_page(){
1856
+
1857
+ if( !current_user_can('manage_options') ){
 
1858
  wp_die(__('You do not have sufficient permissions to access this page: Sucuri Post-Hack') );
1859
  }
1860
 
1861
  // Page pseudo-variables initialization.
1862
  $template_variables = array(
1863
+ 'PageTitle' => 'Post-Hack',
1864
+ 'PosthackNonce' => wp_create_nonce('sucuri_posthack_nonce'),
1865
+ 'WPConfigUpdate.Display' => 'display:none',
1866
+ 'WPConfigUpdate.NewConfig' => '',
1867
+ 'ResetPassword.UserList' => ''
 
1868
  );
1869
 
1870
  // Process form submission
1871
  if( isset($_POST['sucuri_posthack_action']) ){
1872
+ if( !wp_verify_nonce($_POST['sucuri_posthack_nonce'], 'sucuri_posthack_nonce') ){
 
1873
  wp_die(__('WordPress Nonce verification failed, try again going back and checking the form.') );
1874
  }
1875
 
1940
  $user_list = get_users();
1941
  foreach($user_list as $user){
1942
  $counter += 1;
1943
+ $user->user_registered_timestamp = strtotime($user->user_registered);
1944
+ $user->user_registered_formatted = date('D, M/Y H:i', $user->user_registered_timestamp);
1945
+ $user_snippet = sucuriscan_get_snippet('resetpassword', array(
1946
+ 'ResetPassword.UserId' => $user->ID,
1947
+ 'ResetPassword.Username' => $user->user_login,
1948
+ 'ResetPassword.Displayname' => $user->display_name,
1949
+ 'ResetPassword.Email' => $user->user_email,
1950
+ 'ResetPassword.Registered' => $user->user_registered_formatted,
1951
+ 'ResetPassword.Roles' => implode(', ', $user->roles),
1952
+ 'ResetPassword.CssClass' => ( $counter%2 == 0 ) ? '' : 'alternate'
1953
  ));
1954
  $template_variables['ResetPassword.UserList'] .= $user_snippet;
1955
  }
1956
 
1957
+ echo sucuriscan_get_template('posthack', $template_variables);
1958
  }
1959
 
1960
  /**
1964
  *
1965
  * @return void
1966
  */
1967
+ function sucuriscan_lastlogins_page(){
1968
+ if( !current_user_can('manage_options') ){
 
 
1969
  wp_die(__('You do not have sufficient permissions to access this page: Sucuri Last-Logins') );
1970
  }
1971
 
1972
  // Page pseudo-variables initialization.
1973
  $template_variables = array(
1974
+ 'PageTitle' => 'Last Logins',
1975
+ 'LastLoginsNonce' => wp_create_nonce('sucuriscan_lastlogins_nonce'),
1976
+ 'UserList' => '',
1977
+ 'UserListLimit' => SUCURISCAN_LASTLOGINS_USERSLIMIT,
 
 
1978
  );
1979
 
1980
  if( !sucuriscan_lastlogins_datastore_is_writable() ){
1990
  $user_list = sucuriscan_get_logins($limit);
1991
  foreach($user_list as $user){
1992
  $counter += 1;
1993
+ $user_snippet = sucuriscan_get_snippet('lastlogins', array(
1994
+ 'UserList.Number' => $counter,
1995
+ 'UserList.UserId' => intval($user->ID),
1996
+ 'UserList.Username' => ( !is_null($user->user_login) ? $user->user_login : '<em>Unknown</em>' ),
1997
+ 'UserList.Displayname' => $user->display_name,
1998
+ 'UserList.Email' => $user->user_email,
1999
+ 'UserList.Registered' => $user->user_registered,
2000
+ 'UserList.RemoteAddr' => $user->user_remoteaddr,
2001
+ 'UserList.Hostname' => $user->user_hostname,
2002
+ 'UserList.Datetime' => $user->user_lastlogin,
2003
+ 'UserList.TimeAgo' => sucuriscan_time_ago($user->user_lastlogin),
2004
+ 'UserList.UserURL' => admin_url('user-edit.php?user_id='.$user->ID),
2005
+ 'UserList.CssClass' => ( $counter % 2 == 0 ) ? 'alternate' : ''
2006
  ));
2007
  $template_variables['UserList'] .= $user_snippet;
2008
  }
2009
 
2010
+ echo sucuriscan_get_template('lastlogins', $template_variables);
2011
  }
2012
 
2013
  /**
2085
  $remote_addr = sucuriscan_get_remoteaddr();
2086
 
2087
  $login_info = array(
2088
+ 'user_id' => $current_user->ID,
2089
+ 'user_login' => $current_user->user_login,
2090
+ 'user_remoteaddr' => $remote_addr,
2091
+ 'user_hostname' => @gethostbyaddr($remote_addr),
2092
+ 'user_lastlogin' => current_time('mysql')
2093
  );
2094
 
2095
  @file_put_contents($datastore_filepath, serialize($login_info)."\n", FILE_APPEND);
2154
  * Hook for the wp-login action to redirect the user to a specific URL after
2155
  * his successfully login to the administrator interface.
2156
  *
2157
+ * @param string $redirect_to URL where the browser must be originally redirected to, set by WordPress itself.
2158
+ * @param object $request Optional parameter set by WordPress itself through the event triggered.
2159
+ * @param boolean $user WordPress user object with the information of the account involved in the operation.
2160
  * @return string URL where the browser must be redirected to.
2161
  */
2162
  function sucuriscan_login_redirect($redirect_to='', $request=NULL, $user=FALSE){
2204
  * @return void
2205
  */
2206
  function sucuriscan_infosys_page(){
2207
+ if( !current_user_can('manage_options') ){
 
2208
  wp_die(__('You do not have sufficient permissions to access this page: Sucuri Last-Logins') );
2209
  }
2210
 
2211
  // Page pseudo-variables initialization.
2212
  $template_variables = array(
2213
+ 'PageTitle' => 'Site Info',
2214
+ 'ServerInfo' => sucuriscan_server_info(),
2215
+ 'LoggedInUsers' => sucuriscan_infosys_loggedin(),
2216
+ 'Cronjobs' => sucuriscan_show_cronjobs(),
2217
+ 'HTAccessIntegrity' => sucuriscan_infosys_htaccess(),
2218
+ 'WordpressConfig' => sucuriscan_infosys_wpconfig(),
2219
  );
2220
 
2221
+ echo sucuriscan_get_template('infosys', $template_variables);
 
 
 
 
 
2222
  }
2223
 
2224
  /**
2225
  * Find the main htaccess file for the site and check whether the rules of the
2226
+ * main htaccess file of the site are the default rules generated by WordPress.
2227
  *
2228
  * @return string The HTML code displaying the information about the HTAccess rules.
2229
  */
2263
  $template_variables['HTAccess.MessageVisible'] = 'visible';
2264
  }
2265
 
2266
+ return sucuriscan_get_section('infosys-htaccess', $template_variables);
2267
  }
2268
 
2269
  /**
2270
  * Check whether the rules in a htaccess file are the default options generated
2271
+ * by WordPress or if the file has custom options added by other Plugins.
2272
  *
2273
  * @param string $rules Optional parameter containing a text string with the content of the main htaccess file.
2274
  * @return boolean Either TRUE or FALSE if the rules found in the htaccess file specified are the default ones or not.
2313
 
2314
  /**
2315
  * Retrieve all the constants and variables with their respective values defined
2316
+ * in the WordPress configuration file, only the database password constant is
2317
  * omitted for security reasons.
2318
  *
2319
  * @return string The HTML code displaying the constants and variables found in the wp-config file.
2323
  'WordpressConfig.Rules' => '',
2324
  'WordpressConfig.Total' => 0,
2325
  'WordpressConfig.Content' => '',
2326
+ 'WordpressConfig.ThickboxURL' => '#TB_inline?',
2327
  );
2328
  $ignore_wp_rules = array('DB_PASSWORD');
2329
+ $template_variables['WordpressConfig.ThickboxURL'] .= http_build_query(array(
2330
+ 'width' => '800',
2331
+ 'height' => '550',
2332
+ 'inlineId' => 'sucuriscan-wpconfig-content',
2333
+ ));
2334
 
2335
  $wp_config_path = sucuriscan_get_wpconfig_path();
2336
  if( $wp_config_path ){
2384
  foreach( $wp_config_rules as $var_name=>$var_value ){
2385
  $counter += 1;
2386
  $template_variables['WordpressConfig.Total'] += 1;
2387
+ $template_variables['WordpressConfig.Rules'] .= sucuriscan_get_snippet('infosys-wpconfig', array(
2388
  'WordpressConfig.VariableName' => $var_name,
2389
  'WordpressConfig.VariableValue' => htmlentities($var_value),
2390
  'WordpressConfig.CssClass' => ( $counter%2 == 0 ) ? '' : 'alternate'
2392
  }
2393
  }
2394
 
2395
+ return sucuriscan_get_section('infosys-wpconfig', $template_variables);
2396
  }
2397
 
2398
  /**
2417
  $logged_in_user['last_activity_datetime'] = date('d/M/Y H:i', $logged_in_user['last_activity']);
2418
  $logged_in_user['user_registered_datetime'] = date('d/M/Y H:i', strtotime($logged_in_user['user_registered']));
2419
 
2420
+ $template_variables['LoggedInUsers.List'] .= sucuriscan_get_snippet('infosys-loggedin', array(
2421
  'LoggedInUsers.Id' => $logged_in_user['user_id'],
2422
  'LoggedInUsers.UserURL' => admin_url('user-edit.php?user_id='.$logged_in_user['user_id']),
2423
  'LoggedInUsers.UserLogin' => $logged_in_user['user_login'],
2430
  }
2431
  }
2432
 
2433
+ return sucuriscan_get_section('infosys-loggedin', $template_variables);
2434
  }
2435
 
2436
  /**
2527
  * Add an user account to the list of registered users in session.
2528
  *
2529
  * @param string $user_login The name of the user account that just logged in the site.
2530
+ * @param boolean $user The WordPress object containing all the information associated to the user.
2531
  * @return void
2532
  */
2533
  function sucuriscan_set_online_user($user_login='', $user=FALSE){
2612
  $counter += 1;
2613
  $cronjob_snippet = '';
2614
  $template_variables['Cronjobs.Total'] += 1;
2615
+ $template_variables['Cronjobs.List'] .= sucuriscan_get_snippet('infosys-cronjobs', array(
2616
  'Cronjob.Task' => ucwords(str_replace('_',chr(32),$hook)),
2617
  'Cronjob.Schedule' => $event['schedule'],
2618
  'Cronjob.Nexttime' => date_i18n($date_format, $timestamp),
2624
  }
2625
  }
2626
 
2627
+ return sucuriscan_get_section('infosys-cronjobs', $template_variables);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2628
  }
2629
 
2630
  /**
2633
  * @param array $template_variables The hash for the template system, keys are pseudo-variables.
2634
  * @return array A list of pseudo-variables and values that will replace them in the HTML template.
2635
  */
2636
+ function sucuriscan_server_info(){
 
2637
  global $wpdb;
2638
 
2639
  if( current_user_can('manage_options') ){
2644
  $plugin_runtime_filepath = sucuriscan_dir_filepath('.runtime');
2645
  $plugin_runtime_datetime = file_exists($plugin_runtime_filepath) ? date('r',filemtime($plugin_runtime_filepath)) : 'N/A';
2646
 
2647
+ $template_variables = array(
2648
  'SettingsDisplay'=>'block',
2649
  'PluginVersion'=>SUCURISCAN_VERSION,
2650
  'PluginForceUpdate'=>admin_url('admin.php?page=sucurisec_settings&sucuri_force_update=1'),
2656
  'MySQLVersion'=>$mysql_version,
2657
  'SQLMode'=>$sql_mode,
2658
  'PHPVersion'=>PHP_VERSION,
2659
+ );
2660
 
2661
+ $field_names = array(
2662
  'safe_mode',
2663
  'allow_url_fopen',
2664
  'memory_limit',
2666
  'post_max_size',
2667
  'max_execution_time',
2668
  'max_input_time',
2669
+ );
2670
+
2671
+ foreach( $field_names as $php_flag ){
2672
  $php_flag_name = ucwords(str_replace('_', chr(32), $php_flag) );
2673
  $tpl_varname = str_replace(chr(32), '', $php_flag_name);
2674
  $php_flag_value = ini_get($php_flag);
2676
  }
2677
  }
2678
 
2679
+ return sucuriscan_get_section('infosys-serverinfo', $template_variables);
2680
+ }
2681
+
2682
+
2683
+ /**
2684
+ * Print the HTML code for the plugin about page with information of the plugin,
2685
+ * the scheduled tasks, and some settings from the PHP environment and server.
2686
+ *
2687
+ * @return void
2688
+ */
2689
+ function sucuriscan_about_page(){
2690
+
2691
+ if( !current_user_can('manage_options') ){
2692
+ wp_die(__('You do not have sufficient permissions to access this page: Sucuri Last-Logins') );
2693
+ }
2694
+
2695
+ $template_variables = array(
2696
+ 'PageTitle' => 'About'
2697
+ );
2698
+
2699
+ echo sucuriscan_get_template('about', $template_variables);
2700
  }
2701