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

Version Description

  • Fixed bug on the secret keys hardening.
Download this release

Release Info

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

Code changes from version 1.7.7 to 1.7.8

Files changed (2) hide show
  1. readme.txt +5 -2
  2. sucuri.php +59 -30
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: dd@sucuri.net
3
Donate Link: http://sucuri.net/
4
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection,WordPress Security, Login Security,Security Auditing,File Integrity,htaccess,phishing,backdoors,SQL Injection, RFI, LFI, XSS, CSRF, website firewall, Website Security, Performance Optimization, Zero Day, Software Vulnerability, Exploits, Hacks, Attackers, Bad Actors, Reverse Proxy, Two Factor Security, Two Factor Authentication, Security Logs, HeatBleed Vulnerability, Website Protection, Bash Vulnerability, RevSlider Vulnerability, MailPoet Vulnerability, Malware Prevention, Website Firewall, Website AntiVirus, Security Response, Security Detection, Security Prevention
5
Requires at least:3.2
6
- Stable tag:1.7.7
7
Tested up to: 4.1.1
8
9
The Sucuri WordPress Security plugin is a security toolset for security integrity monitoring, malware detection and security hardening.
@@ -352,7 +352,10 @@ service from the WordPress dashboard.
352
353
== Changelog ==
354
355
- = 1.7.7.=
356
* Added better support for directory separators
357
* Added option to remove API key from plugin
358
* Various bugfixes and improvements
3
Donate Link: http://sucuri.net/
4
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection,WordPress Security, Login Security,Security Auditing,File Integrity,htaccess,phishing,backdoors,SQL Injection, RFI, LFI, XSS, CSRF, website firewall, Website Security, Performance Optimization, Zero Day, Software Vulnerability, Exploits, Hacks, Attackers, Bad Actors, Reverse Proxy, Two Factor Security, Two Factor Authentication, Security Logs, HeatBleed Vulnerability, Website Protection, Bash Vulnerability, RevSlider Vulnerability, MailPoet Vulnerability, Malware Prevention, Website Firewall, Website AntiVirus, Security Response, Security Detection, Security Prevention
5
Requires at least:3.2
6
+ Stable tag:1.7.8
7
Tested up to: 4.1.1
8
9
The Sucuri WordPress Security plugin is a security toolset for security integrity monitoring, malware detection and security hardening.
352
353
== Changelog ==
354
355
+ = 1.7.8 =
356
+ * Fixed bug on the secret keys hardening.
357
+
358
+ = 1.7.7 =
359
* Added better support for directory separators
360
* Added option to remove API key from plugin
361
* Various bugfixes and improvements
sucuri.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Sucuri Security - Auditing, Malware Scanner and Hardening
4
Plugin URI: http://wordpress.sucuri.net/
5
Description: The <a href="http://sucuri.net/" target="_blank">Sucuri</a> plugin provides the website owner the best Activity Auditing, SiteCheck Remote Malware Scanning, Effective Security Hardening and Post-Hack features. SiteCheck will check for malware, spam, blacklisting and other security issues like .htaccess redirects, hidden eval code, etc. The best thing about it is it's completely free.
6
Author: Sucuri, INC
7
- Version: 1.7.7
8
Author URI: http://sucuri.net
9
*/
10
@@ -66,7 +66,7 @@ define( 'SUCURISCAN', 'sucuriscan' );
66
/**
67
* Current version of the plugin's code.
68
*/
69
- define( 'SUCURISCAN_VERSION', '1.7.7' );
70
71
/**
72
* The name of the Sucuri plugin main file.
@@ -608,7 +608,7 @@ class SucuriScan {
608
* @return string Secret key definition pattern.
609
*/
610
public static function secret_key_pattern(){
611
- return '/define\((\s+)?\'([A-Z_]+)\',(\s+)?\'(.*)\'(\s+)?\);/';
612
}
613
614
/**
@@ -1370,6 +1370,7 @@ class SucuriScanFileInfo extends SucuriScan {
1370
$tree = $this->get_directory_tree_with_spl( $directory );
1371
} else {
1372
$this->scan_interface = 'opendir';
1373
$tree = $this->get_directory_tree( $directory );
1374
}
1375
break;
@@ -1456,7 +1457,11 @@ class SucuriScanFileInfo extends SucuriScan {
1456
$filepath = @realpath( $directory );
1457
1458
if ( ! class_exists( 'FilesystemIterator' ) ){
1459
- return $this->get_directory_tree( $directory, 'opendir' );
1460
}
1461
1462
if ( $this->run_recursively ){
@@ -3144,8 +3149,6 @@ class SucuriScanEvent extends SucuriScan {
3144
$new_keys_string = '';
3145
3146
foreach ( (array) $config_lines as $config_line ){
3147
- $config_line = str_replace( "\n", '', $config_line );
3148
-
3149
if ( preg_match( $pattern, $config_line, $match ) ){
3150
$key_name = $match[1];
3151
@@ -4026,6 +4029,11 @@ class SucuriScanAPI extends SucuriScanOption {
4026
}
4027
}
4028
4029
if ( $method == 'GET' ) {
4030
if ( ! empty($params) ) {
4031
$url = sprintf( '%s?%s', $url, http_build_query( $params ) );
@@ -4362,46 +4370,60 @@ class SucuriScanAPI extends SucuriScanOption {
4362
4363
if ( self::handle_response( $response ) ) {
4364
$response['body']->output_data = array();
4365
- $log_pattern = '/^([0-9-: ]+) (.*) : (.*)/';
4366
$extra_pattern = '/(.+ \(multiple entries\):) (.+)/';
4367
- $generic_pattern = '/^([A-Z][a-z]{3,7}): ([0-9a-zA-Z@_\s\.\-\(\)]+, )?(\S+; )?(.+)/';
4368
$auth_pattern = '/^User authentication (succeeded|failed): ([^<;]+)/';
4369
4370
foreach ( $response['body']->output as $log ) {
4371
if ( preg_match( $log_pattern, $log, $log_match ) ) {
4372
$log_data = array(
4373
'event' => 'notice',
4374
- 'datetime' => $log_match[1],
4375
- 'timestamp' => strtotime( $log_match[1] ),
4376
- 'account' => $log_match[2],
4377
'username' => 'system',
4378
'remote_addr' => '::1',
4379
- 'message' => $log_match[3],
4380
'file_list' => false,
4381
'file_list_count' => 0,
4382
);
4383
4384
- $log_data['message'] = str_replace( ', new size', '; new size', $log_data['message'] );
4385
$log_data['message'] = str_replace( '<br>', '; ', $log_data['message'] );
4386
4387
// Extract more information from the generic audit logs.
4388
if ( preg_match( $generic_pattern, $log_data['message'], $log_extra ) ) {
4389
$log_data['event'] = strtolower( $log_extra[1] );
4390
- $log_data['message'] = trim( $log_extra[4] );
4391
-
4392
- // Extract the remote address from the generic logs.
4393
- if ( ! empty($log_extra[3]) ) {
4394
- $log_data['remote_addr'] = str_replace( ";\x20", '', $log_extra[3] );
4395
- }
4396
4397
- // Extract the username from the authentication logs.
4398
if ( ! empty($log_extra[2]) ) {
4399
- $log_data['username'] = preg_replace( '/.*\((\S+)\),\s#x2F;', '$1', $log_extra[2] );
4400
- $log_data['username'] = str_replace( ",\x20", '', $log_data['username'] );
4401
}
4402
4403
- // Match old user authentication logs.
4404
- $log_data['message'] = str_replace( 'logged in', 'authentication succeeded', $log_data['message'] );
4405
4406
if ( preg_match( $auth_pattern, $log_data['message'], $user_match ) ) {
4407
$log_data['username'] = $user_match[2];
@@ -4411,6 +4433,7 @@ class SucuriScanAPI extends SucuriScanOption {
4411
// Extract more information from the special formatted logs.
4412
if ( preg_match( $extra_pattern, $log_data['message'], $log_extra ) ) {
4413
$log_data['message'] = $log_extra[1];
4414
$log_data['file_list'] = explode( ',', $log_extra[2] );
4415
$log_data['file_list_count'] = count( $log_data['file_list'] );
4416
}
@@ -4430,7 +4453,7 @@ class SucuriScanAPI extends SucuriScanOption {
4430
*
4431
* @return array Valid audit event types with their colors.
4432
*/
4433
- public static function get_audit_event_types(){
4434
$event_types = array(
4435
'critical' => '#000000',
4436
'debug' => '#c690ec',
@@ -4794,14 +4817,19 @@ class SucuriScanAPI extends SucuriScanOption {
4794
isset($json_data->checksums)
4795
&& ! empty($json_data->checksums)
4796
) {
4797
- $checksums = $json_data->checksums;
4798
4799
- // Convert the object list to an array for better handle of the data.
4800
if ( $checksums instanceof stdClass ) {
4801
- $checksums = (array) $checksums;
4802
}
4803
-
4804
- return $checksums;
4805
}
4806
}
4807
@@ -8525,6 +8553,7 @@ function sucuriscan_check_core_integrity( $version = 0 ){
8525
8526
// Search added files (files not common in a normal wordpress installation).
8527
foreach ( $wp_core_hashes as $file_path => $extra_info ){
8528
$file_path = preg_replace( '/^\.\/(.*)/', '$1', $file_path );
8529
8530
if ( sucuriscan_ignore_integrity_filepath( $file_path ) ){ continue; }
4
Plugin URI: http://wordpress.sucuri.net/
5
Description: The <a href="http://sucuri.net/" target="_blank">Sucuri</a> plugin provides the website owner the best Activity Auditing, SiteCheck Remote Malware Scanning, Effective Security Hardening and Post-Hack features. SiteCheck will check for malware, spam, blacklisting and other security issues like .htaccess redirects, hidden eval code, etc. The best thing about it is it's completely free.
6
Author: Sucuri, INC
7
+ Version: 1.7.8
8
Author URI: http://sucuri.net
9
*/
10
66
/**
67
* Current version of the plugin's code.
68
*/
69
+ define( 'SUCURISCAN_VERSION', '1.7.8' );
70
71
/**
72
* The name of the Sucuri plugin main file.
608
* @return string Secret key definition pattern.
609
*/
610
public static function secret_key_pattern(){
611
+ return '/define\(\s*\'([A-Z_]+)\',(\s*)\'(.+)\'\s*\);/';
612
}
613
614
/**
1370
$tree = $this->get_directory_tree_with_spl( $directory );
1371
} else {
1372
$this->scan_interface = 'opendir';
1373
+ SucuriScanOption::update_option( ':scan_interface', $this->scan_interface );
1374
$tree = $this->get_directory_tree( $directory );
1375
}
1376
break;
1457
$filepath = @realpath( $directory );
1458
1459
if ( ! class_exists( 'FilesystemIterator' ) ){
1460
+ $this->scan_interface = 'opendir';
1461
+ SucuriScanOption::update_option( ':scan_interface', $this->scan_interface );
1462
+ $alternative_tree = $this->get_directory_tree( $directory );
1463
+
1464
+ return $alternative_tree;
1465
}
1466
1467
if ( $this->run_recursively ){
3149
$new_keys_string = '';
3150
3151
foreach ( (array) $config_lines as $config_line ){
3152
if ( preg_match( $pattern, $config_line, $match ) ){
3153
$key_name = $match[1];
3154
4029
}
4030
}
4031
4032
+ // Add random request parameter to avoid request reset.
4033
+ if ( ! empty($params) ) {
4034
+ $params['time'] = time();
4035
+ }
4036
+
4037
if ( $method == 'GET' ) {
4038
if ( ! empty($params) ) {
4039
$url = sprintf( '%s?%s', $url, http_build_query( $params ) );
4370
4371
if ( self::handle_response( $response ) ) {
4372
$response['body']->output_data = array();
4373
+ $log_pattern = '/^([0-9\-]+) ([0-9:]+) (\S+) : (.+)/';
4374
$extra_pattern = '/(.+ \(multiple entries\):) (.+)/';
4375
+ $generic_pattern = '/^([A-Z][a-z]{3,7}): ([^:;]+; )?(.+)/';
4376
$auth_pattern = '/^User authentication (succeeded|failed): ([^<;]+)/';
4377
4378
foreach ( $response['body']->output as $log ) {
4379
if ( preg_match( $log_pattern, $log, $log_match ) ) {
4380
$log_data = array(
4381
'event' => 'notice',
4382
+ 'date' => $log_match[1],
4383
+ 'time' => $log_match[2],
4384
+ 'datetime' => '',
4385
+ 'timestamp' => 0,
4386
+ 'account' => $log_match[3],
4387
'username' => 'system',
4388
'remote_addr' => '::1',
4389
+ 'message' => $log_match[4],
4390
'file_list' => false,
4391
'file_list_count' => 0,
4392
);
4393
4394
+ $log_data['datetime'] = sprintf( '%s %s', $log_match[1], $log_match[2] );
4395
+ $log_data['timestamp'] = strtotime( $log_data['datetime'] );
4396
$log_data['message'] = str_replace( '<br>', '; ', $log_data['message'] );
4397
4398
// Extract more information from the generic audit logs.
4399
if ( preg_match( $generic_pattern, $log_data['message'], $log_extra ) ) {
4400
$log_data['event'] = strtolower( $log_extra[1] );
4401
+ $log_data['message'] = trim( $log_extra[3] );
4402
4403
+ // Extract the username and remote address from the log.
4404
if ( ! empty($log_extra[2]) ) {
4405
+ $username_address = rtrim( $log_extra[2], ";\x20" );
4406
+
4407
+ // Separate the username from the remote address.
4408
+ if ( strpos( $username_address, ",\x20" ) !== false ) {
4409
+ $usip_parts = explode( ",\x20", $username_address, 2 );
4410
+
4411
+ if ( count( $usip_parts ) == 2 ) {
4412
+ // Separate the username from the display name.
4413
+ $log_data['username'] = preg_replace( '/^.+ \((.+)\)#x2F;', '$1', $usip_parts[0] );
4414
+ $log_data['remote_addr'] = $usip_parts[1];
4415
+ }
4416
+ } else {
4417
+ $log_data['remote_addr'] = $username_address;
4418
+ }
4419
}
4420
4421
+ // Fix old user authentication logs for backward compatibility.
4422
+ $log_data['message'] = str_replace(
4423
+ 'logged in',
4424
+ 'authentication succeeded',
4425
+ $log_data['message']
4426
+ );
4427
4428
if ( preg_match( $auth_pattern, $log_data['message'], $user_match ) ) {
4429
$log_data['username'] = $user_match[2];
4433
// Extract more information from the special formatted logs.
4434
if ( preg_match( $extra_pattern, $log_data['message'], $log_extra ) ) {
4435
$log_data['message'] = $log_extra[1];
4436
+ $log_extra[2] = str_replace( ', new size', '; new size', $log_extra[2] );
4437
$log_data['file_list'] = explode( ',', $log_extra[2] );
4438
$log_data['file_list_count'] = count( $log_data['file_list'] );
4439
}
4453
*
4454
* @return array Valid audit event types with their colors.
4455
*/
4456
+ public static function get_audit_event_types() {
4457
$event_types = array(
4458
'critical' => '#000000',
4459
'debug' => '#c690ec',
4817
isset($json_data->checksums)
4818
&& ! empty($json_data->checksums)
4819
) {
4820
+ if (
4821
+ count( (array) $json_data->checksums ) <= 1
4822
+ && property_exists( $json_data->checksums, $version )
4823
+ ) {
4824
+ $checksums = $json_data->checksums->{$version};
4825
+ } else {
4826
+ $checksums = $json_data->checksums;
4827
+ }
4828
4829
+ // Check whether the list of file is an object.
4830
if ( $checksums instanceof stdClass ) {
4831
+ return (array) $checksums;
4832
}
4833
}
4834
}
4835
8553
8554
// Search added files (files not common in a normal wordpress installation).
8555
foreach ( $wp_core_hashes as $file_path => $extra_info ){
8556
+ $file_path = str_replace( DIRECTORY_SEPARATOR, '/', $file_path );
8557
$file_path = preg_replace( '/^\.\/(.*)/', '$1', $file_path );
8558
8559
if ( sucuriscan_ignore_integrity_filepath( $file_path ) ){ continue; }