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$/', '$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( '/^.+ \((.+)\)$/', '$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; }