HEX
Server: nginx/1.18.0
System: Linux hqnl0246134.online-vm.com 5.4.0-135-generic #152-Ubuntu SMP Wed Nov 23 20:19:22 UTC 2022 x86_64
User: www-data (33)
PHP: 7.4.33
Disabled: phpinfo,disk_free_space,disk_total_space,diskfreespace,dl,exec,opcache_get_configuration,opcache_get_status,passthru,pclose,pcntl_alarm,pcntl_exec,pcntl_fork,pcntl_get_last_error,pcntl_getpriority,pcntl_setpriority,pcntl_signal,pcntl_signal_dispatch,pcntl_sigprocmask,pcntl_sigtimedwait,pcntl_sigwaitinfo,pcntl_strerror,pcntl_waitpid,pcntl_wait,pcntl_wexitstatus,pcntl_wifcontinued,pcntl_wifexited,pcntl_wifsignaled,pcntl_wifstopped,pcntl_wstopsig,pcntl_wtermsig,popen,posix_getpwuid,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,posix_uname,proc_close,proc_get_status,proc_nice,proc_terminate,shell_exec,show_source,system,exec,passthru,shell_exec,system,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
Upload Files
File: /var/www/sites/scanner-whitelist.json
{"73ad4ddac917fd39deaf5f0da8b278fc":{"file":"\/breather.com.ua\/wp-content\/plugins\/wp-cerber\/admin\/cerber-dashboard.php","exploit":"11413268","line":2897,"match":"exploit"},"e1f231031938a0950aa2b2117dbf893e":{"file":"\/breather.com.ua\/wp-content\/plugins\/wp-cerber\/admin\/cerber-dashboard.php","exploit":"eval_strrev","line":871,"match":"lave"},"e409db13fe334b3d35e198147894c8b3":{"file":"\/breather.com.ua\/wp-content\/plugins\/wp-cerber\/cerber-common.php","exploit":"silenced_eval","line":3709,"match":"@eval( $config )"},"0235cdb5b8cb81f58143eed9073c8da4":{"file":"\/breather.com.ua\/wp-content\/plugins\/wp-cerber\/cerber-common.php","exploit":"1058174d","line":4196,"match":"[] = 'RewriteEngine On"},"e7357c06bcf6972c554220e2082e0433":{"file":"\/breather.com.ua\/wp-content\/plugins\/wp-cerber\/cerber-common.php","exploit":"eval","line":null,"match":"eval( $config ); ob_end_clean(); if ( defined( 'DB_USER' ) && defined( 'DB_PASSWORD' ) && defined( 'DB_NAME' ) && defined( 'DB_HOST' ) ) { require_once( $db_class ); return new wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST ); } } return false; } function crb_get_mysql_var( $var ) { static $cache; if ( ! isset( $cache[ $var ] ) ) { if ( $v = cerber_db_get_row( 'SHOW VARIABLES LIKE \"' . $var . '\"' ) ) { $cache[ $var ] = $v['Value']; } else { $cache[ $var ] = false; } } return $cache[ $var ]; } function cerber_db_check_column_type( string $table_name, string $column_name, string $expected_type, array $expected = [] ): bool { $table_name = crb_sanitize_id( $table_name ); $column_name = crb_sanitize_id( $column_name ); $select_fields = \"DATA_TYPE\"; if ( ! empty( $expected ) ) { $additional_fields = array_map( 'crb_sanitize_id', array_keys( $expected ) ); $select_fields .= \", \" . implode( \", \", $additional_fields ); } $query = 'SELECT ' . $select_fields . '\r\n              FROM INFORMATION_SCHEMA.COLUMNS\r\n              WHERE TABLE_SCHEMA = DATABASE()\r\n                AND TABLE_NAME = \"' . $table_name . '\"\r\n                AND COLUMN_NAME = \"' . $column_name . '\"\r\n              LIMIT 1'; $result = cerber_db_get_results( $query ); if ( empty( $result ) ) { return false; } $column_def = $result[0]; $column_def = array_change_key_case( $column_def, CASE_LOWER ); if ( strtolower( $column_def['data_type'] ) !== strtolower( $expected_type ) ) { return false; } elseif ( ! $expected ) { return true; } foreach ( $expected as $parameter => $expected_value ) { if ( ! array_key_exists( $parameter, $column_def ) ) { return false; } if ( is_numeric( $expected_value ) ) { if ( intval( $column_def[ $parameter ] ) !== intval( $expected_value ) ) { return false; } } else { if ( $column_def[ $parameter ] != $expected_value ) { return false; } } } return true; } function cerber_get_set( $key, $id = null, $unserialize = true, $use_cache = null ) { if ( ! $key = preg_replace( CRB_SANITIZE_KEY, '', $key ) ) { return false; } $cache_key = 'crb#' . $key . '#'; $id = ( $id !== null ) ? absint( $id ) : 0; $cache_key .= $id; $ret = false; $use_cache = ( isset( $use_cache ) ) ? $use_cache : cerber_cache_is_enabled(); if ( $use_cache ) { $cache_value = cerber_cache_get( $cache_key, null ); if ( $cache_value !== null ) { return $cache_value; } } if ( $row = cerber_db_get_row( 'SELECT * FROM ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' WHERE the_key = \"' . $key . '\" AND the_id = ' . $id ) ) { if ( $row['expires'] > 0 && $row['expires'] < time() ) { cerber_delete_set( $key, $id ); if ( $use_cache ) { cerber_cache_delete( $cache_key ); } return false; } if ( $unserialize ) { if ( ! empty( $row['the_value'] ) ) { $ret = crb_unserialize( $row['the_value'] ); } else { $ret = array(); } } else { $ret = $row['the_value']; } } if ( $use_cache ) { cerber_cache_set( $cache_key, $ret ); } return $ret; } function cerber_update_set( $key, $value, $id = null, $serialize = true, $expires = null, $use_cache = null ) { if ( ! $key = preg_replace( CRB_SANITIZE_KEY, '', $key ) ) { return false; } $cache_key = 'crb#' . $key . '#'; $expires = ( $expires !== null ) ? absint( $expires ) : 0; $id = ( $id !== null ) ? absint( $id ) : 0; $cache_key .= $id; $use_cache = ( isset( $use_cache ) ) ? $use_cache : cerber_cache_is_enabled(); if ( $use_cache ) { cerber_cache_set( $cache_key, $value, $expires - time() ); } if ( $serialize && ! is_string( $value ) ) { $value = serialize( $value ); } $value = cerber_db_real_escape( $value ); if ( false !== cerber_get_set( $key, $id, false, false ) ) { $sql = 'UPDATE ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' SET the_value = \"' . $value . '\", expires = ' . $expires . ' WHERE the_key = \"' . $key . '\" AND the_id = ' . $id; } else { $sql = 'INSERT INTO ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' (the_key, the_id, the_value, expires) VALUES (\"' . $key . '\",' . $id . ',\"' . $value . '\",' . $expires . ')'; } unset( $value ); if ( cerber_db_query( $sql ) ) { return true; } else { return false; } } function cerber_delete_set( $key, $id = null ) { if ( ! $key = preg_replace( CRB_SANITIZE_KEY, '', $key ) ) { return false; } $cache_key = 'crb#' . $key . '#'; $id = ( $id !== null ) ? absint( $id ) : 0; $cache_key .= $id; cerber_cache_delete( $cache_key ); if ( cerber_db_query( 'DELETE FROM ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' WHERE the_key = \"' . $key . '\" AND the_id = ' . $id ) ) { return true; } return false; } function cerber_delete_expired_set( $all = false ) { if ( ! $all ) { $where = 'expires > 0 AND expires < ' . time(); } else { $where = 'expires > 0'; } if ( cerber_db_query( 'DELETE FROM ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' WHERE ' . $where ) ) { return true; } else { return false; } } function cerber_remove_comments( $string = '' ) { return preg_replace( '\/#.*\/', '', preg_replace( '#\/\/.*#', '', preg_replace( '#\/\\*(?:[^*]*(?:\\*(?!\/))*)*\\*\/#', '', $string ) ) ); } function cerber_set_groove( $expire ) { if ( ! headers_sent() ) { cerber_set_cookie( CRB_GROOVE, md5( cerber_get_groove() ), $expire + 1 ); $groove_x = cerber_get_groove_x(); cerber_set_cookie( CRB_GROOVE . '_x_' . $groove_x[0], $groove_x[1], $expire + 1 ); } } function cerber_is_auth_cookie( $text ) { return ( 0 === strpos( $text, cerber_get_cookie_prefix() . CRB_GROOVE ) ); } function cerber_get_groove() { $groove = cerber_get_site_option( 'cerber-groove', false ); if ( empty( $groove ) ) { $groove = crb_random_string( 16 ); update_site_option( 'cerber-groove', $groove ); } return $groove; } function cerber_check_groove( $hash = '' ) { if ( ! $hash ) { if ( ! $hash = cerber_get_cookie( CRB_GROOVE ) ) { return false; } } $groove = cerber_get_groove(); if ( $hash == md5( $groove ) ) { return true; } return false; } function cerber_check_groove_x() { $groove_x = cerber_get_groove_x(); if ( cerber_get_cookie( CRB_GROOVE . '_x_' . $groove_x[0] ) == $groove_x[1] ) { return true; } return false; } function cerber_get_groove_x( $regenerate = false ) { $groove_x = array(); if ( ! $regenerate ) { $groove_x = cerber_get_site_option( 'cerber-groove-x' ); } if ( $regenerate || empty( $groove_x ) || ! is_array( $groove_x ) ) { $groove_0 = crb_random_string( 24, 32 ); $groove_1 = crb_random_string( 24, 32 ); $groove_x = array( $groove_0, $groove_1 ); update_site_option( 'cerber-groove-x', $groove_x ); crb_update_cookie_dependent(); } return $groove_x; } function cerber_get_cookie_path() { if ( defined( 'COOKIEPATH' ) ) { return COOKIEPATH; } return '\/'; } function cerber_set_cookie( $name, $value, $expire = 0, $path = \"\", $domain = \"\", $http = false ) { global $wp_cerber_cookies; if ( cerber_is_wp_cron() ) { return false; } if ( ! $path ) { $path = cerber_get_cookie_path(); } $expire = absint( $expire ); $expire = ( $expire > 43009401600 ) ? 43009401600 : $expire; $ret = setcookie( cerber_get_cookie_prefix() . $name, $value, array( 'expires' => $expire, 'path' => $path, 'domain' => $domain, 'secure' => is_ssl(), 'httponly' => false, 'samesite' => 'Strict', ) ); if ( $ret ) { $wp_cerber_cookies[ cerber_get_cookie_prefix() . $name ] = array( $expire, $value ); } return $ret; } function cerber_get_cookie( $name, $default = false ) { return crb_array_get( $_COOKIE, cerber_get_cookie_prefix() . $name, $default ); } function cerber_get_cookie_prefix() { if ( $p = (string) crb_get_settings( 'cookiepref' ) ) { return $p; } return ''; } function crb_update_cookie_dependent() { static $done = false; if ( $done ) { return; } register_shutdown_function( function () { cerber_htaccess_sync( 'main' ); } ); $done = true; } function cerber_htaccess_sync( $file, $settings = array() ) { if ( ! $settings ) { $settings = crb_get_settings(); } if ( 'main' == $file ) { $rules = array(); if ( ! empty( $settings['adminphp'] ) && ( ! defined( 'CONCATENATE_SCRIPTS' ) || ! CONCATENATE_SCRIPTS ) ) { if ( ! crb_is_apache_mod_loaded( 'mod_rewrite' ) ) { return new WP_Error( 'no_mod', 'The Apache mod_rewrite module is not enabled on your web server. Ask your server administrator for assistance.' ); } $groove_x = cerber_get_groove_x(); $cookie = cerber_get_cookie_prefix() . CRB_GROOVE . '_x_' . $groove_x[0]; $rules [] = '# Protection of admin scripts is enabled (CVE-2018-6389)'; $rules [] = '<IfModule mod_rewrite.c>'; $rules [] = 'RewriteEngine On'; $rules [] = 'RewriteBase \/'; $rules [] = 'RewriteCond %{REQUEST_URI} ^(.*)wp-admin\/+load-scripts\\.php$ [OR,NC]'; $rules [] = 'RewriteCond %{REQUEST_URI} ^(.*)wp-admin\/+load-styles\\.php$ [NC]'; $rules [] = 'RewriteCond %{HTTP_COOKIE} !' . $cookie . '=' . $groove_x[1]; $rules [] = 'RewriteRule (.*) - [R=403,L]'; $rules [] = '<\/IfModule>'; } return cerber_update_htaccess( $file, $rules ); } if ( 'media' == $file ) { $rules = array(); if ( ! empty( $settings['phpnoupl'] ) ) { $rules [] = '<Files *>'; $rules [] = 'SetHandler none'; $rules [] = 'SetHandler default-handler'; $rules [] = 'Options -ExecCGI'; $rules [] = 'RemoveHandler .cgi .php .php3 .php4 .php5 .php7 .php8 .phtml .pl .py .pyc .pyo'; $rules [] = '<\/Files>'; $rules [] = '<IfModule mod_php.c>'; $rules [] = 'php_flag engine off'; $rules [] = '<\/IfModule>'; $rules [] = '<IfModule mod_php7.c>'; $rules [] = 'php_flag engine off'; $rules [] = '<\/IfModule>'; $rules [] = '<IfModule mod_php5.c>'; $rules [] = 'php_flag engine off'; $rules [] = '<\/IfModule>'; } return cerber_update_htaccess( $file, $rules ); } return false; } function cerber_htaccess_clean_up() { cerber_update_htaccess( 'main', array() ); cerber_update_htaccess( 'media', array() ); } function cerber_update_htaccess( $file, $rules = array() ) { if ( $file == 'main' ) { $htaccess = cerber_get_htaccess_file(); $marker = CERBER_MARKER1; } elseif ( $file == 'media' ) { $htaccess = cerber_get_upload_dir() . '\/.htaccess'; $marker = CERBER_MARKER2; } else { return new WP_Error( 'htaccess-io', 'Unknown .htaccess file specified' ); } if ( ! is_file( $htaccess ) ) { if ( ! touch( $htaccess ) ) { return new WP_Error( 'htaccess-io', 'ERROR: Unable to create the file ' . $htaccess ); } } elseif ( ! is_writable( $htaccess ) ) { return new WP_Error( 'htaccess-io', 'ERROR: Unable to update the file ' . $htaccess ); } $result = crb_insert_with_markers( $htaccess, $marker, $rules ); if ( $result || $result === 0 ) { $result = 'The file ' . $htaccess . ' has been updated'; } else { $result = new WP_Error( 'htaccess-io', 'ERROR: Unable to update the file ' . $htaccess ); } return $result; } function cerber_get_htaccess_file() { require_once( ABSPATH . 'wp-admin\/includes\/file.php' ); $home_path = get_home_path(); return $home_path . '.htaccess'; } function cerber_check_remote_domain( $domain_mask ) { $hostname = @gethostbyaddr( cerber_get_remote_ip() ); if ( ! $hostname || filter_var( $hostname, FILTER_VALIDATE_IP ) ) { return false; } if ( ! is_array( $domain_mask ) ) { $domain_mask = array( $domain_mask ); } foreach ( $domain_mask as $mask ) { if ( substr_count( $mask, '.' ) != substr_count( $hostname, '.' ) ) { continue; } $parts = array_reverse( explode( '.', $hostname ) ); $ok = true; foreach ( array_reverse( explode( '.', $mask ) ) as $i => $item ) { if ( $item != '*' && $item != $parts[ $i ] ) { $ok = false; break; } } if ( $ok == true ) { return true; } } return false; } function cerber_set_boot_mode( $mode = null ) { if ( $mode === null ) { $mode = crb_get_settings( 'boot-mode' ); } $source = dirname( cerber_plugin_file() ) . '\/modules\/aaa-wp-cerber.php'; $target = WPMU_PLUGIN_DIR . '\/aaa-wp-cerber.php'; if ( $mode == 1 ) { if ( file_exists( $target ) ) { if ( sha1_file( $source, true ) == sha1_file( $target, true ) ) { return 1; } if ( ! wp_is_writable( $target ) ) { return new WP_Error( 'cerber-boot', __( 'Destination file is not writable', 'wp-cerber' ) . ' ' . $target ); } } if ( ! is_dir( WPMU_PLUGIN_DIR ) ) { if ( ! mkdir( WPMU_PLUGIN_DIR, 0755, true ) ) { return new WP_Error( 'cerber-boot', __( 'Unable to create required directory', 'wp-cerber' ) . ' ' . WPMU_PLUGIN_DIR ); } } if ( ! wp_is_writable( WPMU_PLUGIN_DIR ) ) { return new WP_Error( 'cerber-boot', __( 'Destination directory is not writable', 'wp-cerber' ) . ' ' . WPMU_PLUGIN_DIR ); } if ( ! file_exists( $source ) ) { return new WP_Error( 'cerber-boot', __( 'Source file not found', 'wp-cerber' ) . ' ' . $source ); } if ( ! copy( $source, $target ) ) { return new WP_Error( 'cerber-boot', __( 'Unable to copy file', 'wp-cerber' ) . ' ' . $target ); } else { return 2; } } if ( file_exists( $target ) ) { if ( ! unlink( $target ) ) { return new WP_Error( 'cerber-boot', __( 'Unable to delete the file', 'wp-cerber' ) . ' ' . $target ); } else { cerber_diag_log( 'MU module deleted. IP:' . cerber_get_remote_ip() . ' METHOD: ' . $_SERVER['REQUEST_METHOD'] . ' ' . print_r( crb_get_post_fields(), 1 ) . ' UA: ' . $_SERVER['HTTP_USER_AGENT'] . ' REQ: ' . $_SERVER['REQUEST_URI'] ); return 3; } } return 4; } function cerber_get_mode() { if ( function_exists( 'cerber_mode' ) ) { return cerber_mode(); } return 0; } function cerber_is_permalink_enabled() { static $ret; if ( ! isset( $ret ) ) { $ret = (bool) get_option( 'permalink_structure' ); } return $ret; } function crb_check_dir( $dir, &$msg = '', $none = '' ) { $ret = 0; if ( ! is_dir( $dir ) ) { $ret = 1; $msg = $none ?: 'Required directory does not exist: ' . crb_escape( $dir ); } elseif ( ! wp_is_writable( $dir ) ) { if ( ! chmod( $dir, 0755 ) ) { $ret = 2; $msg = 'Required directory is not writable. Please check write permissions and ownership of this directory: ' . crb_escape( $dir ); } } return $ret; } function cerber_mb_basename( $file_name ) { $pos = mb_strrpos( $file_name, DIRECTORY_SEPARATOR ); if ( $pos !== false ) { return mb_substr( $file_name, $pos + 1 ); } return $file_name; } function cerber_get_extension( $file_name ) { $file_name = cerber_mb_basename( $file_name ); $pos = mb_strpos( $file_name, '.' ); if ( $pos !== false ) { if ( $ext = mb_substr( $file_name, $pos + 1 ) ) { return mb_strtolower( $ext ); } } return ''; } function crb_wp_version_compare( $ver, $comp = '>=' ) { return version_compare( cerber_get_wp_version(), (string) $ver, $comp ); } function cerber_get_wp_version() { static $ver; if ( ! $ver ) { include( ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'version.php' ); $ver = (string) $wp_version; } return $ver; } function cerber_get_wp_locale() { static $lc; if ( ! $lc ) { include( ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'version.php' ); $lc = $wp_local_package ?? 'en_US'; } return $lc; } function crb_get_themes() { static $theme_headers = array( 'Name' => 'Theme Name', 'ThemeURI' => 'Theme URI', 'Description' => 'Description', 'Author' => 'Author', 'AuthorURI' => 'Author URI', 'Version' => 'Version', 'Template' => 'Template', 'Status' => 'Status', 'Tags' => 'Tags', 'TextDomain' => 'Text Domain', 'DomainPath' => 'Domain Path', ); $themes = array(); if ( $list = search_theme_directories() ) { foreach ( $list as $key => $info ) { $css = $info['theme_root'] . '\/' . $info['theme_file']; if ( is_readable( $css ) ) { $themes[ $key ] = get_file_data( $info['theme_root'] . '\/' . $info['theme_file'], $theme_headers, 'theme' ); $themes[ $key ]['theme_root'] = $info['theme_root']; $themes[ $key ]['theme_file'] = $info['theme_file']; } } } return $themes; } function cerber_is_base64_encoded( $val ) { $val = trim( $val ); if ( empty( $val ) || is_numeric( $val ) || strlen( $val ) < 8 || preg_match( '\/[^A-Z0-9\\+\\\/=]\/i', $val ) ) { return false; } if ( $val = @base64_decode( $val ) ) { if ( ! preg_match( '\/[\\x00-\\x08\\x0B-\\x0C\\x0E-\\x1F]\/', $val ) ) { if ( preg_match( '\/[A-Z]\/i', $val ) ) { return $val; } } } return false; } function crb_is_alphanumeric( $str ) { return ! preg_match( '\/[^\\w\\-]\/', $str ); } function crb_arrays_similar( &$arr, $fields ) { if ( crb_array_diff_keys( $arr, $fields ) ) { return false; } foreach ( $fields as $field => $pattern ) { if ( is_callable( $pattern ) ) { if ( ! call_user_func( $pattern, $arr[ $field ] ) ) { return false; } } else { if ( ! preg_match( $pattern, $arr[ $field ] ) ) { return false; } } } return true; } function cerber_get_html_label( int $iid ) { $c = ( $iid == CERBER_FOK ) ? '#33be84' : '#e94045'; return '<span style=\"background-color: ' . $c . '; color: #fff; margin-left: 6px; display: inline-block; line-height: 1em; padding: 3px 5px; font-size: 92%;\">' . cerber_get_issue_labels( $iid ) . '<\/span>'; } function crb_getallheaders() { static $headers; if ( function_exists( 'getallheaders' ) ) { return getallheaders(); } if ( ! $headers ) { $headers = array(); foreach ( $_SERVER as $name => $value ) { if ( substr( $name, 0, 5 ) == 'HTTP_' ) { $headers[ str_replace( ' ', '-', ucwords( strtolower( str_replace( '_', ' ', substr( $name, 5 ) ) ) ) ) ] = $value; } } } return $headers; } function crb_is_request_header( $search_header ) { static $headers; list( $name, $value ) = explode( ':', $search_header, 2 ); $name = strtolower( trim( $name ) ); $value = strtolower( trim( $value ) ); if ( ! $name || ! $value ) { return false; } if ( ! $headers ) { $headers = array_change_key_case( crb_getallheaders(), CASE_LOWER ); } if ( $header_value = $headers[ $name ] ?? false ) { return strtolower( trim( $header_value ) ) === $value; } return false; } function cerber_error_log( $msg, $source = '' ) { cerber_diag_log( $msg, $source, true ); } function cerber_diag_log( $msg, string $source = '', $error = false ) { if ( $source == 'CLOUD' && ( ! defined( 'CERBER_CLOUD_DEBUG' ) || ! CERBER_CLOUD_DEBUG || ( ! defined( 'WP_ADMIN' ) && ! defined( 'WP_NETWORK_ADMIN' ) ) ) ) { return false; } if ( ! $msg || ( ! $log_file = cerber_get_diag_log() ) || ( ! $log = @fopen( $log_file, 'a' ) ) ) { return false; } if ( $source ) { $source = '[' . $source . ']'; } if ( $error ) { $source .= ' ERROR: '; } if ( ! is_array( $msg ) ) { $msg = array( $msg ); } foreach ( $msg as $line ) { if ( is_array( $line ) ) { $line = print_r( $line, 1 ); } $ret = @fwrite( $log, '[' . cerber_date( time(), false ) . ']' . $source . ' ' . $line . PHP_EOL ); } @fclose( $log ); return $ret; } function cerber_get_diag_log(): string { if ( ! $dir = crb_get_diag_dir() ) { return ''; } return $dir . 'cerber-debug.log'; } function crb_get_diag_dir(): string { if ( defined( 'CERBER_DIAG_DIR' ) && is_dir( CERBER_DIAG_DIR ) ) { return rtrim( CERBER_DIAG_DIR, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR; } elseif ( $dir = cerber_get_the_folder() ) { return $dir; } return ''; } function cerber_truncate_log( $bytes = 10000000 ) { update_user_meta( get_current_user_id(), 'clast_log_view', array() ); $file = cerber_get_diag_log(); if ( ! is_file( $file ) || filesize( $file ) <= $bytes ) { return; } if ( $bytes == 0 ) { $log = @fopen( $file, 'w' ); @fclose( $log ); return; } if ( $text = file_get_contents( $file ) ) { $text = substr( $text, 0 - $bytes ); if ( ! $log = @fopen( $file, 'w' ) ) { return; } @fwrite( $log, $text ); @fclose( $log ); } } function crb_get_bloginfo( $what ) { static $info = array(); if ( ! isset( $info[ $what ] ) ) { $info[ $what ] = get_bloginfo( $what ); } return $info[ $what ]; } function crb_is_php_mod() { require_once( ABSPATH . 'wp-admin\/includes\/misc.php' ); if ( apache_mod_loaded( 'mod_php7' ) ) { return true; } if ( apache_mod_loaded( 'mod_php5' ) ) { return true; } return false; } function cerber_fromcharcode( $str ) { $vals = explode( ',', $str ); $vals = array_map( function ( $v ) { $v = trim( $v ); if ( $v[0] == '0' ) { $v = ( $v[1] == 'x' || $v[1] == 'X' ) ? hexdec( $v ) : octdec( $v ); } else { $v = intval( $v ); } return '&#' . $v . ';'; }, $vals ); return mb_convert_encoding( implode( '', $vals ), 'UTF-8', 'HTML-ENTITIES' ); } function cerber_empty_dir( $dir ) { if ( ! @is_dir( $dir ) || 0 === strpos( $dir, ABSPATH ) ) { return new WP_Error( 'no-dir', 'This directory cannot be emptied' ); } $files = @scandir( $dir ); if ( ! is_array( $files ) || empty( $files ) ) { return true; } $fs = cerber_init_wp_filesystem(); if ( crb_is_wp_error( $fs ) ) { return $fs; } $ret = true; foreach ( $files as $file ) { $full = $dir . $file; if ( @is_file( $full ) ) { if ( ! @unlink( $full ) ) { $ret = false; } } elseif ( ! in_array( $file, array( '..', '.' ) ) && is_dir( $full ) ) { if ( ! $fs->rmdir( $full, true ) ) { $ret = false; } } } if ( ! $ret ) { return new WP_Error( 'file-deletion-error', 'Some files or subdirectories in this directory cannot be deleted: ' . $dir ); } return $ret; } function crb_create_folder( $target_dir, $permissions = 0755 ) { if ( file_exists( $target_dir ) ) { return true; } $err = ''; if ( ! mkdir( $target_dir, $permissions, true ) ) { $err = 'Unable to create directory: <b>' . $target_dir . '<\/b>. Check permissions of parent directory.'; } elseif ( ! chmod( $target_dir, $permissions ) ) { $err = 'Unable to set directory permissions for ' . $target_dir; } if ( $err ) { return new WP_Error( 'cerber-dir', $err ); } return true; } function crb_raise_limits( $mem = null ) { @ini_set( 'max_execution_time', 180 ); if ( function_exists( 'set_time_limit' ) && false === strpos( ini_get( 'disable_functions' ), 'set_time_limit' ) ) { @set_time_limit( 0 ); } if ( $mem ) { @ini_set( 'memory_limit', $mem ); } } function cerber_mask_email( $email ) { list( $box, $host ) = explode( '@', $email ); $box = str_pad( $box[0], strlen( $box ), '*' ); $host = str_pad( substr( $host, strrpos( $host, '.' ) ), strlen( $host ), '*', STR_PAD_LEFT ); return str_replace( '*', '&#8727;', $box . '@' . $host ); } function crb_mask_login( $login ) { if ( is_email( $login ) ) { return cerber_mask_email( $login ); } $strlen = mb_strlen( $login ); return str_pad( mb_substr( $login, 0, intdiv( $strlen, 2 ) ), $strlen, '*' ); } function crb_mask_ip( $ip = '' ) { if ( cerber_is_ipv6( $ip ) ) { $pos = strpos( $ip, ':', strpos( $ip, ':', strpos( $ip, ':' ) + 1 ) + 1 ); $delimiter = ':'; } else { $pos = strpos( $ip, '.', strpos( $ip, '.' ) + 1 ); $delimiter = '.'; } if ( ! $pos ) { return $ip; } $net = substr( $ip, 0, $pos ); $sub = substr( $ip, $pos ); return $net . preg_replace( '\/[^' . $delimiter . ']\/', '*', $sub ); } function crb_insert_with_markers( $filename, $marker, $insertion ) { if ( ! file_exists( $filename ) ) { if ( ! is_writable( dirname( $filename ) ) ) { return false; } if ( ! touch( $filename ) ) { return false; } } elseif ( ! is_writeable( $filename ) ) { return false; } if ( ! is_array( $insertion ) ) { $insertion = explode( \"\\n\", $insertion ); } $start_marker = \"# BEGIN {$marker}\"; $end_marker = \"# END {$marker}\"; $fp = fopen( $filename, 'r+' ); if ( ! $fp ) { return false; } flock( $fp, LOCK_EX ); $lines = array(); while ( ! feof( $fp ) ) { $lines[] = rtrim( fgets( $fp ), \"\\r\\n\" ); } $pre_lines = array(); $post_lines = array(); $existing_lines = array(); $found_marker = false; $found_end_marker = false; foreach ( $lines as $line ) { if ( ! $found_marker && false !== strpos( $line, $start_marker ) ) { $found_marker = true; continue; } elseif ( ! $found_end_marker && false !== strpos( $line, $end_marker ) ) { $found_end_marker = true; continue; } if ( ! $found_marker ) { $pre_lines[] = $line; } elseif ( $found_marker && $found_end_marker ) { $post_lines[] = $line; } else { $existing_lines[] = $line; } } if ( $existing_lines === $insertion ) { flock( $fp, LOCK_UN ); fclose( $fp ); return true; } $new_file_data = implode( \"\\n\", array_merge( $pre_lines, array( $start_marker ), $insertion, array( $end_marker ), $post_lines ) ); fseek( $fp, 0 ); $bytes = fwrite( $fp, $new_file_data ); if ( $bytes ) { ftruncate( $fp, ftell( $fp ) ); } fflush( $fp ); flock( $fp, LOCK_UN ); fclose( $fp ); return (bool) $bytes; } function cerber_init_wp_filesystem() { global $wp_filesystem; if ( $wp_filesystem instanceof WP_Filesystem_Direct ) { return $wp_filesystem; } require_once( ABSPATH . 'wp-admin\/includes\/file.php' ); add_filter( 'filesystem_method', '__ret_direct' ); if ( ! WP_Filesystem() ) { return new WP_Error( 'cerber-file', 'Unable to init WP_Filesystem' ); } remove_filter( 'filesystem_method', '__ret_direct' ); return $wp_filesystem; } function __ret_direct() { return 'direct'; } function crb_redirect( string $url ) { CRB_Globals::$redirect_url = $url; return wp_redirect( $url ); } function crb_safe_redirect( string $url ) { CRB_Globals::$redirect_url = $url; return wp_safe_redirect( $url ); } function crb_get_alert_params() { $params = CRB_ALERT_PARAMS; $get = crb_get_query_params(); if ( ! array_intersect_key( $params, $get ) ) { return $params; } if ( ! empty( $get['filter_ip'] ) ) { $begin = 0; $end = 0; $ip = cerber_any2range( $get['filter_ip'] ); if ( is_array( $ip ) ) { $begin = $ip['begin']; $end = $ip['end']; $ip = 0; } elseif ( ! $ip ) { $ip = 0; } $params['begin'] = $begin; $params['end'] = $end; $params['filter_ip'] = $ip; } $temp = $params; unset( $temp['begin'], $temp['end'], $temp['filter_ip'] ); foreach ( array_keys( $temp ) as $key ) { if ( ! empty( $get[ $key ] ) ) { if ( is_array( $get[ $key ] ) ) { $params[ $key ] = array_map( 'trim', $get[ $key ] ); } else { $params[ $key ] = trim( $get[ $key ] ); } } else { $params[ $key ] = 0; } } if ( ! empty( $params['al_expires'] ) ) { $time = 24 * 3600 + strtotime( 'midnight ' . $params['al_expires'] ); $params['al_expires'] = $time - get_option( 'gmt_offset' ) * 3600; } $int_fields = array( 'al_limit', 'al_ignore_rate', 'al_send_emails', 'al_send_pushbullet', 'al_send_me', ); foreach ( $int_fields as $f ) { $params[ $f ] = crb_absint( $params[ $f ] ); } if ( ! is_array( $params['filter_activity'] ) ) { $params['filter_activity'] = array( $params['filter_activity'] ); } $params['filter_activity'] = array_filter( $params['filter_activity'] ); array_walk_recursive( $params, function ( &$item ) { $item = str_replace( array( '<', '>', '[', ']', '\"', \"'\" ), '', $item ); } ); return $params; } function crb_get_alert_id( $params ) { return sha1( json_encode( array_values( array_diff_key( $params, array_flip( CRB_NON_ALERT_PARAMS ) ) ) ) ); } function crb_random_string( $length_min, $length_max = null, $inc_num = true, $upper_case = true, $extra = '' ) { static $alpha1 = 'abcdefghijklmnopqrstuvwxyz'; static $alpha2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; static $digits = '0123456789'; if ( ! $length_max ) { $length_max = $length_min; } $str = $alpha1; if ( $inc_num ) { $str .= $digits; } if ( $upper_case ) { $str .= $alpha2; } if ( $extra ) { $str .= $extra; } $n = (int) ceil( $length_max \/ strlen( $str ) ); if ( $n > 1 ) { $str = implode( '', array_fill( 0, $n, $str ) ); } $length = ( $length_min != $length_max ) ? rand( $length_min, $length_max ) : $length_min; return substr( str_shuffle( $str ), 0, $length ); } function crb_auto_decode( &$text ) { if ( ! $text ) { return array(); } if ( $text[0] == 'a' ) { return crb_unserialize( $text ); } return @json_decode( $text, true ); } function crb_unserialize( &$string ) { return @unserialize( $string, [ 'allowed_classes' => false ] ); } function crb_get_review_url( $vendor = null ) { static $urls = array( 'tpilot' => array( 'https:\/\/www.trustpilot.com\/review\/wpcerber.com', 'https:\/\/www.trustpilot.com\/evaluate\/wpcerber.com' ), 'g2' => array( 'https:\/\/www.g2.com\/products\/cerber-security-antispam-malware-scan\/reviews\/start' ), 'wp' => array( 'https:\/\/wordpress.org\/support\/plugin\/wp-cerber\/reviews\/#new-post' ), 'cap' => array( 'https:\/\/reviews.capterra.com\/new\/187653' ), 'tradius' => array( 'https:\/\/www.trustradius.com\/products\/wp-cerber-security\/reviews' ), ); $ret = $urls[ $vendor ]; if ( $vendor == 'tpilot' ) { shuffle( $ret ); } return $ret[0]; } function crb_was_activated( $ago ) { static $actvd; if ( ! isset( $actvd ) ) { if ( ! $actvd = cerber_get_set( '_activated' ) ) { return true; } } return ( ( (int) crb_array_get( $actvd, 'time' ) + $ago ) <= time() ); } function cerber_hash_token( $token ) { if ( function_exists( 'hash' ) ) { return hash( 'sha256', $token ); } else { return sha1( $token ); } } function crb_absint( $val ) { return abs( (int) $val ); } function crb_is_apache_mod_loaded( $mod = '' ) { static $loaded = array(); if ( ! isset( $loaded[ $mod ] ) ) { $loaded[ $mod ] = apache_mod_loaded( 'mod_rewrite' ); } return $loaded[ $mod ]; } final class CRB_Cache { private static $cache = array(); private static $stat = array(); private static $wp_cache_group = 'wp_cerber'; private static $wp_key_list = 'wp_cerber_list'; static function set( $key, $value, $expire = 0 ) { $exp = 0; if ( $expire > 0 ) { $exp = time() + (int) $expire; if ( $exp < time() ) { return false; } } $element = array( $value, $exp ); self::$cache[ $key ] = $element; if ( self::checker() ) { wp_cache_set( $key, $element, self::$wp_cache_group ); $entries = wp_cache_get( self::$wp_key_list, self::$wp_key_list ); if ( ! $entries ) { $entries = array(); } $entries[ $key ] = $expire; wp_cache_set( self::$wp_key_list, $entries, self::$wp_key_list ); } if ( ! isset( self::$stat[ $key ] ) ) { self::$stat[ $key ] = array( 0, 0 ); } self::$stat[ $key ][0] ++; return true; } static function get( $key, $default = null ) { $element = crb_array_get( self::$cache, $key ); if ( ! is_array( $element ) ) { if ( self::checker() ) { $element = wp_cache_get( $key, self::$wp_cache_group ); } } if ( ! is_array( $element ) ) { return $default; } if ( ! empty( $element[1] ) && $element[1] < time() ) { self::delete( $key ); return $default; } if ( ! isset( self::$stat[ $key ] ) ) { self::$stat[ $key ] = array( 0, 0 ); } self::$stat[ $key ][1] ++; return $element[0]; } static function delete( $key ) { if ( isset( self::$cache[ $key ] ) ) { unset( self::$cache[ $key ] ); } if ( self::checker() ) { wp_cache_delete( $key, self::$wp_cache_group ); } } static function reset() { self::$cache = array(); if ( $entries = wp_cache_get( self::$wp_key_list, self::$wp_key_list ) ) { foreach ( $entries as $entry => $exp ) { wp_cache_delete( $entry, self::$wp_cache_group ); } wp_cache_delete( self::$wp_key_list, self::$wp_key_list ); } } static function get_stat( $recheck = false ) { $entries = wp_cache_get( self::$wp_key_list, self::$wp_key_list ); if ( $recheck && $entries ) { foreach ( $entries as $key => $exp ) { if ( ! $element = wp_cache_get( $key, self::$wp_cache_group ) ) { unset( $entries[ $key ] ); } } wp_cache_set( self::$wp_key_list, $entries, self::$wp_key_list ); } if ( empty( $entries ) ) { $entries = array(); } return array( self::$stat, $entries ); } static function checker() { $sid = get_wp_cerber()->getRequestID(); $check = wp_cache_get( '__checker__', self::$wp_cache_group ); if ( ! $check || ! isset( $check['t'] ) || ! isset( $check['s'] ) ) { wp_cache_set( '__checker__', array( 't' => time(), 's' => $sid ), self::$wp_cache_group ); return 0; } if ( $check['s'] == $sid ) { return 0; } return $check['t']; } } function cerber_cache_set( $key, $value, $expire = 0 ) { return CRB_Cache::set( $key, $value, $expire ); } function cerber_cache_get( $key, $default = null ) { return CRB_Cache::get( $key, $default ); } function cerber_cache_delete( $key ) { CRB_Cache::delete( $key ); } function cerber_cache_enable() { global $cerber_use_cache; $cerber_use_cache = true; } function cerber_cache_disable() { global $cerber_use_cache; $cerber_use_cache = false; } function cerber_cache_is_enabled() { global $cerber_use_cache; return ! empty( $cerber_use_cache ); } function crb_q_cache_get( $sql, $table, $cache_only = false, $hash_fields = array( 'stamp', 'ip', 'session_id' ), $order_by = 0 ) { global $wp_cerber_q_cache; if ( is_string( $sql ) ) { $sql = array( array( $sql ) ); } $single = ( count( $sql ) == 1 ); $run = true; $cache_key = 'q_cache_' . sha1( implode( '|', array_column( $sql, 0 ) ) ); $cache = cerber_get_set( $cache_key, 0, false, true ); if ( $cache ) { $cache = json_decode( $cache ); if ( $cache->hash == crb_get_table_hash( $table, $hash_fields, $order_by ) ) { $wp_cerber_q_cache = true; $run = false; } } if ( $run && $cache_only ) { return false; } if ( ! $run ) { $results = $cache->results; } else { $new_cache = array(); $new_cache['hash'] = crb_get_table_hash( $table, $hash_fields, $order_by ); $results = array(); foreach ( $sql as $query ) { $results[] = cerber_db_get_results( $query[0], crb_array_get( $query, 1 ) ); } $new_cache['results'] = $results; $new_cache = json_encode( $new_cache, JSON_UNESCAPED_UNICODE ); cerber_update_set( $cache_key, $new_cache, 0, false, time() + 7200, true ); } if ( $single ) { return $results[0]; } return $results; } function crb_get_table_hash( $table, $hash_fields, $order_by ) { static $hashes; $fields = implode( ',', $hash_fields ); $key = sha1( $table . '|' . $fields . '|' . $order_by ); if ( ! isset( $hashes[ $key ] ) ) { if ( $data = cerber_db_get_row( 'SELECT ' . $fields . ' FROM ' . $table . ' ORDER BY ' . $hash_fields[ $order_by ] . ' DESC LIMIT 1' ) ) { $hashes[ $key ] = sha1( implode( '|', $data ) ); } else { $hashes[ $key ] = ''; } } return $hashes[ $key ]; } add_filter( 'update_plugins_downloads.wpcerber.com', 'cerber_check_for_update', 10, 4 ); function cerber_check_for_update( $update, $plugin_data, $plugin_file, $locales ) { if ( ! crb_get_settings( 'cerber_sw_repo' ) || ! $uri = crb_array_get( $plugin_data, 'UpdateURI' ) ) { return false; } $response = wp_remote_get( $uri ); $err = ''; if ( crb_is_wp_error( $response ) ) { $err = $response->get_error_message(); } if ( ! $body = crb_array_get( $response, 'body' ) ) { cerber_update_set( 'last_update_check', array( 'error' => $err, 'no_body' => 1, 'uri' => $uri ) ); return false; } $package_data = json_decode( $body, true ); $update = crb_array_get( $package_data, $plugin_file, $update ); if ( isset( $update['requires_wp'] ) ) { $update['requires'] = $update['requires_wp']; } $update['tested'] = cerber_get_wp_version(); $update['slug'] = 'wp-cerber'; if ( ! is_array( $locales ) ) { $locales = array(); } $available = $update['trans_bucket'] ?? array(); if ( ! is_array( $available ) ) { $available = array(); } $update['translations'] = crb_process_locales( $locales, $available ); unset( $update['trans_bucket'] ); cerber_update_set( 'last_update_check', array( 'success' => time(), 'uri' => $uri ) ); return $update; } function crb_process_locales( array $wp_locales, array $available ): array { if ( ! $wp_locales || ! $available ) { return array(); } if ( $locale = crb_get_settings( 'admin_locale' ) ) { $wp_locales[] = $locale; } $wp_locales = array_filter( $wp_locales, function ( $value ) { return strpos( $value, 'en_' ) !== 0; }); if ( ! $wp_locales ) { return array(); } $translations = array(); foreach ( $wp_locales as $locale ) { if ( $hash = $available[ $locale ] ?? false ) { $mo_file = WP_LANG_DIR . '\/plugins\/wp-cerber-' . $locale . '.mo'; if ( file_exists( $mo_file ) && $hash == sha1_file( $mo_file ) ) { continue; } } $translations[] = array( 'language' => $locale, 'package' => 'https:\/\/downloads.wpcerber.com\/translations\/wp-cerber\/' . $locale . '.zip', 'autoupdate' => 1, 'version' => CERBER_VER, ); } return $translations; } add_filter( 'auto_update_plugin', function ( $update, $item ) { if ( crb_get_settings( 'cerber_sw_auto' ) && $item->plugin == CERBER_PLUGIN_ID ) { return true; } return $update; }, PHP_INT_MAX, 2 ); function crb_get_remote_json( string $url ) { if ( 0 !== strpos( $url, 'https:\/\/' ) ) { return new WP_Error( 'unsafe_url', 'Invalid URL. It must begin with https:\/\/' ); } if ( defined( 'CERBER_NETWORK_DEBUG' ) && CERBER_NETWORK_DEBUG ) { cerber_diag_log( 'Initiating downloading JSON payload from ' . $url ); } $response = wp_remote_get( $url ); if ( crb_is_wp_error( $response ) ) { return $response; } if ( ! $body = wp_remote_retrieve_body( $response ) ) { return new WP_Error( 'no_content', 'The response body is empty' ); } $decoded = json_decode( $body, true ); if ( ! $decoded || JSON_ERROR_NONE != json_last_error() ) { return new WP_Error( 'json_not_found', 'Unable to decode JSON payload. ' . json_last_error_msg() ); } if ( defined( 'CERBER_NETWORK_DEBUG' ) && CERBER_NETWORK_DEBUG ) { cerber_diag_log( 'Loaded and decoded successfully, size: ' . strlen( $body ) ); } return $decoded; } function crb_get_last_user_login( $user_id ) { $user_set = cerber_get_set( CRB_USER_SET, $user_id ); if ( $user_set['last_login']['cn'] ?? false ) { return $user_set['last_login']; } if ( ! $row = cerber_get_last_login( $user_id ) ) { return false; } $user_set['last_login']['ts'] = $row->stamp; $user_set['last_login']['cn'] = $row->country ?: lab_get_country( $row->ip, false ); cerber_update_set( CRB_USER_SET, $user_set, $user_id ); return $user_set['last_login']; } function crb_configure_curl( $curl, $params, $setting = 'main_use_proxy' ) { global $wp_cerber_relay; if ( crb_get_settings( $setting ) ) { if ( defined( 'WP_PROXY_HOST' ) && defined( 'WP_PROXY_PORT' ) ) { $params[ CURLOPT_PROXYTYPE ] = defined( 'CERBER_PROXY_TYPE' ) ? CERBER_PROXY_TYPE : CURLPROXY_HTTP; $params[ CURLOPT_PROXY ] = WP_PROXY_HOST; $params[ CURLOPT_PROXYPORT ] = WP_PROXY_PORT; if ( defined( 'WP_PROXY_USERNAME' ) && defined( 'WP_PROXY_PASSWORD' ) ) { $params[ CURLOPT_PROXYAUTH ] = CURLAUTH_ANY; $params[ CURLOPT_PROXYUSERPWD ] = WP_PROXY_USERNAME . ':' . WP_PROXY_PASSWORD; } } $wp_cerber_relay = 1; } else { $wp_cerber_relay = 0; } try { if ( ! curl_setopt_array( $curl, $params ) ) { throw new Exception( 'Failed to set cURL options.' ); } } catch ( Throwable $e ) { if ( defined( 'CERBER_NETWORK_DEBUG' ) && CERBER_NETWORK_DEBUG ) { cerber_error_log( $e->getMessage() . '. Error thrown on line ' . $e->getLine() . ' in file ' . $e->getFile() . '. cURL options provided: ' . print_r( $params, 1 ), 'NETWORK' ); } return false; } return true; } function crb_get_plugin_slug( string $path ): string { if ( strpos( $path, WP_PLUGIN_DIR ) === 0 ) { $path = str_replace( WP_PLUGIN_DIR, '', $path ); $path = ltrim( $path, '\/' ); } if ( strpos( $path, '\/' ) ) { $plugin_slug = dirname( $path ); } elseif ( $path === 'hello.php' ) { $plugin_slug = 'hello-dolly'; } else { $plugin_slug = preg_replace( '\/\\.php$\/', '', $path ); } return $plugin_slug; } function crb_load_dependencies( $func, $load_cons = false ) { if ( function_exists( $func ) ) { return false; } if ( $load_cons ) { cerber_load_wp_constants(); } $ret = true; switch ( $func ) { case 'wp_mail': case 'wp_create_nonce': case 'is_user_logged_in': case 'wp_get_current_user': require_once( ABSPATH . WPINC . '\/pluggable.php' ); break; case 'wp_is_auto_update_enabled_for_type': require_once( ABSPATH . 'wp-admin\/includes\/update.php' ); break; default: $ret = false; } return $ret; } add_filter( 'lang_dir_for_domain', 'crb_loc_exception_handler', 10, 3 ); function crb_loc_exception_handler( $path, $domain, $locale ) { if ( $domain == 'wp-cerber' && ( ! doing_action( 'after_setup_theme' ) && ! did_action( 'after_setup_theme' ) ) ) { $path = ''; } return $path; } function crb_load_localization() { if ( is_admin() || nexus_is_valid_request() ) { $locale = crb_get_admin_locale(); if ( $locale == 'en_US' ) { add_filter( 'override_load_textdomain', function ( $val, $domain, $mofile ) { if ( $domain == 'wp-cerber' ) { $val = true; } return $val; }, 100, 3 ); } else { add_filter( 'load_textdomain_mofile', function ( $mofile, $domain ) { if ( $domain != 'wp-cerber' ) { return $mofile; } $locale = crb_get_admin_locale(); $new_mofile = dirname( $mofile ) . '\/' . $domain . '-' . $locale . '.mo'; return file_exists( $new_mofile ) ? $new_mofile : $mofile; }, PHP_INT_MAX, 2 ); } } load_plugin_textdomain( 'wp-cerber', false, 'wp-cerber\/languages' ); } class CRB_Globals { static $session_status; static $act_status; static $do_not_log = array(); static $reset_pwd_msg = ''; static $reset_pwd_denied = false; static $retrieve_password = false; static $login_form_errors = array(); static $user_id; static $req_status = 0; private static $assets_url = ''; static $ajax_loader = ''; static $logged = array(); static $blocked; static $db_requests = array(); static $db_errors = array(); static $bot_status = 0; static $htaccess_failure = array(); static $php_errors = array(); static $prev_handler = null; private static $by_settings = array(); static $admin_footer_html = ''; static $redirect_url = ''; static $doing_upgrade; static function admin_init() { } static function get_errors() { if ( ! is_array( self::$php_errors ) ) { self::$php_errors = array(); } if ( $last_err = error_get_last() ) { $add = true; if ( self::$php_errors) { foreach ( self::$php_errors as $err ) { if ( $last_err['type'] == $err[0] && $last_err['line'] == $err[3] && $last_err['file'] == $err[2] ) { $add = false; break; } } } if ( $add ) { self::$php_errors[] = array( $last_err['type'], $last_err['message'], $last_err['file'], $last_err['line'] ); } } return self::$php_errors; } static function has_errors( $code ) { if ( ! self::get_errors() ) { return false; } $error_codes = array_column( self::$php_errors, 0 ); if ( is_array( $code ) ) { return (bool) array_intersect( $error_codes, $code ); } return in_array( $code, $error_codes ); } static function assets_url( $res = '', $echo = false ) { if ( ! self::$assets_url ) { self::$assets_url = crb_escape( cerber_plugin_dir_url() ) . 'assets\/'; } $ret = self::$assets_url; if ( $res ) { $ret .= $res; } if ( $echo ) { echo $ret; } return $ret; } static function set_assets_url( $url ) { self::$assets_url = crb_escape( $url ); } static function set_bot_status( $val ) { self::$bot_status = (int) $val; CRB_Globals::set_act_status( $val ); } static function set_act_status_if( $val, $setting_id = '' ) { if ( ! self::$act_status ) { self::$act_status = $val; if ( $setting_id ) { self::$by_settings[] = $setting_id; } } } static function set_act_status( $val, $setting_id = '' ) { self::$act_status = $val; if ( $setting_id ) { self::$by_settings[] = $setting_id; } } static function set_ctrl_setting( $setting_id ) { self::$by_settings[] = $setting_id; } static function get_ctrl_settings() { return self::$by_settings; } static function to_admin_footer( $html ) { self::$admin_footer_html .= (string)"},"66390dbd5cd82efb7db9cb3eeef2deed":{"file":"\/breather.com.ua\/wp-content\/plugins\/wp-cerber\/cerber-settings.php","exploit":"eval_strrev","line":52,"match":"lave"},"de50d43cdd08533cff63666a88fa90be":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/cerber-scanner.php","exploit":"f9dc0a55","line":2933,"match":"'base64_decode'"},"fc4589583b09e4e3d49bb60a5431242b":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/nexus\/cerber-nexus-client.php","exploit":"eval_strrev","line":432,"match":"lave"},"f092c82ea24b1e4abaed0535c036ef54":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/nexus\/cerber-nexus.php","exploit":"eval_strrev","line":64,"match":"lave"},"2b94fcf407ab789b7d7163e5a4ab0245":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/nexus\/cerber-nexus-list.php","exploit":"eval_strrev","line":120,"match":"lave"},"7fd9701247a01ae710f0f4c7f44804ca":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/nexus\/cerber-nexus-manager.php","exploit":"eval_strrev","line":454,"match":"lave"},"cbab5595ef227fe92a7be0a28bfc14a5":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/cerber-load.php","exploit":"11413268","line":934,"match":"exploit"},"6778cf211778b1985aa79d819bf7054c":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/cerber-load.php","exploit":"eval_strrev","line":6989,"match":"lave"},"0896ed0ebbc1ec8d9dc55d531306361f":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/cerber-load.php","exploit":"syslog","line":null,"match":"syslog( LOG_NOTICE, 'Authentication failure for ' . $user_login . ' from ' . $ip ); @closelog(); } } function cerber_get_subnet_ipv4( $ip ) { return preg_replace( '\/\\.\\d{1,3}$\/', '.*', $ip ); } function cerber_is_ip_or_net( $ip ) { if ( filter_var( $ip, FILTER_VALIDATE_IP ) ) { return true; } $ip = str_replace( '*', '0', $ip ); if ( filter_var( $ip, FILTER_VALIDATE_IP ) ) { return true; } if ( strpos( $ip, '\/' ) ) { $cidr = explode( '\/', $ip ); $net = $cidr[0]; $mask = absint( $cidr[1] ); $dots = substr_count( $net, '.' ); if ( $dots < 3 ) { if ( $dots == 1 ) { $net .= '.0.0'; } elseif ( $dots == 2 ) { $net .= '.0'; } } if ( ! cerber_is_ipv4( $net ) ) { return false; } if ( ! is_numeric( $mask ) ) { return false; } return true; } return false; } function cerber_parse_ip_range( $string ) { if ( cerber_is_ip_or_net( $string ) ) { return $string; } $explode = explode( '-', $string, 2 ); if ( ! is_array( $explode ) || 2 != count( $explode ) ) { return false; } $begin_ip = filter_var( trim( $explode[0] ), FILTER_VALIDATE_IP ); $end_ip = filter_var( trim( $explode[1] ), FILTER_VALIDATE_IP ); if ( ! $begin_ip || ! $end_ip ) { return false; } if ( cerber_is_ipv4( $begin_ip ) && cerber_is_ipv4( $end_ip ) ) { $begin = ip2long( $begin_ip ); $end = ip2long( $end_ip ); if ( $begin > $end ) { return false; } $ver6 = 0; $v6range = ''; } elseif ( cerber_is_ipv6( $begin_ip ) && cerber_is_ipv6( $end_ip ) ) { $ver6 = 1; list( $begin, $end, $v6range ) = crb_ipv6_prepare( $begin_ip, $end_ip ); if ( $begin > $end ) { return false; } list( $begin1, $begin2, $end1, $end2 ) = explode( '#', $v6range, 4 ); if ( crb_compare_numbers( $begin1, $begin2, $end1, $end2 ) ) { return false; } } else { return false; } return array( 'range' => $begin_ip . ' - ' . $end_ip, 'begin_ip' => $begin_ip, 'end_ip' => $end_ip, 'begin' => $begin, 'end' => $end, 'IPV6' => $ver6, 'IPV6range' => $v6range ); } function cerber_wildcard2range( $wildcard ) { if ( false === strpos( $wildcard, '*' ) ) { return false; } if ( ! strpos( $wildcard, ':' ) ) { $begin = str_replace( '*', '0', $wildcard ); $end = str_replace( '*', '255', $wildcard ); if ( ! cerber_is_ipv4( $begin ) || ! cerber_is_ipv4( $end ) ) { return false; } } else { $begin = str_replace( ':*', ':0000', $wildcard ); $end = str_replace( ':*', ':ffff', $wildcard ); if ( ! cerber_is_ipv6( $begin ) || ! cerber_is_ipv6( $end ) ) { return false; } } return cerber_parse_ip_range( $begin . ' - ' . $end ); } function cerber_cidr2range( $cidr = '' ) { if ( ! strpos( $cidr, '\/' ) ) { return false; } $cidr = explode( '\/', $cidr ); $net = $cidr[0]; $mask = absint( $cidr[1] ); $dots = substr_count( $net, '.' ); if ( $dots < 3 ) { if ( $dots == 1 ) { $net .= '.0.0'; } elseif ( $dots == 2 ) { $net .= '.0'; } } if ( ! cerber_is_ipv4( $net ) ) { return false; } if ( ! is_numeric( $mask ) ) { return false; } if ( $mask == 32 ) { $begin_ip = $net; $end_ip = $net; } else { $begin_ip = long2ip( ( ip2long( $net ) ) & ( ( - 1 << ( 32 - (int) $mask ) ) ) ); $end_ip = long2ip( ( ip2long( $net ) ) + pow( 2, ( 32 - (int) $mask ) ) - 1 ); } return cerber_parse_ip_range( $begin_ip . ' - ' . $end_ip ); } function cerber_any2range( $string ) { if ( ! $string || ! is_string( $string ) ) { return false; } $string = trim( $string ); if ( filter_var( $string, FILTER_VALIDATE_IP ) ) { return $string; } $ret = cerber_wildcard2range( $string ); if ( ! $ret ) { $ret = cerber_cidr2range( $string ); } if ( ! $ret ) { $ret = crb_ipv6_cidr2range( $string ); } if ( ! $ret ) { $ret = cerber_parse_ip_range( $string ); } return $ret; } function crb_ipv6_cidr2range( $cidr ) { if ( ! strpos( $cidr, '\/' ) ) { return false; } list( $net, $mask ) = explode( '\/', $cidr ); $mask = (int) $mask; if ( ! cerber_is_ipv6( $net ) || ! is_integer( $mask ) || $mask < 0 || $mask > 128 ) { return false; } $begin_hex = (string) bin2hex( inet_pton( $net ) ); $begin_ip = cerber_ipv6_expand( $net ); $exceptions = array( 65 => '7fffffffffffffff', 1 => '7fffffffffffffffffffffffffffffff', 0 => 'ffffffffffffffffffffffffffffffff' ); if ( isset( $exceptions[ $mask ] ) ) { $add = $exceptions[ $mask ]; } elseif ( $mask >= 66 ) { $add = (string) dechex( pow( 2, ( 128 - $mask ) ) - 1 ); } else { $add = (string) dechex( pow( 2, ( 128 - $mask - 64 ) ) - 1 ) . 'ffffffffffffffff'; } $end_hex = str_pad( crb_summ_hex( $begin_hex, $add ), 32, '0', STR_PAD_LEFT ); $end_ip = implode( ':', str_split( $end_hex, 4 ) ); return cerber_parse_ip_range( $begin_ip . ' - ' . $end_ip ); } function crb_summ_hex( $hex1, $hex2) { $hex1 = ltrim( $hex1, '0' ); $hex2 = ltrim( $hex2, '0' ); if ( strlen( $hex1 ) > strlen( $hex2 ) ) { $h1 = $hex1; $h2 = $hex2; } else { $h1 = $hex2; $h2 = $hex1; } $h1 = str_split( (string) $h1 ); $h2 = str_split( (string) $h2 ); $h1 = array_reverse( array_map( 'hexdec', $h1 ) ); $h2 = array_reverse( array_map( 'hexdec', $h2 ) ); $max1 = count( $h1 ) - 1; $max2 = count( $h2 ) - 1; $i = 0; $r = 0; $finish = false; while ( $i <= $max1 && ! $finish ) { if ( $i <= $max2 ) { $h1[ $i ] = $h1[ $i ] + $h2[ $i ] + $r; } else { if ( ! $r ) { $finish = true; } $h1[ $i ] += $r; } if ( $h1[ $i ] >= 16 ) { $r = 1; $h1[ $i ] -= 16; } else { $r = 0; } $i ++; } if ( $r ) { $h1[] = 1; } $h1 = array_reverse( array_map( 'dechex', $h1 ) ); return implode( '', $h1 ); } function cerber_is_myip( $ip ) { if ( ! is_string( $ip ) ) { return false; } $remote_ip = cerber_get_remote_ip(); if ( $ip == $remote_ip ) { return true; } if ( $ip == cerber_get_subnet_ipv4( $remote_ip ) ) { return true; } return false; } function cerber_is_ip_in_range( $range, $ip ) { if ( ! is_array( $range ) ) { return false; } if ( $range['IPV6'] ) { if ( cerber_is_ipv4( $ip ) ) { return false; } return crb_ipv6_is_in_range( $ip, $range ); } if ( cerber_is_ipv6( $ip ) ) { return false; } $long = ip2long( $ip ); if ( $range['begin'] <= $long && $long <= $range['end'] ) { return true; } return false; } function cerber_404_page( $simple = false ) { global $wp_query; header_remove( 'Link' ); $method = crb_get_settings( 'page404' ); if ( $method == 2 && $url = crb_get_settings( 'page404_redirect' ) ) { if ( ! headers_sent() ) { CRB_Globals::$redirect_url = $url; header( 'Location: ' . $url, true, 302 ); exit; } } elseif ( ! $simple ) { if ( function_exists( 'status_header' ) ) { status_header( '404' ); } if ( isset( $wp_query ) && is_object( $wp_query ) ) { $wp_query->set_404(); } if ( 0 == $method ) { $template = null; remove_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' ); if ( function_exists( 'get_404_template' ) ) { $template = get_404_template(); } if ( function_exists( 'apply_filters' ) ) { $template = apply_filters( 'cerber_404_template', $template ); } if ( $template && @file_exists( $template ) ) { include( $template ); exit; } } } header( 'HTTP\/1.0 404 Not Found', true, 404 ); echo '<html><head><title>404 Not Found<\/title><\/head><body><h1>Not Found<\/h1><p>The requested URL ' . esc_url( $_SERVER['REQUEST_URI'] ) . ' was not found on this server.<\/p><\/body><\/html>'; cerber_traffic_log(); exit; } function cerber_forbidden_page() { $wp_cerber = get_wp_cerber(); $sid = strtoupper( $wp_cerber->getRequestID() ); status_header( '403' ); header( 'HTTP\/1.0 403 Access Forbidden', true, 403 ); ?>\r\n    <!DOCTYPE html>\r\n    <html style=\"height: 100%;\">\r\n    <head>\r\n        <meta charset=\"UTF-8\">\r\n        <title>403 Access Forbidden<\/title>\r\n        <style>\r\n            @media screen and (max-width: 800px) {\r\n                body > div > div > div div {\r\n                    display: block !important;\r\n                    padding-right: 0 !important;\r\n                }\r\n\r\n                body {\r\n                    text-align: center !important;\r\n                }\r\n            }\r\n        <\/style>\r\n    <\/head>\r\n    <body style=\"height: 90%;\">\r\n    <div style=\"display: flex; align-items: center; justify-content: center; height: 90%;\">\r\n        <div style=\"background-color: #eee; width: 70%; border: solid 3px #ddd; padding: 1.5em 3em 3em 3em; font-family: Arial, Helvetica, sans-serif;\">\r\n            <div style=\"display: table-row;\">\r\n                <div style=\"display: table-cell; font-size: 150px; color: red; vertical-align: top; padding-right: 50px;\">\r\n                    &#9995;\r\n                <\/div>\r\n                <div style=\"display: table-cell; vertical-align: top;\">\r\n                    <h1 style=\"margin-top: 0;\"><?php _e( \"We're sorry, you are not allowed to proceed\", 'wp-cerber' ); ?><\/h1>\r\n                    <p><?php _e( 'Your request looks suspiciously similar to automated requests from spam posting software or it has been denied by a security policy configured by the website administrator.', 'wp-cerber' ); ?><\/p>\r\n                    <p><?php _e( 'If you believe you should be able to perform this request, please let us know.', 'wp-cerber' ); ?><\/p>\r\n                    <p style=\"margin-top: 2em;\">\r\n                    <pre style=\"color: #777\">RID: <?php echo $sid; ?><\/pre>\r\n                    <\/p>\r\n                    <p style=\"margin-top: 2em; font-size: 80%\">\r\n                        Know more: <a href=\"https:\/\/wpcerber.com\/rid-request-not-allowed-wordpress\/\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation<\/a>\r\n                    <\/p>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n    <\/body>\r\n    <\/html>\r\n\t<?php\r\n cerber_traffic_log(); exit; } function cerber_enable_citadel() { if ( ! crb_get_settings( 'citadel_on' ) ) { return; } if ( cerber_is_citadel() ) { return; } cerber_update_set( 'cerber_citadel', 1, null, false, time() + crb_get_settings( 'ciduration' ) * 60 ); cerber_log( 12 ); if ( crb_get_settings( 'cinotify' ) ) { cerber_send_message( 'citadel_mode' ); } } function cerber_disable_citadel() { cerber_delete_set( 'cerber_citadel' ); } function cerber_is_citadel() { return (bool) cerber_get_set( 'cerber_citadel', null, false ); } class CRB_Messaging { private $smpt_enabled = false; private $no_smtp = false; private $mailer; private $email_args = array(); private $error = false; public function send_message( $type, $msg_parts = array(), $channels = array(), $ignore = false, $args = array() ) { $type = $type ?: 'generic'; $sb = $msg_parts['subj'] ?? ''; $msg = $msg_parts['text'] ?? ''; $msg_masked = $msg_parts['text_masked'] ?? ''; $more = $msg_parts['more'] ?? ''; $ip = $msg_parts['ip'] ?? ''; $channels = array_merge( CRB_CHANNELS, $channels ); if ( ! array_filter( $channels ) ) { return false; } if ( ! $ignore && ! is_admin() && in_array( $type, array( 'lockout', 'send_alert' ) ) ) { $channels = $this->check_limits( $channels ); if ( ! array_filter( $channels ) ) { return false; } } $html_mode = false; $blogname = crb_get_blogname_decoded(); if ( ! in_array( $type, array( '2fa', 'new_version' ) ) ) { $subj = '[' . $blogname . '] WP Cerber: ' . $sb; } else { $subj = '[' . $blogname . '] ' . $sb; } $body = ''; $body_masked = ''; if ( is_array( $msg ) ) { $msg = implode( \"\\n\\n\", $msg ) . \"\\n\\n\"; } if ( is_array( $msg_masked ) ) { $msg_masked = implode( \"\\n\\n\", $msg_masked ) . \"\\n\\n\"; } $last = null; switch ( $type ) { case 'citadel_mode': $max = cerber_db_get_var( 'SELECT MAX(stamp) FROM ' . CERBER_LOG_TABLE . ' WHERE  activity = ' . CRB_EV_LFL ); if ( $max ) { $last_date = cerber_date( $max, false ); $last = cerber_db_get_row( 'SELECT * FROM ' . CERBER_LOG_TABLE . ' WHERE stamp = ' . $max . ' AND activity = ' . CRB_EV_LFL, MYSQL_FETCH_OBJECT ); } if ( ! $last ) { $last = new stdClass(); $last->ip = CERBER_NO_REMOTE_IP; $last->user_login = 'test'; } $subj .= __( 'Citadel mode is active', 'wp-cerber' ); $body = sprintf( __( 'Citadel mode has been activated after %d failed login attempts in %d minutes.', 'wp-cerber' ), crb_get_settings( 'cilimit' ), crb_get_settings( 'ciperiod' ) ) . \"\\n\\n\"; $body .= sprintf( __( 'Last failed attempt was at %s from IP %s using username: %s.', 'wp-cerber' ), $last_date, $last->ip, $last->user_login ) . \"\\n\\n\"; $more = __( 'View activity in the Dashboard', 'wp-cerber' ) . ': ' . cerber_admin_link( 'activity', array(), false, false ) . \"\\n\\n\"; break; case 'lockout': $max = cerber_db_get_var( 'SELECT MAX(stamp) FROM ' . CERBER_LOG_TABLE . ' WHERE  activity IN (10,11)' ); if ( $max ) { $last_date = cerber_date( $max, false ); $last = cerber_db_get_row( 'SELECT * FROM ' . CERBER_LOG_TABLE . ' WHERE stamp = ' . $max . ' AND activity IN (10,11)', MYSQL_FETCH_OBJECT ); } else { $last_date = ''; $last = new stdClass(); $last->ip = CERBER_NO_REMOTE_IP; $last->user_login = 'test'; } $active = cerber_blocked_num(); if ( $last->ip && ( $block = cerber_get_block( $last->ip ) ) ) { $reason = $block->reason; } else { $reason = __( 'unspecified', 'wp-cerber' ); } $subj .= __( 'Number of lockouts is increasing', 'wp-cerber' ) . ' (' . $active . ')'; $body = __( 'Number of active lockouts at the moment:', 'wp-cerber' ) . ' ' . $active . \"\\n\\n\"; if ( $last_date ) { $body .= sprintf( __( 'Last security action: IP address %s was locked out at %s', 'wp-cerber' ), $last->ip . ' (' . @gethostbyaddr( $last->ip ) . ')', $last_date ) . \"\\n\\n\"; $body .= __( 'Reason:', 'wp-cerber' ) . ' '.strip_tags( $reason ) . \"\\n\\n\"; } $more = __( 'View activity for this IP:', 'wp-cerber' ) . ' ' . cerber_admin_link( 'activity', array(), false, false ) . '&filter_ip=' . $last->ip . \"\\n\\n\"; $more .= __( 'View all lockouts:', 'wp-cerber' ) . ' ' . cerber_admin_link( 'lockouts', array(), false, false ) . \"\\n\\n\"; $more .= __( 'Learn more about advanced alerting in WP Cerber:', 'wp-cerber' ) . ' ' . 'https:\/\/wpcerber.com\/wordpress-notifications-made-easy\/'; break; case 'new_version': $body = $msg . \"\\n\\n\"; $more = __( 'Website', 'wp-cerber' ) . ': ' . $blogname; break; case 'shutdown': $d = __( 'The WP Cerber Security plugin has been deactivated', 'wp-cerber' ); $subj = '[' . $blogname . '] ' . $d; $body .= \"\\n\" . $d . \"\\n\\n\"; if ( ! is_user_logged_in() ) { $u = __( 'Unknown', 'wp-cerber' ); } else { $user = wp_get_current_user(); $u = $user->display_name; } $body .= __( 'Website', 'wp-cerber' ) . ': ' . $blogname . \"\\n\"; $more = __( 'By the user', 'wp-cerber' ) . ': ' . $u . \"\\n\"; $more .= __( 'From the IP address', 'wp-cerber' ) . ': ' . cerber_get_remote_ip() . \"\\n\"; $whois = cerber_ip_whois_info( cerber_get_remote_ip() ); if ( ! empty( $whois['data']['country'] ) ) { $more .= __( 'From the country', 'wp-cerber' ) . ': ' . cerber_country_name( $whois['data']['country'] ); } break; case 'activated': $subj = '[' . $blogname . '] ' . __( 'The WP Cerber Security plugin is now active', 'wp-cerber' ); $body = \"\\n\" . __( 'WP Cerber is now active and has started protecting your site', 'wp-cerber' ) . \"\\n\\n\"; $body .= __( 'Getting Started Guide', 'wp-cerber' ) . \"\\n\\n\"; $body .= 'https:\/\/wpcerber.com\/getting-started\/' . \"\\n\\n\"; $body .= 'Is your website under Cloudflare? You have to enable a crucial WP Cerber setting.' . \"\\n\\n\"; $body .= 'https:\/\/wpcerber.com\/cloudflare-and-wordpress-cerber\/' . \"\\n\\n\"; $body .= 'Be in touch with the developer.' . \"\\n\\n\"; $body .= 'Follow Cerber on X: https:\/\/twitter.com\/wpcerber' . \"\\n\\n\"; $body .= \"Subscribe to Cerber's newsletter: https:\/\/wpcerber.com\/subscribe-newsletter\/\" . \"\\n\\n\"; break; case 'newlurl': $subj .= __( 'New Custom login URL', 'wp-cerber' ); $body .= $msg; break; case 'send_alert': $body = __( 'A new activity has occurred', 'wp-cerber' ) . \"\\n\\n\"; $body_masked = $body; $body .= $msg; $body_masked .= $msg_masked; break; case 'report': list ( $title, $body ) = cerber_generate_email_report( $args ); $subj .= $title; $link = cerber_admin_link( 'notifications', array(), false, false ); $body .= '<br\/>' . __( 'To change reporting settings visit', 'wp-cerber' ) . ' <a href=\"' . $link . '\">' . $link . '<\/a>'; $body .= $msg; $html_mode = true; break; case 'scan': $subj .= __( 'Scanner Report', 'wp-cerber' ); $body = $msg; $link = cerber_admin_link( 'scan_main', array(), false, false ); $body .= '<p>' . __( 'To view full report, navigate to:', 'wp-cerber' ) . ' <a href=\"' . $link . '\">' . $link . '<\/a><\/p>'; $link = cerber_admin_link( 'scan_schedule', array(), false, false ); $body .= '<br\/>' . __( 'To modify your reporting settings, navigate to:', 'wp-cerber' ) . ' <a href=\"' . $link . '\">' . $link . '<\/a>'; $html_mode = true; break; case 'generic': case '2fa': default: $body = $msg; break; } $to_list = array(); $to = ''; if ( $channels['email'] ) { $to_list = cerber_get_email( $type, $args ); $to = implode( ', ', $to_list ); } $body_filtered = apply_filters( 'cerber_notify_body', $body, array( 'type' => $type, 'IP' => $ip, 'to' => $to, 'subject' => $subj ) ); if ( $body_filtered && is_string( $body_filtered ) ) { $body = $body_filtered; } if ( ! $body ) { return false; } $footer = ''; $mf = crb_get_settings( 'email_format' ); if ( ( 1 > $mf ) && ! in_array( $type, array( 'shutdown', 'generic', '2fa' ) ) && $lolink = cerber_get_custom_login_url() ) { $lourl = urldecode( $lolink ); if ( $html_mode ) { $lourl = '<a href=\"' . $lolink . '\">' . $lourl . '<\/a>'; } $footer .= \"\\n\\n\" . __( 'Your login page:', 'wp-cerber' ) . ' ' . $lourl; } if ( ( 1 > $mf ) && $type == 'report' && $date = lab_lab( 1 ) ) { $footer .= \"\\n\\n\" . __( 'Your license is valid until', 'wp-cerber' ) . ' ' . $date; } if ( $type != '2fa' ) { $footer .= \"\\n\\n\\n\" . __( 'This message was created by', 'wp-cerber' ) . ' WP Cerber Security ' . ( lab_lab() ? 'Professional ' : '' ) . ( 1 > $mf ? CERBER_VER : '' ); $footer .= \"\\n\" . __( 'Date:', 'wp-cerber' ) . ' ' . cerber_date( time(), false ); $footer .= \"\\n\" . 'https:\/\/wpcerber.com'; } $results = array(); $recipients = array(); $success = false; $go = 'pushbullet'; if ( $channels[ $go ] && ! $html_mode ) { $body_go = ( $type == 'send_alert' && crb_get_settings( 'pb_mask' ) ) ? $body_masked : $body; $res = cerber_pb_send( $subj, $body_go, $more, $footer ); if ( $res && ! crb_is_wp_error( $res ) ) { $results[ $go ] = true; $recipients[ $go ] = cerber_pb_get_active(); $success = true; } } $go = 'email'; if ( $channels[ $go ] ) { $body_go = ( $type == 'send_alert' && crb_get_settings( 'email_mask' ) ) ? $body_masked : $body; if ( $results[ $go ] = $this->send_email( $type, $html_mode, $to_list, $subj, $body_go, $more, $footer, $ip ) ) { $recipients[ $go ] = $to; $success = true; } } if ( ! $success ) { return false; } $sent = cerber_get_set( '_cerber_last_send' ); if ( ! is_array( $sent ) ) { $sent = array(); } foreach ( $results as $channel_id => $result ) { $sent[ $channel_id ] = ( $result ) ? time() : 0; } cerber_update_set( '_cerber_last_send', $sent ); return $recipients; } private function send_email( $type, $html_mode, $to_list, $subj, $body, $more, $footer, $ip ) { if ( function_exists( 'wp_mail' ) ) { return $this->go_send_email( $type, $html_mode, $to_list, $subj, $body, $more, $footer, $ip ); } $this->email_args[] = func_get_args(); add_action( 'plugins_loaded', array( $this, 'launch_send_email' ) ); register_shutdown_function( [ $this, 'launch_send_email' ] ); return true; } public function launch_send_email() { if ( ! $this->email_args ) { return; } foreach ( $this->email_args as $item ) { $this->go_send_email( ...$item ); } $this->email_args = array(); } private function go_send_email( $type, $html_mode, $to_list, $subj, $body, $more, $footer, $ip ) { $this->error = false; add_action( 'wp_mail_failed', array( $this, 'process_email_errors' ) ); if ( $html_mode ) { add_filter( 'wp_mail_content_type', 'cerber_enable_html' ); $footer = str_replace( \"\\n\", '<br\/>', $footer ); } if ( crb_get_settings( 'email_format' ) < 2 ) { $body .= $more; } $this->enable_smtp(); $result = false; $to = implode( ', ', $to_list ); if ( $to_list && $subj && $body ) { $lang = crb_get_bloginfo( 'language' ); if ( $type == 'report') { $result = true; foreach ( $to_list as $email ) { $lastus = ''; if ( ( $user = get_user_by( 'email', $email ) ) && $last = crb_get_last_user_login( $user->ID ) ) { $last_ip = crb_get_settings( 'email_mask' ) ? crb_mask_ip( $last['ip'] ) : $last['ip']; $lastus = sprintf( __( 'Your last sign-in was at %s from the IP address %s', 'wp-cerber' ), cerber_date( $last['ts'], false ), $last_ip ); if ( $country = cerber_country_name( $last['cn'] ) ) { $lastus .= ' (' . $country . ')'; } if ( $html_mode ) { $lastus = '<br\/><br\/>' . $lastus; } else { $lastus = \"\\n\\n\" . $lastus; } } $body = '<html lang=\"' . $lang . '\">' . $body . $lastus . $footer . '<\/html>'; if ( ! $this->transmit_email( $email, $subj, $body ) ) { $result = false; } } } else { $result = true; $body = $body . $footer; if ( $html_mode ) { $body = '<html lang=\"' . $lang . '\">' . $body . '<\/html>'; } foreach ( $to_list as $email ) { if ( ! $this->transmit_email( $email, $subj, $body ) ) { $result = false; } } } } $this->disable_smtp(); remove_filter('wp_mail_content_type', 'cerber_enable_html'); remove_action( 'wp_mail_failed', array( $this, 'process_email_errors' ) ); $params = array( 'type' => $type, 'IP' => $ip, 'to' => $to, 'subject' => $subj ); if ( $result ) { do_action( 'cerber_notify_sent', $body, $params ); if ( ! $this->error ) { cerber_delete_set( 'last_email_error' ); } } else { do_action( 'cerber_notify_fail', $body, $params ); } return $result; } private function transmit_email( $email, $subj, $body ) { crb_load_dependencies( 'wp_mail' ); if ( ( ! $result = wp_mail( $email, $subj, $body ) ) && $this->smpt_enabled ) { $this->no_smtp = true; if ( ! $result = wp_mail( $email, $subj, $body ) ) { $this->no_smtp = false; } } return $result; } public function set_smtp_credentials( $pm ) { if ( ! lab_lab() || $this->no_smtp ) { return; } $config = crb_get_settings(); $pm->isSMTP(); $pm->SMTPAuth = true; $pm->Timeout = 5; $pm->Host = $config['smtp_host']; $pm->Port = $config['smtp_port']; $pm->Username = $config['smtp_user']; $pm->Password = $config['smtp_pwd']; $pm->From = ( $config['smtp_from'] ) ?: $config['smtp_user']; if ( $config['smtp_from_name'] ) { $pm->FromName = $config['smtp_from_name']; } if ( $config['smtp_encr'] ) { $pm->SMTPSecure = $config['smtp_encr']; } $this->save_mailer( array( &$pm ) ); } private function enable_smtp() { if ( ! $this->smpt_enabled = crb_get_settings( 'use_smtp' ) ) { return; } add_action( 'phpmailer_init', array( $this, 'set_smtp_credentials' ) ); } private function disable_smtp() { if ( ! $this->smpt_enabled ) { return; } remove_action( 'phpmailer_init', array( $this, 'set_smtp_credentials' ) ); if ( is_admin() && crb_get_query_params( 'cerber_admin_do' ) ) { $mailer = $this->mailer; if ( ! ( $mailer instanceof PHPMailer\\PHPMailer\\PHPMailer ) || $mailer->Host != crb_get_settings( 'smtp_host' ) || $mailer->Port != crb_get_settings( 'smtp_port' ) || $mailer->Username != crb_get_settings( 'smtp_user' ) ) { cerber_admin_notice( \"Warning: The WP Cerber SMTP settings were not used while sending email. They can be altered by another plugin.\" ); $alien = true; } else { $alien = false; } if ( $alien && $mailer->Host ) { cerber_admin_notice( 'Warning: The email was sent using the host ' . $mailer->Host . ' and the user ' . $mailer->Username ); } } } private function save_mailer( $pm = null ) { if ( isset( $pm[0] ) ) { $this->mailer = $pm[0]; } return $this->mailer; } public function process_email_errors( $error ) { $this->error = true; $mailer_data = $error->get_error_data(); if ( is_admin() && crb_get_query_params( 'cerber_admin_do' ) ) { cerber_admin_notice( strip_tags( $error->get_error_message() ) . ' (' . ( $mailer_data['phpmailer_exception_code'] ?? '' ) . ')' ); } else { $to = $mailer_data['to'] ?? array(); if ( ! is_array( $to ) ) { $to = array( $to ); } $save = array( time(), cerber_get_remote_ip(), strip_tags( $error->get_error_message() ), $mailer_data['phpmailer_exception_code'] ?? '', isset( $this->mailer->Host ) ? $this->mailer->Host : '', isset( $this->mailer->Username ) ? $this->mailer->Username : '', $to, $mailer_data['subject'] ?? '', ); cerber_update_set( 'last_email_error', $save ); } } private function check_limits( $channels ) { static $ref = array( 'email' => 'emailrate', 'pushbullet' => 'pbrate' ); if ( ! lab_lab() ) { $ref ['pushbullet'] = 'emailrate'; } $limits = array_filter( array_intersect_key( crb_get_settings(), array_flip( $ref ) ) ); if ( ! $limits ) { return $channels; } $sent = cerber_get_set( '_cerber_last_send' ); if ( empty( $sent ) ) { return $channels; } foreach ( $ref as $channel_id => $key ) { $rate = absint( $limits[ $key ] ?? 0 ); if ( $rate && ( $sent[ $channel_id ] ?? 0 ) > ( time() - 3600 \/ $rate ) ) { $channels[ $channel_id ] = 0; } } return $channels; } } function cerber_send_message( $type, $msg_parts = array(), $channels = array(), $ignore = false, $args = array() ) { static $messenger; if ( ! $messenger ) { $messenger = new CRB_Messaging(); } return $messenger->send_message( $type, $msg_parts, $channels, $ignore, $args ); } function crb_send_lockout( $ip_address = '' ) { $em = crb_get_settings( 'notify_above-enabled' ); $pb = crb_get_settings( 'pbnotify-enabled' ); if ( ! $em && ! $pb ) { return false; } $count = cerber_blocked_num(); $send_email = ( $em && ( $count > crb_get_settings( 'notify_above' ) ) ); $channels = array( 'email' => $send_email, ); if ( lab_lab() ) { $channels['pushbullet'] = ( $pb && ( $count > crb_get_settings( 'pbnotify' ) ) ); } else { $channels['pushbullet'] = $send_email; } if ( array_filter( $channels ) ) { return cerber_send_message( 'lockout', array( 'ip' => $ip_address ), $channels ); } return false; } function cerber_enable_html() { return 'text\/html'; } function cerber_generate_email_report( $args ) { global $wpdb; $period = $args['report_id'] ?? 'one_week'; if ( $period == 'one_week' ) { if ( crb_get_settings( 'wreports_7' ) ) { $end = strtotime( 'midnight' ) - 1; $begin = $end - 7 * 24 * 3600 + 1; } else { $end = strtotime( 'last sunday' ) + 24 * 3600 - 1; $begin = $end - 7 * 24 * 3600 + 1; } $title = __( 'Weekly Report', 'wp-cerber' ); } elseif ( $period == 'one_month' ) { if ( crb_get_settings( 'monthly_30' ) ) { $end = strtotime( 'midnight' ) - 1; $begin = $end - 30 * 24 * 3600 + 1; } else { $date = getdate( strtotime( 'first day of previous month' ) ); $begin = mktime( 0, 0, 0, $date['mon'], $date['mday'], $date['year'] ); $date = getdate( strtotime( 'last day of previous month' ) ); $end = mktime( 23, 59, 59, $date['mon'], $date['mday'], $date['year'] ); } $title = __( 'Monthly Report', 'wp-cerber' ); } else { return array( 'Unsupported period of time', 'Unsupported period of time' ); } $report = ''; $kpi_rows = array(); $base_url = cerber_admin_link( 'activity', array(), false, false ); $css_table = 'width: 95%; max-width: 1000px; margin:0 auto; margin-bottom: 10px; background-color: #f5f5f5; text-align: center; font-family: Arial, Helvetica, sans-serif;'; $css_td = 'padding: 0.5em 0.5em 0.5em 1em; text-align: left;'; $css_border = 'border-bottom: solid 2px #f9f9f9;'; $site_name = ( is_multisite() ) ? get_site_option( 'site_name' ) : get_option( 'blogname' ); $df = get_option( 'date_format' ); $report .= '<div style=\"' . $css_table . '\"><div style=\"margin:0 auto; text-align: center;\"><p style=\"font-size: 130%; padding-top: 0.5em;\">' . $site_name . '<\/p><p>' . $title . '<\/p><p style=\"padding-bottom: 1em;\">' . date( $df, $begin ) . ' - ' . date( $df, $end ) . '<\/p><\/div><\/div>'; $activites = $wpdb->get_results( 'SELECT activity, COUNT(activity) cnt FROM ' . CERBER_LOG_TABLE . ' WHERE stamp BETWEEN ' . $begin . ' AND ' . $end . ' GROUP by activity ORDER BY cnt DESC' ); if ( $activites ) { $kpi_list = cerber_calculate_kpi( $begin, $end ); foreach ( $kpi_list as $kpi ) { $kpi_rows[] = '<td style=\"' . $css_td . ' text-align: right;\">' . $kpi[1] . '<\/td><td style=\"padding: 0.5em; text-align: left;\">' . $kpi[0] . '<\/td>'; } $report .= '<div style=\"text-align: center; ' . $css_table . '\"><table style=\"font-size: 130%; margin:0 auto;\"><tr>' . implode( '<\/tr><tr>', $kpi_rows ) . '<\/tr><\/table><\/div>'; $rows = array(); $rows[] = '<td style=\"' . $css_td . $css_border . '\" colspan=\"2\"><p style=\"line-height: 1.5em; font-weight: bold;\">' . __( 'Activity details', 'wp-cerber' ) . '<\/p><\/td>'; $lables = cerber_get_labels(); foreach ( $activites as $a ) { $rows[] = '<td style=\"' . $css_border . $css_td . '\">' . $lables[ $a->activity ] . '<\/td><td style=\"padding: 0.5em; text-align: center; width:10%;' . $css_border . '\"><a href=\"' . $base_url . '&filter_activity=' . $a->activity . '\">' . $a->cnt . '<\/a><\/td>'; } $report .= '<table style=\"border-collapse: collapse; ' . $css_table . '\"><tr>' . implode( '<\/tr><tr>', $rows ) . '<\/tr><\/table>'; $attempts = $wpdb->get_results( 'SELECT user_login, COUNT(user_login) cnt FROM ' . CERBER_LOG_TABLE . ' WHERE activity = 51 AND (stamp BETWEEN ' . $begin . ' AND ' . $end . ') GROUP by user_login ORDER BY cnt DESC LIMIT 10' ); if ( $attempts ) { $rows = array(); $rows[] = '<td style=\"' . $css_td . $css_border . '\" colspan=\"2\"><p style=\"line-height: 1.5em; font-weight: bold;\">' . __( 'Attempts to log in with non-existing usernames', 'wp-cerber' ) . '<\/p><\/td>'; foreach ( $attempts as $a ) { $rows[] = '<td style=\"' . $css_border . $css_td . '\">' . crb_generic_escape( $a->user_login ) . '<\/td><td style=\"padding: 0.5em; text-align: center; width:10%;' . $css_border . '\"><a href=\"' . $base_url . '&filter_login=' . $a->user_login . '\">' . $a->cnt . '<\/a><\/td>'; } $report .= '<table style=\"border-collapse: collapse; ' . $css_table . '\"><tr>' . implode( '<\/tr><tr>', $rows ) . '<\/tr><\/table>'; } } else { $report .= '<div style=\"text-align: center; ' . $css_table . '\"><p style=\"padding: 1em;\">No data logged within the specified date range to generate the report<\/p><\/div>'; } $report = '<div style=\"width:100%; padding: 1em; text-align: center; background-color: #f9f9f9;\">' . $report . '<\/div>'; return array( $title, $report ); } add_filter( 'cron_schedules', function ( $schedules ) { $schedules['crb_five'] = array( 'interval' => 300, 'display' => 'Every 5 Minutes', ); return $schedules; } ); add_action( 'cerber_hourly_1', 'cerber_do_hourly_1' ); function cerber_do_hourly_1( $force = false ) { $t = 'cerber_hourly_1'; $start = time(); if ( ( $last = get_site_transient( $t ) ) && date( 'G', $last[0] ) == date( 'G' ) ) { return; } set_site_transient( $t, array( $start ), 2 * 3600 ); if ( is_multisite() ) { if ( ! $force && get_site_transient( 'cerber_multisite' ) ) { return; } set_site_transient( 'cerber_multisite', 'executed', 3600 ); } require_once( __DIR__ . '\/cerber-toolbox.php' ); crb_log_maintainer(); crb_once_upgrade_log(); crb_once_upgrade_cbla(); cerber_truncate_log(); crb_plugin_update_notifier(); if ( $alerts = get_site_option( CRB_ALERTZ ) ) { $delete = array(); foreach ( $alerts as $hash => $alert ) { if ( crb_is_alert_expired( $alert ) ) { $delete[] = $hash; } } if ( $delete ) { foreach ( $delete as $hash ) { unset( $alerts[ $hash ] ); } if ( ! update_site_option( CRB_ALERTZ, $alerts ) ) { cerber_error_log( 'Unable to update the list of alerts', 'ALERTS' ); } } } if ( cerber_get_mode() != crb_get_settings( 'boot-mode' ) ) { cerber_set_boot_mode(); } set_site_transient( $t, array( $start, time() ), 2 * 3600 ); } add_action( 'cerber_hourly_2', 'cerber_do_hourly_2'); function cerber_do_hourly_2() { $t = 'cerber_hourly_2'; $start = time(); if ( ( $last = get_site_transient( $t ) ) && date( 'G', $last[0] ) == date( 'G' ) ) { return; } set_site_transient( $t, array( $start ), 2 * 3600 ); cerber_watchdog( true ); $now = time() + get_option( 'gmt_offset' ) * 3600; if ( crb_get_settings( 'enable-report' ) && date( 'w', $now ) == crb_get_settings( 'wreports-day' ) && date( 'G', $now ) == crb_get_settings( 'wreports-time' ) ) { $result = cerber_send_message( 'report' ); if ( ! $sent = get_site_option( '_cerber_report' ) ) { $sent = array(); } $sent['period_week'] = array( time(), $result ); update_site_option( '_cerber_report', $sent ); } if ( crb_get_settings( 'monthly_report' ) && $on = crb_get_settings( 'monthly_on' ) ) { $last_day = date( 'j', strtotime( 'last day of this month' ) ); $send_day = ( $on['day'] > $last_day ) ? $last_day : $on['day']; if ( date( 'j', $now ) == $send_day && date( 'G', $now ) == $on['hours'] ) { $result = cerber_send_message( 'report', array(), array(), false, array( 'report_id' => 'one_month' ) ); if ( ! $sent = get_site_option( '_cerber_report' ) ) { $sent = array(); } $sent['one_month'] = array( time(), $result ); update_site_option( '_cerber_report', $sent ); } } cerber_delete_expired_set(); if ( crb_get_settings( 'cerberlab' ) || lab_lab() ) { lab_check_nodes( true, true ); } cerber_push_lab(); cerber_cloud_sync(); cerber_get_the_folder(); cerber_db_query( 'DELETE FROM ' . CERBER_QMEM_TABLE . ' WHERE stamp < ' . ( time() - 30 * 60 ) ); set_site_transient( $t, array( $start, time() ), 2 * 3600 ); } add_action( 'cerber_daily', 'cerber_daily_run' ); function cerber_daily_run() { $t = 'cerber_daily_1'; $start = time(); if ( ( $last = get_site_transient( $t ) ) && date( 'j', $last[0] ) == date( 'j' ) ) { return; } set_site_transient( $t, array( $start ), 48 * 3600 ); cerber_do_hourly_1( true ); $time = time(); lab_validate_lic(); cerber_db_query( 'DELETE FROM ' . CERBER_LAB_NET_TABLE . ' WHERE expires < ' . $time ); cerber_db_query( 'DELETE FROM ' . CERBER_LAB_TABLE . ' WHERE stamp < ' . ( $time - 3600 ) ); $sql = 'SELECT the_id FROM ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' sets LEFT JOIN ' . CERBER_LOG_TABLE . ' log\r\n\t\t    ON log.user_id = sets.the_id\r\n\t\t    WHERE  sets.the_key = \"user_deleted\" AND log.user_id IS NULL'; $user_ids1 = cerber_db_get_col( $sql ); $sql = 'SELECT the_id FROM ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' sets LEFT JOIN ' . CERBER_TRAF_TABLE . ' log\r\n\t\t    ON log.user_id = sets.the_id\r\n\t\t    WHERE  sets.the_key = \"user_deleted\" AND log.user_id IS NULL'; $user_ids2 = cerber_db_get_col( $sql ); if ( $delete = array_intersect( $user_ids1, $user_ids2 ) ) { cerber_db_query( 'DELETE FROM ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' WHERE the_key = \"user_deleted\" AND the_id IN (' . implode( ',', $delete ) . ')' ); } cerber_db_query( 'OPTIMIZE TABLE ' . CERBER_LOG_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . CERBER_QMEM_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . CERBER_TRAF_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . CERBER_ACL_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . CERBER_BLOCKS_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . CERBER_LAB_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . CERBER_LAB_IP_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . CERBER_LAB_NET_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . cerber_get_db_prefix() . CERBER_SCAN_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . cerber_get_db_prefix() . CERBER_SETS_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . cerber_get_db_prefix() . CERBER_MS_LIST_TABLE ); cerber_db_query( 'OPTIMIZE TABLE ' . cerber_get_db_prefix() . CERBER_USS_TABLE ); cerber_check_new_version( false ); if ( nexus_is_main() ) { if ( ( $ups = get_site_transient( 'update_plugins' ) ) && ! empty( $ups->response ) ) { nexus_update_updates( obj_to_arr_deep( $ups->response ) ); } nexus_delete_unused( 'nexus_servers', 'server_id' ); nexus_delete_unused( 'nexus_countries', 'server_country' ); } CRB_Cache::reset(); if ( $dirs = glob( cerber_get_the_folder() . 'quarantine' . '\/*', GLOB_ONLYDIR ) ) { $sync = false; foreach ( $dirs as $dir ) { $d = basename( $dir ); if ( is_numeric( $d ) ) { if ( $d < ( time() - DAY_IN_SECONDS * crb_get_settings( 'scan_qcleanup' ) ) ) { $fs = cerber_init_wp_filesystem(); if ( ! crb_is_wp_error( $fs ) ) { $fs->delete( $dir, true ); $sync = true; } } } } if ( $sync ) { _crb_qr_total_sync(); } } else { _crb_qr_total_sync( 0 ); } cerber_upgrade_deferred(); crb_truncate_log_file( crb_get_diag_dir() . 'cerber-errors.log' ); set_site_transient( $t, array( $start, time() ), 48 * 3600 ); } add_action( 'cerber_bg_launcher', function () { $next_hour = intval( floor( ( time() + 3600 ) \/ 3600 ) * 3600 ); if ( ! wp_next_scheduled( 'cerber_hourly_1' ) ) { wp_schedule_event( $next_hour, 'hourly', 'cerber_hourly_1' ); } if ( ! wp_next_scheduled( 'cerber_hourly_2' ) ) { wp_schedule_event( $next_hour + 600 , 'hourly', 'cerber_hourly_2' ); } if ( ! wp_next_scheduled( 'cerber_daily' ) ) { if ( ! $when = strtotime( 'midnight' ) + 24 * 3600 ) { $when = $next_hour; } wp_schedule_event( $when + 2 * 3600 + 1200, 'daily', 'cerber_daily' ); } define( 'CRB_DOING_BG_TASK', 1 ); @ignore_user_abort( true ); crb_raise_limits(); if ( nexus_is_main() ) { nexus_schedule_refresh(); } cerber_bg_task_launcher(); require_once( __DIR__ . '\/cerber-toolbox.php' ); if ( cerber_get_set( 'event_wp_found_updates', null, false ) ) { crb_plugin_update_notifier( true ); cerber_delete_set( 'event_wp_found_updates' ); } } ); function cerber_bg_task_launcher( $filter = null ) { $ret = array(); if ( ! $task_list = cerber_bg_task_get_all() ) { return $ret; } if ( $filter ) { $task_list = array_intersect_key( $task_list, $filter ); } if ( empty( $task_list ) ) { return $ret; } foreach ( $task_list as $task_id => $task ) { $func = crb_array_get( $task, 'func' ); if ( ! is_callable( $func ) ) { $err = 'Function ' . crb_make_callable_name( $func ) . ' is not callable or not defined'; $ret[ $task_id ] = $err; cerber_error_log( $err, 'BG TASK' ); cerber_bg_task_delete( $task_id ); continue; } if ( ! isset( $task['exec_until'] ) ) { cerber_bg_task_delete( $task_id ); } if ( ! empty( $task['load_admin'] ) ) { cerber_load_admin_code(); } $args = crb_array_get( $task, 'args', array() ); nexus_diag_log( 'Launching bg task: ' . crb_make_callable_name( $func ) ); ob_start(); $result = call_user_func_array( $func, $args ); $output = ob_get_clean(); if ( isset( $task['exec_until'] ) ) { if ( $task['exec_until'] === $result ) { cerber_bg_task_delete( $task_id ); } } if ( empty( $task['return'] ) ) { $output = ( $output ) ? 'there was an output ' . mb_strlen( $output ) . ' bytes length' : 'no output'; $result = 1; } $ret[ $task_id ] = array( $result, crb_array_get( $task, 'run_js' ), $output ); } return $ret; } function cerber_bg_task_get_all() { $tasks = cerber_get_set( '_background_tasks' ); if ( ! $tasks || ! is_array( $tasks ) ) { $tasks = array(); } return $tasks; } function cerber_bg_task_add( $func, $config = array(), $priority = false ) { if ( ! is_callable( $func ) ) { return new WP_Error( 'bg_tasks_nope', 'Specified function ' . crb_make_callable_name( $func ) . ' is not callable or not defined.' ); } $list = cerber_bg_task_get_all(); $config['func'] = $func; $task_id = sha1( serialize( $config ) ); if ( isset( $list[ $task_id ] ) ) { return false; } if ( $priority ) { $list = array( $task_id => $config ) + $list; } else { $list[ $task_id ] = $config; } return cerber_update_set( '_background_tasks', $list ); } function cerber_bg_task_delete( $task_id = '' ) { if ( ! $list = cerber_bg_task_get_all() ) { return false; } if ( ! isset( $list[ $task_id ] ) ) { return false; } unset( $list[ $task_id ] ); return cerber_update_set( '_background_tasks', $list ); } function crb_make_callable_name( $cb ) { if ( is_string( $cb ) ) { return $cb; } if ( is_array( $cb ) ) { if ( count( $cb ) === 2 ) { if ( is_object( $cb[0] ) ) { return get_class( $cb[0] ) . '::' . $cb[1]; } else { return $cb[0] . '::' . $cb[1]; } } return print_r( $cb, true ); } if ( $cb instanceof Closure ) { return 'Closure'; } if ( is_object( $cb ) ) { return print_r( $cb, true ); } return (string) $cb; } function cerber_log( $activity, $login = '', $user_id = 0, $status = 0, $ip = '' ) { return CRB_Activity::log( (int) $activity, (string) $login, (int) $user_id, (int) $status, (string) $ip ); } function cerber_get_last_login( $user_id, $user_email = '' ) { if ( $user_id ) { $u = array( 'id' => $user_id ); } elseif ( $user_email ) { $u = array( 'email' => $user_email ); } else { return false; } if ( $recs = CRB_Activity::get_log( array( CRB_EV_LIN ), $u, array( 'DESC' => 'stamp' ), 1 ) ) { return $recs[0]; } return false; } function crb_get_last_failed( $login, $email, $denied = false ) { $act = ( $denied ) ? 53 : CRB_EV_LFL; return cerber_db_get_row( 'SELECT * FROM ' . CERBER_LOG_TABLE . ' WHERE ( user_login = \"' . $login . '\" OR user_login = \"' . $email . '\" ) AND activity = ' . $act . ' ORDER BY stamp DESC LIMIT 1', MYSQL_FETCH_OBJECT ); } function cerber_count_log( $activity, $begin, $end, $column = 'ip', $distinct = false ) { $begin = ( (int) floor( (int) $begin \/ 90 ) ) * 90; $end = ( (int) floor( (int) $end \/ 90 ) ) * 90; $column = ( ( $distinct ) ? ' DISTINCT ' : '' ) . $column; $result = crb_q_cache_get( 'SELECT COUNT( ' . $column . ' ) FROM ' . CERBER_LOG_TABLE . ' WHERE activity IN (' . implode( ',', $activity ) . ') AND (stamp BETWEEN ' . $begin . ' AND ' . $end . ')', CERBER_LOG_TABLE ); if ( empty( $result ) ) { return 0; } return $result[0][0]; } function cerber_on_plugin_activation() { if ( cerber_get_get( 'action' ) === 'activate' && cerber_get_get( 'plugin' ) === CERBER_PLUGIN_ID ) { if ( ! crb_get_settings( '', true, false ) ) { if ( ! defined( 'CRB_JUST_MARRIED' ) ) { define( 'CRB_JUST_MARRIED', 1 ); } cerber_load_defaults(); } } add_action( 'activated_plugin', function ( $plugin ) { if ( $plugin !== CERBER_PLUGIN_ID ) { return; } if ( ! crb_get_settings( '', true, false ) ) { if ( ! defined( 'CRB_JUST_MARRIED' ) ) { define( 'CRB_JUST_MARRIED', 1 ); } cerber_load_defaults(); } } ); } register_activation_hook( cerber_plugin_file(), function () { load_plugin_textdomain( 'wp-cerber', false, 'wp-cerber\/languages' ); if ( version_compare( CERBER_REQ_PHP, phpversion(), '>' ) ) { cerber_stop_activating( '<h3>' . sprintf( __( 'WP Cerber requires PHP version %s or higher, but your web server is currently running PHP %s.', 'wp-cerber' ), CERBER_REQ_PHP, phpversion() ) . '<\/h3>' ); } if ( ! crb_wp_version_compare( CERBER_REQ_WP ) ) { cerber_stop_activating( '<h3>' . sprintf( __( 'WP Cerber requires WordPress version %s or higher. Your WordPress version is %s. Please update your WordPress to the latest version.', 'wp-cerber' ), CERBER_REQ_WP, cerber_get_wp_version() ) . '<\/h3>' ); } $db_errors = cerber_create_db(); if ( $db_errors ) { $e = ''; foreach ( $db_errors as $db_error ) { $e .= '<p>' . implode( '<\/p><p>', $db_error ) . '<\/p>'; } cerber_stop_activating( '<h3>' . __( \"Can't activate WP Cerber due to a database error.\", 'wp-cerber' ) . '<\/h3>'.$e); } lab_get_key( true ); cerber_upgrade_all( true ); cerber_cookie_one(); cerber_load_admin_code(); cerber_bg_task_add( 'crb_sessions_sync_all' ); $whited = ''; if ( is_user_logged_in() ) { $ip = cerber_get_remote_ip(); if ( cerber_get_block( $ip ) ) { if ( ! cerber_block_delete( $ip ) ) { $sub = cerber_get_subnet_ipv4( $ip ); cerber_block_delete( $sub ); } } if ( ! crb_get_settings( 'no_white_my_ip' ) ) { cerber_add_white( $ip, 'My IP address (' . cerber_date( time(), false ) . ')' ); $whited = ' <p>' . sprintf( __( 'Your IP address %s has been added to the White IP Access List', 'wp-cerber' ), cerber_get_remote_ip() ); } cerber_disable_citadel(); } cerber_htaccess_sync( 'main' ); cerber_htaccess_sync( 'media' ); cerber_set_boot_mode(); crb_x_update_add_on_list(); $msg = '<h2>' . __( 'WP Cerber is now active and has started protecting your site', 'wp-cerber' ) . '<\/h2>' . $whited . '<p style=\"font-size:130%;\"><a href=\"https:\/\/wpcerber.com\/getting-started\/\" target=\"_blank\">' . __( 'Getting Started Guide', 'wp-cerber' ) . '<\/a><\/p>' . '<div id=\"crb-activation-msg\"><p>' . ' <i class=\"crb-icon crb-icon-bx-layer\"><\/i> <a href=\"' . cerber_admin_link( 'imex' ) . '\">' . __( 'Import settings', 'wp-cerber' ) . '<\/a>' . ' <i class=\"crb-icon dashicons-before dashicons-twitter\"><\/i> <a target=\"_blank\" href=\"https:\/\/twitter.com\/wpcerber\">Follow Cerber on X<\/a>' . ' <i class=\"crb-icon dashicons-before dashicons-email-alt\"><\/i> <a target=\"_blank\" href=\"https:\/\/wpcerber.com\/subscribe-newsletter\/\">Subscribe to Cerber\\'s newsletter<\/a>' . '<\/p><\/div>'; cerber_update_set( 'cerber_admin_wide', $msg ); $pi = array(); $pi['Version'] = CERBER_VER; $pi['time'] = time(); $pi['user'] = get_current_user_id(); $pi['ip'] = cerber_get_remote_ip(); $pi['ua'] = crb_array_get( $_SERVER, 'HTTP_USER_AGENT', '' ); cerber_update_set( '_cerber_on', $pi ); if ( ! defined( 'CRB_JUST_MARRIED' ) || ! CRB_JUST_MARRIED ) { return; } cerber_send_message( 'activated' ); if ( ! cerber_get_set( '_activated' ) ) { cerber_update_set( '_activated', $pi ); } }); function cerber_stop_activating( $msg ) { deactivate_plugins( CERBER_PLUGIN_ID ); wp_die( $msg ); } register_uninstall_hook( cerber_plugin_file(), 'cerber_finito' ); function cerber_finito() { if ( ! is_super_admin() ) { return; } $dir = cerber_get_the_folder(); if ( $dir && file_exists( $dir ) ) { $fs = cerber_init_wp_filesystem(); if ( ! crb_is_wp_error( $fs ) ) { $fs->rmdir( $dir, true ); } } $list = array( CRB_ALERTZ, '_cerber_up', '_cerber_report', 'cerber_tmp_old_settings', 'cerber-groove', 'cerber-groove-x', '_cerberkey_', 'cerber-antibot', 'cerber_admin_info', '_cerber_db_errors', '_cerber_notify_new' ); $list = array_merge( $list, cerber_get_setting_list( true ) ); foreach ( $list as $opt ) { delete_site_option( $opt ); } cerber_db_query( 'DROP TABLE IF EXISTS ' . implode( ',', cerber_get_tables() ) ); } function cerber_upgrade_all( $force = false ) { $ver = get_site_option( '_cerber_up' ); if ( ! $force && crb_array_get( $ver, 'v' ) == CERBER_VER ) { return; } $d = @ini_get( 'display_errors' ); @ini_set( 'display_errors', 0 ); @ignore_user_abort( true ); crb_raise_limits(); CRB_Globals::$doing_upgrade = true; if ( ! defined( 'CRB_DOING_UPGRADE' ) ) { define( 'CRB_DOING_UPGRADE', 1 ); } crb_clear_admin_msg(); cerber_remove_issues(); cerber_create_db(); if ( $errors = cerber_upgrade_db() ) { } cerber_antibot_gene( true ); cerber_upgrade_settings( crb_array_get( $ver, 'v' ) ); cerber_htaccess_sync( 'main' ); cerber_bg_task_add( 'cerber_upgrade_deferred' ); delete_site_option( '_cerber_report' ); update_site_option( '_cerber_up', array( 'v' => CERBER_VER, 't' => time() ) ); cerber_push_the_news(); cerber_delete_expired_set( true ); CRB_Cache::reset(); if ( wp_next_scheduled( 'cerber_hourly' ) ) { wp_clear_scheduled_hook( 'cerber_hourly' ); } if ( $alerts = get_site_option( CRB_ALERTZ ) ) { $test = current( $alerts ); if ( ! isset( $test[9] ) ) { $new = array(); foreach ( $alerts as $alert ) { $alert[9] = 0; $alert[10] = 0; $new[ crb_get_alert_id( $alert ) ] = $alert; } if ( ! update_site_option( CRB_ALERTZ, $new ) ) { cerber_error_log( 'Unable to update the list of alerts', 'ALERTS' ); } } } $orphans = array( '\/nexus\/cerber-nexus-master.php', '\/nexus\/cerber-nexus-slave.php', '\/nexus\/cerber-slave-list.php' ); foreach ( $orphans as $file ) { $delete = cerber_plugin_dir() . $file; if ( is_file( $delete ) && file_exists( $delete ) ) { unlink( $delete ); } } lab_get_key( true ); CRB_Globals::$doing_upgrade = false; delete_site_transient( 'update_plugins' ); @ini_set( 'display_errors', $d ); } function cerber_create_db($recreate = true) { global $wpdb; $wpdb->hide_errors(); $db_errors = array(); $sql = array(); if ( ! cerber_is_table( CERBER_LOG_TABLE ) ) { $sql[] = '\r\n        \tCREATE TABLE IF NOT EXISTS ' . CERBER_LOG_TABLE . ' (\r\n            ip varchar(39) CHARACTER SET ascii NOT NULL,\r\n            user_login varchar(60) NOT NULL,\r\n            user_id bigint(20) unsigned NOT NULL DEFAULT \"0\",\r\n            stamp bigint(20) unsigned NOT NULL,\r\n            activity int(10) unsigned NOT NULL DEFAULT \"0\",\r\n            KEY ip (ip)\r\n\t        ) DEFAULT CHARSET=utf8;\r\n\t\t\t\t'; } if ( ! cerber_is_table( CERBER_ACL_TABLE ) ) { $sql[] = '\r\n            CREATE TABLE IF NOT EXISTS ' . CERBER_ACL_TABLE . ' (\r\n            ip varchar(39) CHARACTER SET ascii NOT NULL,\r\n            tag char(1) NOT NULL,\r\n            comments varchar(250) NOT NULL\r\n\t        ) DEFAULT CHARSET=utf8;\r\n\t\t\t\t'; } if ( ! cerber_is_table( CERBER_BLOCKS_TABLE ) ) { $sql[] = '\r\n\t        CREATE TABLE IF NOT EXISTS ' . CERBER_BLOCKS_TABLE . ' (\r\n\t\t    ip varchar(39) CHARACTER SET ascii NOT NULL,\r\n\t\t    block_until bigint(20) unsigned NOT NULL,\r\n\t\t    reason varchar(250) NOT NULL,\r\n\t\t    reason_id int(11) unsigned NOT NULL DEFAULT \"0\",\r\n\t\t    UNIQUE KEY ip (ip)\r\n\t\t\t) DEFAULT CHARSET=utf8;\t\t\t\r\n\t\t\t\t'; } if ( ! cerber_is_table( CERBER_LAB_TABLE ) ) { $sql[] = '\r\n            CREATE TABLE IF NOT EXISTS ' . CERBER_LAB_TABLE . ' (\r\n            ip varchar(39) CHARACTER SET ascii NOT NULL,\r\n            reason_id int(11) unsigned NOT NULL DEFAULT \"0\",\r\n            stamp bigint(20) unsigned NOT NULL,\r\n            details text NOT NULL\r\n\t\t\t) DEFAULT CHARSET=utf8;\r\n\t\t\t\t'; } if ( $recreate || ! cerber_is_table( CERBER_LAB_IP_TABLE ) ) { if ( $recreate && cerber_is_table( CERBER_LAB_IP_TABLE ) ) { $sql[] = 'DROP TABLE IF EXISTS ' . CERBER_LAB_IP_TABLE; } $sql[] = '\r\n            CREATE TABLE IF NOT EXISTS ' . CERBER_LAB_IP_TABLE . ' ( \r\n            ip varchar(39) CHARACTER SET ascii NOT NULL,\r\n            reputation INT(11) UNSIGNED NOT NULL,\r\n            expires INT(11) UNSIGNED NOT NULL, \r\n            PRIMARY KEY (ip)\r\n\t\t\t) DEFAULT CHARSET=utf8;\r\n\t\t\t\t'; } if ( $recreate || ! cerber_is_table( CERBER_LAB_NET_TABLE ) ) { if ( $recreate && cerber_is_table( CERBER_LAB_NET_TABLE ) ) { $sql[] = 'DROP TABLE IF EXISTS ' . CERBER_LAB_NET_TABLE; } $sql[] = '\r\n            CREATE TABLE IF NOT EXISTS ' . CERBER_LAB_NET_TABLE . ' (\r\n            ip varchar(39) CHARACTER SET ascii NOT NULL DEFAULT \"\",             \r\n            ip_long_begin BIGINT UNSIGNED NOT NULL DEFAULT \"0\",\r\n            ip_long_end BIGINT UNSIGNED NOT NULL DEFAULT \"0\",\r\n            country CHAR(3) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT \"\",\r\n            expires INT(11) UNSIGNED NOT NULL DEFAULT \"0\", \r\n            PRIMARY KEY (ip),\r\n            UNIQUE KEY begin_end (ip_long_begin, ip_long_end)\r\n\t\t\t) DEFAULT CHARSET=utf8;\r\n\t\t\t\t'; } if ( ! cerber_is_table( CERBER_GEO_TABLE ) ) { $sql[] = '\r\n            CREATE TABLE IF NOT EXISTS ' . CERBER_GEO_TABLE . ' (\r\n            country CHAR(3) NOT NULL DEFAULT \"\" COMMENT \"Country code\",\r\n            locale CHAR(10) NOT NULL DEFAULT \"\" COMMENT \"Locale i18n\",\r\n            country_name VARCHAR(250) NOT NULL DEFAULT \"\",\r\n            PRIMARY KEY (country, locale)\r\n\t\t\t) DEFAULT CHARSET=utf8;\r\n\t\t\t\t'; } if ( ! cerber_is_table( CERBER_TRAF_TABLE ) ) { $sql[] = '\r\n            CREATE TABLE IF NOT EXISTS ' . CERBER_TRAF_TABLE . ' (            \r\n            ip varchar(39) CHARACTER SET ascii NOT NULL,\r\n            ip_long BIGINT UNSIGNED NOT NULL DEFAULT \"0\", \r\n            hostname varchar(250) NOT NULL DEFAULT \"\",\r\n            uri text NOT NULL,\r\n            request_fields MEDIUMTEXT NOT NULL,\r\n            request_details MEDIUMTEXT NOT NULL,\r\n            session_id char(32) CHARACTER SET ascii NOT NULL,\r\n            user_id bigint(20) UNSIGNED NOT NULL DEFAULT 0,\r\n            stamp decimal(14,4) NOT NULL,\r\n            processing int(10) NOT NULL DEFAULT 0,\r\n            country char(3) CHARACTER SET ascii NOT NULL DEFAULT \"\",\r\n            request_method char(8) CHARACTER SET ascii NOT NULL,\r\n            http_code int(10) UNSIGNED NOT NULL,\r\n            wp_id bigint(20) UNSIGNED NOT NULL DEFAULT 0,\r\n            wp_type int(10) UNSIGNED NOT NULL DEFAULT 0,\r\n            is_bot int(10) UNSIGNED NOT NULL DEFAULT 0,\r\n            blog_id int(10) UNSIGNED NOT NULL DEFAULT 0,\r\n            KEY stamp (stamp)\r\n            ) DEFAULT CHARSET=utf8;\r\n\t\t\t'; } if ( ! cerber_is_table( cerber_get_db_prefix() . CERBER_SCAN_TABLE ) ) { $sql[] = '\r\n\t\t    CREATE TABLE IF NOT EXISTS ' . cerber_get_db_prefix(). CERBER_SCAN_TABLE . ' (\r\n            scan_id INT(10) UNSIGNED NOT NULL,\r\n            scan_type INT(10) UNSIGNED NOT NULL DEFAULT 1,\r\n            scan_mode INT(10) UNSIGNED NOT NULL DEFAULT 0,\r\n            scan_status INT(10) UNSIGNED NOT NULL DEFAULT 0,\r\n            file_name_hash VARCHAR(255) CHARACTER SET ascii NOT NULL DEFAULT \"\",\r\n            file_name TEXT NOT NULL,\r\n            file_type INT(10) UNSIGNED NOT NULL DEFAULT 0,\r\n            file_hash VARCHAR(255) CHARACTER SET ascii NOT NULL DEFAULT \"\",\r\n            file_md5 VARCHAR(255) CHARACTER SET ascii NOT NULL DEFAULT \"\",\r\n            file_hash_repo VARCHAR(255) CHARACTER SET ascii NOT NULL DEFAULT \"\",\r\n            hash_match INT(10) UNSIGNED NOT NULL DEFAULT 0,\r\n            file_size BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,\r\n            file_perms INT(11) NOT NULL DEFAULT 0,\r\n            file_writable INT(10) UNSIGNED NOT NULL DEFAULT 0,\r\n            file_mtime INT(10) UNSIGNED NOT NULL DEFAULT 0,\r\n            extra TEXT NOT NULL,\r\n            PRIMARY KEY (scan_id, file_name_hash)\r\n            ) DEFAULT CHARSET=utf8;\r\n        '; } if ( ! cerber_is_table( cerber_get_db_prefix() . CERBER_SETS_TABLE ) ) { $sql[] = '\r\n            CREATE TABLE IF NOT EXISTS ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' (          \r\n            the_key VARCHAR(255) CHARACTER SET ascii NOT NULL,\r\n            the_id BIGINT(20) NOT NULL DEFAULT 0,\r\n            the_value LONGTEXT NOT NULL,\r\n            expires BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,\r\n            PRIMARY KEY (the_key, the_id)\r\n\t\t\t) DEFAULT CHARSET=utf8;\r\n        '; } if ( ! cerber_is_table( CERBER_QMEM_TABLE ) ) { $sql[] = '\r\n            CREATE TABLE IF NOT EXISTS ' . CERBER_QMEM_TABLE . ' (            \r\n            ip varchar(39) CHARACTER SET ascii NOT NULL,\r\n            http_code int(10) UNSIGNED NOT NULL,\r\n            stamp int(10) UNSIGNED NOT NULL,\r\n            KEY ip_stamp (ip, stamp)\r\n\t\t\t) DEFAULT CHARSET=utf8;\r\n    \t\t\t'; } if ( ! cerber_is_table( cerber_get_db_prefix() . CERBER_USS_TABLE ) ) { $sql[] = '\r\n            CREATE TABLE IF NOT EXISTS ' . cerber_get_db_prefix() . CERBER_USS_TABLE . ' (\r\n            user_id bigint(20) UNSIGNED NOT NULL,\r\n            ip varchar(39) CHARACTER SET ascii NOT NULL,\r\n            country char(3) CHARACTER SET ascii NOT NULL DEFAULT \"\",\r\n            started int(10) UNSIGNED NOT NULL,\r\n            expires int(10) UNSIGNED NOT NULL,\r\n            session_id char(32) CHARACTER SET ascii NOT NULL DEFAULT \"\",\r\n            wp_session_token varchar(250) CHARACTER SET ascii NOT NULL,             \r\n            KEY user_id (user_id)\r\n\t\t\t) DEFAULT CHARSET=utf8;\r\n    \t\t\t'; } foreach ( $sql as $query ) { $query = str_replace( '\"', '\\'', $query ); if ( ! $wpdb->query( $query ) && $wpdb->last_error ) { $db_errors[] = array( $wpdb->last_error, $wpdb->last_query ); } } return $db_errors; } function cerber_upgrade_db( $force = false ) { $sql = array(); if ( $force || ! cerber_db_check_column_type( CERBER_LOG_TABLE, 'stamp', 'decimal', [ 'numeric_precision' => 14, 'numeric_scale' => 4 ] ) ) { $sql[] = 'ALTER TABLE ' . CERBER_LOG_TABLE . ' CHANGE stamp stamp DECIMAL(14,4) NOT NULL'; } if ( $force || ! cerber_is_column( CERBER_LOG_TABLE, 'ip_long' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_LOG_TABLE . ' ADD ip_long BIGINT UNSIGNED NOT NULL DEFAULT \"0\" AFTER ip, ADD INDEX (ip_long)'; } if ( $force || ! cerber_is_column( CERBER_ACL_TABLE, 'ip_long_begin' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_ACL_TABLE . ' ADD ip_long_begin BIGINT UNSIGNED NOT NULL DEFAULT \"0\" AFTER ip, ADD ip_long_end BIGINT UNSIGNED NOT NULL DEFAULT \"0\" AFTER ip_long_begin'; } if ( $force || cerber_is_index( CERBER_ACL_TABLE, 'ip' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_ACL_TABLE . ' DROP INDEX ip'; } if ( $force || cerber_is_index( CERBER_ACL_TABLE, 'begin_end' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_ACL_TABLE . ' DROP INDEX begin_end'; } if ( $force || ! cerber_is_column( CERBER_LOG_TABLE, 'session_id' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_LOG_TABLE . ' \r\n        ADD session_id CHAR(32) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT \"\",\r\n        ADD country CHAR(3) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT \"\",\r\n        ADD details VARCHAR(250) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT \"\";\r\n      '; } if ( $force || ! cerber_is_index( CERBER_LOG_TABLE, 'session_index' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_LOG_TABLE . ' ADD INDEX session_index (session_id)'; } $sql[] = 'DROP TABLE IF EXISTS ' . CERBER_SCAN_TABLE; if ( $force || ! cerber_is_column( cerber_get_db_prefix() . CERBER_SCAN_TABLE, 'file_status' ) ) { $sql[] = 'ALTER TABLE ' . cerber_get_db_prefix() . CERBER_SCAN_TABLE . \" ADD file_status INT UNSIGNED NOT NULL DEFAULT '0' AFTER scan_status\"; } if ( $force || ! cerber_is_column( CERBER_BLOCKS_TABLE, 'reason_id' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_BLOCKS_TABLE . ' ADD reason_id int(11) unsigned NOT NULL DEFAULT \"0\"'; } if ( $force || ! cerber_is_column( CERBER_TRAF_TABLE, 'php_errors' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_TRAF_TABLE . ' ADD php_errors TEXT NOT NULL AFTER blog_id'; } if ( $force || ! cerber_is_column( CERBER_ACL_TABLE, 'ver6' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_ACL_TABLE . '\r\n\t\tADD acl_slice SMALLINT UNSIGNED NOT NULL DEFAULT 0, \r\n\t\tADD ver6 SMALLINT UNSIGNED NOT NULL DEFAULT 0,\r\n\t\tADD v6range VARCHAR(255) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT \"\",\r\n\t\tADD req_uri VARCHAR(255) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT \"\",\r\n\t\tMODIFY COLUMN ip VARCHAR(81) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL\r\n\t\t'; } if ( $force || ! cerber_is_index( CERBER_ACL_TABLE, 'main_for_selects' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_ACL_TABLE . ' ADD INDEX main_for_selects (acl_slice, ver6, ip_long_begin, ip_long_end, tag)'; } if ( $force || cerber_is_index( CERBER_ACL_TABLE, 'begin_end_tag' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_ACL_TABLE . ' DROP INDEX begin_end_tag'; } if ( $force || cerber_is_index( CERBER_ACL_TABLE, 'ip_begin_end' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_ACL_TABLE . ' DROP INDEX ip_begin_end'; } if ( $force || ! cerber_is_column( cerber_get_db_prefix() . CERBER_SCAN_TABLE, 'file_ext' ) ) { $sql[] = 'ALTER TABLE ' . cerber_get_db_prefix() . CERBER_SCAN_TABLE . '\r\n\t\tADD file_ext VARCHAR(255) NOT NULL DEFAULT \"\" AFTER file_mtime\r\n\t\t'; } if ( $force || ! cerber_is_column( CERBER_TRAF_TABLE, 'req_status' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_TRAF_TABLE . ' ADD req_status int(10) UNSIGNED NOT NULL DEFAULT 0'; } if ( $force || ! cerber_is_column( cerber_get_db_prefix() . CERBER_SCAN_TABLE, 'scan_step' ) ) { $sql[] = 'ALTER TABLE ' . cerber_get_db_prefix() . CERBER_SCAN_TABLE . '\r\n\t\tADD scan_step INT UNSIGNED NOT NULL DEFAULT 0 AFTER scan_mode\r\n\t\t'; } if ( $force || ! cerber_is_column( CERBER_LOG_TABLE, 'ac_status' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_LOG_TABLE . '\r\n\t\tADD ac_bot int(10) UNSIGNED NOT NULL DEFAULT 0,\r\n\t\tADD ac_status int(10) UNSIGNED NOT NULL DEFAULT 0,\r\n\t\tADD ac_by_user bigint(20) UNSIGNED NOT NULL DEFAULT 0'; } if ( $force || ! cerber_is_column( cerber_get_db_prefix() . CERBER_SETS_TABLE, 'argo' ) ) { $sql[] = 'ALTER TABLE ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' ADD argo int(10) UNSIGNED NOT NULL DEFAULT 0'; } if ( $force || ! cerber_is_column( cerber_get_db_prefix() . CERBER_USS_TABLE, 'mfa_status' ) ) { $sql[] = 'ALTER TABLE ' . cerber_get_db_prefix() . CERBER_USS_TABLE . '\r\n\t\tADD mfa_status int(10) UNSIGNED NOT NULL DEFAULT 0'; } if ( $force || ! cerber_is_column( CERBER_BLOCKS_TABLE, 'session_id' ) ) { $sql[] = 'ALTER TABLE ' . CERBER_BLOCKS_TABLE . ' ADD session_id CHAR(32) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT \"\"'; } if ( ! empty( $sql ) ) { foreach ( $sql as $query ) { $query = str_replace( '\"', '\\'', $query ); cerber_db_query( $query ); } } cerber_acl_fixer(); $db_errors = cerber_db_get_errors(); if ( ! $force && $db_errors ) { cerber_add_issue( __FUNCTION__, 'Database errors occured while upgrading WP Cerber database tables.', array( 'section' => 'upgrading_db', 'details' => $db_errors ) ); cerber_db_error_log( cerber_db_get_errors( true, false ) ); } return $db_errors; } function cerber_upgrade_deferred() { list ( $charset, $collate ) = cerber_db_detect_collate(); if ( $charset == 'utf8mb4' ) { $col_name = 'request_fields'; if ( ( $col_info = cerber_db_get_columns( CERBER_TRAF_TABLE, $col_name ) ) && 'utf8mb4_unicode_ci' != $col_info['collation'] ) { cerber_db_query( 'ALTER TABLE ' . CERBER_TRAF_TABLE . ' MODIFY COLUMN ' . $col_name . ' ' . $col_info['type'] . ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' ); } } } function cerber_db_get_columns( $table, $column = '' ) { $where = ''; if ( $column ) { $column = preg_replace( '\/[^a-z_]\/i', '', $column ); $where = ' WHERE field = \"' . $column . '\"'; } $table = preg_replace( '\/[^a-z_]\/i', '', $table ); if ( $data = cerber_db_get_results( \"SHOW FULL COLUMNS FROM \" . $table . $where, MYSQL_FETCH_OBJECT_K ) ) { if ( $column ) { $data = current( $data ); } $data = obj_to_arr_deep( $data ); return crb_array_change_key_case( $data, CASE_LOWER ); } return false; } function cerber_db_detect_collate() { global $wpdb; if ( ! $wpdb->charset ) { $wpdb->init_charset(); } if ( 'utf8mb4' === $wpdb->charset || ( ! $wpdb->charset && $wpdb->has_cap( 'utf8mb4' ) ) ) { $charset = 'utf8mb4'; $collate = 'utf8mb4_unicode_ci'; } else { $charset = 'utf8'; $collate = 'utf8_general_ci'; } return array( $charset, $collate ); } function cerber_get_tables() { return array( CERBER_LOG_TABLE, CERBER_QMEM_TABLE, CERBER_TRAF_TABLE, CERBER_ACL_TABLE, CERBER_BLOCKS_TABLE, CERBER_LAB_TABLE, CERBER_LAB_IP_TABLE, CERBER_LAB_NET_TABLE, CERBER_GEO_TABLE, cerber_get_db_prefix() . CERBER_SCAN_TABLE, cerber_get_db_prefix() . CERBER_SETS_TABLE, cerber_get_db_prefix() . CERBER_MS_TABLE, cerber_get_db_prefix() . CERBER_MS_LIST_TABLE, cerber_get_db_prefix() . CERBER_USS_TABLE, ); } function cerber_acl_fixer() { $ips = cerber_db_get_col( 'SELECT ip FROM ' . CERBER_ACL_TABLE . ' WHERE ip_long_begin = 0 OR ip_long_end = 0 OR ip_long_begin = 7777777777' ); if ( ! $ips ) { return; } foreach ( $ips as $ip ) { $v6range = ''; $ver6 = 0; if ( cerber_is_ipv4( $ip ) ) { $begin = ip2long( $ip ); $end = ip2long( $ip ); } elseif ( cerber_is_ipv6( $ip ) ) { $ip = cerber_ipv6_short( $ip ); list( $begin, $end, $v6range ) = crb_ipv6_prepare( $ip, $ip ); $ver6 = 1; } elseif ( ( $range = cerber_any2range( $ip ) ) && is_array( $range ) ) { $ver6 = $range['IPV6']; $begin = $range['begin']; $end = $range['end']; $v6range = $range['IPV6range']; } else { continue; } $set = 'ip_long_begin = ' . $begin . ', ip_long_end = ' . $end . ', ver6 = ' . $ver6 . ', v6range = \"' . $v6range . '\"  WHERE ip = \"' . $ip . '\"'; cerber_db_query( 'UPDATE ' . CERBER_ACL_TABLE . ' SET ' . $set ); } } add_action( 'deac' . 'tivate_' . CERBER_PLUGIN_ID, function ( $ip ) { wp_clear_scheduled_hook( 'cerber_bg_launcher' ); wp_clear_scheduled_hook( 'cerber_hourly_1' ); wp_clear_scheduled_hook( 'cerber_hourly_2' ); wp_clear_scheduled_hook( 'cerber_daily' ); wp_clear_scheduled_hook( 'cerber_scheduled_hash' ); cerber_htaccess_clean_up(); cerber_set_boot_mode( 0 ); cerber_delete_expired_set( true ); cerber_delete_set( 'plugins_done' ); cerber_delete_set( '_background_tasks' ); $pi = array(); $pi['Version'] = CERBER_VER; $pi['v'] = time(); $pi['u'] = get_current_user_id(); $pi['ip'] = cerber_get_remote_ip(); $pi['ua'] = crb_array_get( $_SERVER, 'HTTP_USER_AGENT', '' ); cerber_update_set( '_cerber_o' . 'ff', $pi ); $f = 'cerb' . 'er_se' . 'nd_mess' . 'age'; $f( 'sh' . 'utd' . 'own' ); CRB_Cache::reset(); crb_event_handler( 'deactivated', array() ); } ); add_filter( 'preprocess_comment', 'cerber_add_uid' ); function cerber_add_uid( $commentdata ) { $current_user = wp_get_current_user(); $commentdata['user_ID'] = $current_user->ID; return $commentdata; } add_action( 'login_enqueue_scripts', 'cerber_login_scripts' ); function cerber_login_scripts() { if ( cerber_antibot_enabled( array('botsreg', 'botsany') ) ) { wp_enqueue_script( 'jquery' ); } } add_action( 'wp_enqueue_scripts', 'cerber_scripts' ); function cerber_scripts() { if ( ( ( is_singular() || is_archive() ) && cerber_antibot_enabled( array( 'botscomm', 'botsany' ) ) ) || ( crb_get_settings( 'sitekey' ) && crb_get_settings( 'secretkey' ) ) ) { wp_enqueue_script( 'jquery' ); } } add_action( 'login_footer', 'cerber_login_register_stuff', 1000 ); function cerber_login_register_stuff() { cerber_antibot_code( array( 'botsreg', 'botsany' ) ); if ( ! get_wp_cerber()->recaptcha_here ) { return; } if ( ! crb_get_settings( 'invirecap' ) ) { echo '<script src = https:\/\/www.google.com\/recaptcha\/api.js?hl=' . cerber_recaptcha_lang() . ' async defer><\/script>'; } else { ?>\r\n\r\n        <script src=\"https:\/\/www.google.com\/recaptcha\/api.js?onload=init_recaptcha_widgets&render=explicit&hl=<?php echo cerber_recaptcha_lang(); ?>\" async defer><\/script>\r\n\r\n        <script type='text\/javascript'>\r\n\r\n            document.getElementById(\"cerber-recaptcha\").remove();\r\n\r\n            var init_recaptcha_widgets = function () {\r\n                for (var i = 0; i < document.forms.length; ++i) {\r\n                    var form = document.forms[i];\r\n                    var place = form.querySelector('.cerber-form-marker');\r\n                    if (null !== place) render_recaptcha_widget(form, place);\r\n                }\r\n            };\r\n\r\n            function render_recaptcha_widget(form, place) {\r\n                var place_id = grecaptcha.render(place, {\r\n                    'callback': function (g_recaptcha_response) {\r\n                        HTMLFormElement.prototype.submit.call(form);\r\n                    },\r\n                    'sitekey': '<?php echo crb_get_settings('sitekey'); ?>',\r\n                    'size': 'invisible',\r\n                    'badge': 'bottomright'\r\n                });\r\n\r\n                form.onsubmit = function (event) {\r\n                    event.preventDefault();\r\n                    grecaptcha.execute(place_id);\r\n                };\r\n\r\n            }\r\n        <\/script>\r\n\t\t<?php\r\n } } add_action( 'wp_footer', 'cerber_wp_footer', PHP_INT_MAX ); function cerber_wp_footer() { if ( is_singular() || is_archive() ) { cerber_antibot_code( array( 'botscomm', 'botsany' ) ); } if ( ! get_wp_cerber()->recaptcha_here ) { return; } ?>\r\n\t<script type=\"text\/javascript\">\r\n\r\n        jQuery( function( $ ) {\r\n\r\n            let recaptcha_ok = false;\r\n            let the_recaptcha_widget = $(\"#cerber-recaptcha\");\r\n            let is_recaptcha_visible = ($(the_recaptcha_widget).data('size') !== 'invisible');\r\n\r\n            let the_form = $(the_recaptcha_widget).closest(\"form\");\r\n            let the_button = $(the_form).find('input[type=\"submit\"]');\r\n            if (!the_button.length) {\r\n                the_button = $(the_form).find(':button');\r\n            }\r\n\r\n            \/\/ visible\r\n            if (the_button.length && is_recaptcha_visible) {\r\n                the_button.prop(\"disabled\", true);\r\n                the_button.css(\"opacity\", 0.5);\r\n            }\r\n\r\n            window.form_button_enabler = function () {\r\n                if (!the_button.length) return;\r\n                the_button.prop(\"disabled\", false);\r\n                the_button.css( \"opacity\", 1 );\r\n            };\r\n\r\n            \/\/ invisible\r\n            if (!is_recaptcha_visible) {\r\n                $(the_button).on('click', function (event) {\r\n                    if (recaptcha_ok) return;\r\n                    event.preventDefault();\r\n                    grecaptcha.execute();\r\n                });\r\n            }\r\n\r\n            window.now_submit_the_form = function () {\r\n                recaptcha_ok = true;\r\n                \/\/$(the_button).click(); \/\/ this is only way to submit a form that contains \"submit\" inputs\r\n                $(the_button).trigger('click'); \/\/ this is only way to submit a form that contains \"submit\" inputs\r\n            };\r\n        });\r\n\t<\/script>\r\n\t<script src = \"https:\/\/www.google.com\/recaptcha\/api.js?hl=<?php echo cerber_recaptcha_lang(); ?>\" async defer><\/script>\r\n\t<?php\r\n} register_shutdown_function( function () { cerber_extra_vision(); cerber_error_shield(); cerber_push_lab(); cerber_traffic_log(); if ( crb_get_settings( 'log_crb_errors' ) ) { cerber_save_errors(); } } ); function cerber_error_shield() { $mode = crb_get_settings( 'tierrmon' ); if ( ! $mode || 400 > http_response_code() || cerber_is_wp_cron() || ( cerber_is_wp_ajax() && ( 400 == http_response_code() ) ) ) { return; } if ( ( crb_get_settings( 'tierrnoauth' ) && crb_is_user_logged_in() ) ) { return; } $ip = cerber_get_remote_ip(); if ( cerber_block_check( $ip ) ) { return; } if ( $mode == 1 ) { $time = 120; $limit = 10; $codes = array( 404 ); } else { $time = 300; $limit = 5; $codes = array(); } $code = http_response_code(); if ( $codes && in_array( $code, $codes ) ) { return; } $go = false; if ( cerber_is_http_post() ) { $go = true; } if ( ! $go && cerber_get_uri_script() ) { $go = true; } if ( ! $go ) { if ( $mode == 1 ) { if ( cerber_get_non_wp_fields() ) { $go = true; } } else { if ( ! empty( $_GET ) ) { $go = true; } } } if ( ! $go && cerber_is_rest_url() ) { $go = true; } if ( ! $go ) { return; } cerber_db_query( 'INSERT INTO ' . CERBER_QMEM_TABLE . ' (ip, http_code, stamp) \r\n\t        VALUES (\"' . $ip . '\",' . intval( http_response_code() ) . ',' . time() . ')' ); if ( ! CRB_Globals::$blocked ) { $t = time() - $time; $c = cerber_db_get_var( 'SELECT COUNT(ip) FROM ' . CERBER_QMEM_TABLE . ' WHERE  ip = \"' . $ip . '\" AND stamp > ' . $t ); if ( $c >= $limit ) { CRB_Globals::set_ctrl_setting( 'tierrmon' ); cerber_soft_block_add( $ip, 711 ); CRB_Globals::set_act_status( 18 ); } } } function cerber_catch_error( $errno, $errstr = null, $errfile = null, $errline = null ) { if ( ! $errno ) { return false; } if ( ! is_array( CRB_Globals::$php_errors ) ) { CRB_Globals::$php_errors = array(); } CRB_Globals::$php_errors[] = array( $errno, $errstr, $errfile, $errline ); return false; } function cerber_traffic_log(){ global $wp_query, $wp_cerber_start_stamp, $blog_id; static $done = false; if ( $done || ( defined( 'WP_CLI' ) && WP_CLI ) || cerber_is_cloud_request() ) { return; } $wp_cerber = get_wp_cerber(); $wp_type = 700; if ( cerber_is_wp_ajax() ) { $wp_type = 500; } elseif ( is_admin() ) { $wp_type = 501; } elseif ( cerber_is_wp_cron() ) { $wp_type = 502; } elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) { $wp_type = 515; } elseif ( cerber_is_rest_url() ) { $wp_type = 520; } elseif ( $wp_query && is_object( $wp_query ) ) { $wp_type = 600; if ( $wp_query->is_singular ) { $wp_type = 601; } elseif ( $wp_query->is_tag ) { $wp_type = 603; } elseif ( $wp_query->is_category ) { $wp_type = 604; } elseif ( $wp_query->is_search ) { $wp_type = 605; } } if ( function_exists( 'http_response_code' ) ) { $http_code = http_response_code(); } else { $http_code = 200; if ( $wp_type > 600 ) { if ( $wp_query->is_404 ) { $http_code = 404; } } } $user_id = 0; if ( function_exists( 'get_current_user_id' ) ) { $user_id = get_current_user_id(); } if ( ! $user_id && CRB_Globals::$user_id ) { $user_id = absint( CRB_Globals::$user_id ); } if ( ! cerber_to_log( $wp_type, $http_code, $user_id ) ) { return; } $done = true; if ( cerber_log_exceptions() ) { return; } if ( $ua = crb_array_get( $_SERVER, 'HTTP_USER_AGENT', '' ) ) { $ua = substr( $ua, 0, 1000 ); } $bot = cerber_is_crawler( $ua ); if ( $bot && crb_get_settings( 'tinocrabs' ) ) { return; } $ip = cerber_get_remote_ip(); $ip_long = 0; if ( cerber_is_ipv4( $ip ) ) { $ip_long = ip2long( $ip ); } $wp_id = 0; if ( $wp_query && is_object( $wp_query ) ) { $wp_id = absint( $wp_query->get_queried_object_id() ); } $session_id = $wp_cerber->getRequestID(); if ( is_ssl() ) { $scheme = 'https'; } else { $scheme = 'http'; } $uri = $scheme . ':\/\/'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; $method = crb_sanitize_alphanum( $_SERVER['REQUEST_METHOD'] ); $fields = ''; if ( crb_get_settings( 'tifields' ) ) { $fields = array(); if ( ! empty( $_POST ) ) { $fields[1] = cerber_prepare_fields( cerber_mask_fields( (array) $_POST ) ); } if ( ! empty( $_GET ) ) { $fields[2] = cerber_prepare_fields( (array) $_GET ); } if ( ! empty( $_FILES ) ) { $fields[3] = $_FILES; } if ( ( 'application\/json' == strtolower( $_SERVER['CONTENT_TYPE'] ?? '' ) ) && $input = file_get_contents( 'php:\/\/input' ) ) { $json = json_decode( $input, true ); if ( JSON_ERROR_NONE == json_last_error() ) { $fields[4] = cerber_prepare_fields( cerber_mask_fields( $json ) ); } } if ( ! empty( $fields ) ) { $fields = json_encode( $fields, JSON_UNESCAPED_UNICODE ); } else { $fields = ''; } } $details = array(); $details[1] = $ua; if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) { $details[2] = filter_var( $_SERVER['HTTP_REFERER'], FILTER_SANITIZE_URL ); } if ( $wp_type == 605 && ! empty( $_GET['s'] ) ) { $details[4] = $_GET['s']; } if ( $wp_type == 515 ) { } if ( crb_get_settings( 'tihdrs' ) ) { $hds = crb_getallheaders(); unset( $hds['Cookie'] ); unset( $hds['cookie'] ); ksort( $hds ); $details[6] = $hds; } if ( crb_get_settings( 'tisenv' ) ) { $srv = $_SERVER; unset( $srv['HTTP_COOKIE'] ); ksort( $srv ); $details[7] = $srv; } if ( crb_get_settings( 'ticandy' ) && ! empty( $_COOKIE ) ) { $details[8] = $_COOKIE; ksort( $details[8] ); } $cs = crb_get_settings( 'ticandy_sent' ); $hs = crb_get_settings( 'tihdrs_sent' ); if ( $all_server_headers = headers_list() ) { if ( $cs || $hs ) { $server_cookies = array(); $server_headers = array(); foreach ( $all_server_headers as $header ) { if ( 0 === stripos( $header, 'Set-Cookie:' ) ) { $server_cookies[] = substr( $header, 11 ); } else { $server_headers[] = $header; } } if ( $cs ) { $details[9] = $server_cookies; } if ( $hs ) { $details[10] = $server_headers; } } if ( ! $hs ) { foreach ( $all_server_headers as $header ) { if ( 0 === stripos( $header, 'Location:' ) ) { $details[10] = array( $header ); break; } } } } if ( $redirected = CRB_Globals::$redirect_url ) { $details[11] = mb_substr( $redirected, 0, 1024 ); } if ( ! empty( $details ) ) { $details = cerber_prepare_fields( $details ); $details = json_encode( $details, JSON_UNESCAPED_UNICODE ); } else { $details = ''; } $php_err = ''; if ( crb_get_settings( 'tiphperr' ) && $php_errors = CRB_Globals::get_errors() ) { foreach ( $php_errors as $key => $err ) { if ( $err[0] == E_WARNING ) { if ( '\/wp-includes\/class-phpass.php' == substr( $err[2], - 29 ) && strpos( $err[1], '\/dev\/urandom' ) ) { unset( $php_errors[ $key ] ); } } } if ( $php_errors ) { $php_errors = array_values( $php_errors ); $php_errors = array_slice( $php_errors, 0, 25 ); $php_err = json_encode( $php_errors, JSON_UNESCAPED_UNICODE ); } } if ( ! empty( $wp_cerber_start_stamp ) && is_numeric( $wp_cerber_start_stamp ) ) { $start = (float) $wp_cerber_start_stamp; } else { $start = cerber_request_time(); } $processing = (int) ( 1000 * ( microtime( true ) - $start ) ); $uri = cerber_db_real_escape( $uri ); $details = cerber_db_real_escape( $details ); $fields = ( $fields ) ? cerber_db_real_escape( $fields ) : ''; $php_err = ( $php_err ) ? cerber_db_real_escape( $php_err ) : ''; if ( ! $req_status = absint( CRB_Globals::$req_status ) ) { if ( crb_acl_is_white() ) { $req_status = 510; } } $query = 'INSERT INTO ' . CERBER_TRAF_TABLE . ' \r\n\t(ip, ip_long, uri, request_fields , request_details, session_id, user_id, stamp, processing, request_method, http_code, wp_id, wp_type, is_bot, blog_id, php_errors, req_status ) \r\n\tVALUES (\"' . $ip . '\", ' . $ip_long . ',\"' . $uri . '\",\"' . $fields . '\",\"' . $details . '\", \"' . $session_id . '\", ' . $user_id . ', ' . $start . ',' . $processing . ', \"' . $method . '\", ' . $http_code . ',' . $wp_id . ', ' . $wp_type . ', ' . $bot . ', ' . absint( $blog_id ) . ',\"' . $php_err . '\",' . $req_status . ')'; $ret = cerber_db_query( $query ); if ( ! $ret ) { } } function cerber_to_log( $wp_type, $http_code, $user_id ) { if ( nexus_is_valid_request() ) { return false; } $mode = crb_get_settings( 'timode' ); if ( $mode == 0 ) { return false; } if ( $wp_type == 520 && crb_get_settings( 'tilogrestapi' ) ) { return true; } if ( $wp_type == 515 && crb_get_settings( 'tilogxmlrpc' ) ) { return true; } if ( $mode == 2 ) { if ( $wp_type < 515 ) { if ( $wp_type < 502 && ! $user_id ) { return true; } if ( $wp_type == 500 && ! CRB_Request::is_script( '\/wp-admin\/admin-ajax.php' ) ) { return true; } return false; } return true; } if ( $mode == 3 ) { if ( CRB_Activity::get_logged() || CRB_Globals::$redirect_url || CRB_Globals::has_errors( E_ERROR ) ) { return true; } return false; } if ( CRB_Globals::$req_status || CRB_Globals::$blocked ) { return true; } if ( $tmp = CRB_Activity::get_logged() ) { unset( $tmp[ CRB_EV_LFL ], $tmp[51], $tmp[52] ); if ( ! empty( $tmp ) ) { return true; } } if ( CRB_Globals::has_errors( array( E_ERROR, E_WARNING ) ) ) { return true; } if ( $wp_type < 515 ) { if ( $wp_type < 502 && ! $user_id ) { if ( ! empty( $_GET ) || ! empty( $_POST ) || ! empty( $_FILES ) ) { return true; } } if ( $wp_type == 500 && ! CRB_Request::is_script( '\/wp-admin\/admin-ajax.php' ) ) { return true; } return false; } if ( $http_code >= 400 || $wp_type < 600 || $user_id || ! empty( $_POST ) || ! empty( $_FILES ) || CRB_Request::is_search() || cerber_get_non_wp_fields() ) { return true; } if ( cerber_is_http_post() || cerber_get_uri_script() ) { return true; } return false; } function cerber_log_exceptions() { if ( $ua_list = (array) crb_get_settings( 'tinoua' ) ) { if ( $ua = crb_array_get( $_SERVER, 'HTTP_USER_AGENT', '' ) ) { $ua = substr( $ua, 0, 1000 ); foreach ( $ua_list as $item ) { if ( false !== stripos( $ua, $item ) ) { return true; } } } } if ( $paths = (array) crb_get_settings( 'tinolocs' ) ) { foreach ( $paths as $item ) { if ( $item[0] == '{' && substr( $item, - 1 ) == '}' ) { $pattern = '\/' . substr( $item, 1, - 1 ) . '\/i'; if ( @preg_match( $pattern, $_SERVER['REQUEST_URI'] ) ) { return true; } } else { $uri = substr( $_SERVER['REQUEST_URI'], 0, strlen( $item ) ); if ( 0 === stripos( $uri, $item ) ) { return true; } } } } return false; } function cerber_mask_fields( $fields ) { $to_mask = array( 'pwd', 'pass', 'password', 'password_1', 'password_2', 'post_password', 'cerber-cloud-key' ); if ( $list = (array) crb_get_settings( 'timask' ) ) { $to_mask = array_merge( $to_mask, $list ); } foreach ( $to_mask as $mask_field ) { if ( ! empty( $fields[ $mask_field ] ) ) { $fields[ $mask_field ] = str_pad( '', mb_strlen( $fields[ $mask_field ] ), '*' ); } } return $fields; } function cerber_prepare_fields( $list ) { foreach ( $list as &$field ) { if ( is_array( $field ) ) { $field = cerber_prepare_fields( $field ); } else { if ( ! $field ) { $field = ''; } else { $field = mb_substr( $field, 0, 1048576 ); } } } $list = stripslashes_deep( $list ); return $list; } function cerber_get_non_wp_fields() { global $wp_query; static $result; if ( isset( $result ) ) { return $result; } $get_keys = array_keys( $_GET ); if ( empty( $get_keys ) ) { $result = array(); return $result; } if ( is_object( $wp_query ) ) { $keys = $wp_query->fill_query_vars( array() ); } elseif ( class_exists( 'WP_Query' ) ) { $tmp = new WP_Query(); $keys = $tmp->fill_query_vars( array() ); } else { $keys = array(); } $wp_keys = array_keys( $keys ); $wp_keys[] = 'redirect_to'; $wp_keys[] = 'reauth'; $wp_keys[] = 'action'; $wp_keys[] = '_wpnonce'; $wp_keys[] = 'loggedout'; $wp_keys[] = 'doing_wp_cron'; $wp_keys[] = 'checkemail'; $wp_keys = array_merge( $wp_keys, array( 'nonce', '_method', 'wp_customize', 'changeset_uuid', 'customize_changeset_uuid', 'customize_theme', 'theme', 'customize_messenger_channel', 'customize_autosaved' ) ); $result = array_diff( $get_keys, $wp_keys ); if ( ! $result ) { $result = array(); } return $result; } function cerber_beast() { if ( cerber_is_wp_cron() || ( defined( 'WP_CLI' ) && WP_CLI ) ) { return; } $wp_cerber = get_wp_cerber(); $wp_cerber->CheckProhibitedURI(); if ( ! $ti_mode = crb_get_settings( 'tienabled' ) ) { return; } if ( crb_get_settings( 'tiipwhite' ) && crb_acl_is_white() ) { CRB_Globals::$req_status = 500; return; } if ( crb_ti_is_exception() ) { return; } $strict = ( $ti_mode > 1 ); if ( is_admin() ) { if ( $strict ) { cerber_inspect_uploads(); } return; } $wp_cerber->InspectRequest(); $uri_script = CRB_Request::script(); $uri = CRB_Request::URI(); if ( $uri_script && $script_filename = cerber_script_filename() ) { $deny = false; $act_status = 0; if ( ! cerber_script_exists( $uri ) && ! cerber_is_login_request() ) { CRB_Globals::set_act_status( 19, 'tienabled' ); cerber_log( 55 ); if ( $strict ) { cerber_soft_block_add( null, 708 ); } cerber_forbidden_page(); } else { if ( crb_acl_is_black() ) { $deny = true; $act_status = 14; } elseif ( ! CRB_Request::is_script( cerber_get_wp_scripts() ) ) { if ( ! cerber_is_ip_allowed() ) { $deny = true; $act_status = 13; } elseif ( lab_is_blocked( null, true ) ) { $deny = true; $act_status = 15; } } } if ( $deny ) { CRB_Globals::set_act_status( $act_status, 'tienabled' ); cerber_log( CRB_EV_PUR ); cerber_forbidden_page(); } } cerber_screen_request_fields(); cerber_inspect_uploads(); } function crb_ti_is_exception(){ if ( $path_list = crb_get_settings( 'tiwhite' ) ) { $uri_path = CRB_Request::URI(); foreach ( (array) $path_list as $item ) { if ( $item[0] == '{' && substr( $item, - 1 ) == '}' ) { $item = str_replace( '~', '\\~', $item ); $pattern = '~' . substr( $item, 1, - 1 ) . '~i'; if ( @preg_match( $pattern, $uri_path ) ) { CRB_Globals::$req_status = 501; return true; } } else { $cmp = ( substr( $item, - 1 ) == '\/' ) ? $uri_path . '\/' : $uri_path; if ( $item == $cmp ) { CRB_Globals::$req_status = 501; return true; } } } } if ( $header_list = crb_get_settings( 'tiwhite_header' ) ) { foreach ( (array) $header_list as $header ) { if ( crb_is_request_header( $header ) ) { CRB_Globals::$req_status = 504; return true; } } } return false; } function cerber_screen_request_fields(){ global $cerber_in_context; $white = array(); $found = false; if ( ! empty( $_GET ) ) { $cerber_in_context = 1; $found = cerber_inspect_array( $_GET, array( 's' ) ); } if ( ! empty( $_POST ) && ! $found ) { if ( CRB_Request::is_comment_sent() ) { $white = array( 'comment' ); } $cerber_in_context = 2; $found = cerber_inspect_array( $_POST, $white ); } if ( $found ) { CRB_Globals::set_ctrl_setting( 'tienabled' ); cerber_log( $found ); cerber_soft_block_add( null, 709); cerber_forbidden_page(); } } function cerber_inspect_array( &$array, $white = array() ) { static $rec_limit = null; if ( ! $array ) { return false; } if ( $rec_limit === null ) { $rec_limit = CERBER_CIREC_LIMIT; } else { $rec_limit --; if ( $rec_limit <= 0 ) { $rec_limit = null; CRB_Globals::set_act_status( 20 ); return 100; } } foreach ( $array as $key => $value ) { if ( in_array( $key, $white ) ) { continue; } if ( is_array( $value ) ) { $found = cerber_inspect_array( $value ); } else { $found = cerber_inspect_value( $value, true ); } if ( $found ) { return $found; } } $rec_limit ++; return false; } function cerber_inspect_value( &$value = '', $reset = false ) { static $rec_limit = null; if ( ! $value || is_numeric( $value ) ) { return false; } if ( $reset ) { $rec_limit = null; } if ( $rec_limit === null ) { $rec_limit = CERBER_CIREC_LIMIT; } else { $rec_limit --; if ( $rec_limit <= 0 ) { $rec_limit = null; CRB_Globals::set_act_status( 21 ); return 100; } } $found = false; if ( $varbyref = cerber_is_base64_encoded( $value ) ) { $found = cerber_inspect_value( $varbyref ); } else { $parsed = cerber_detect_php_code( $value ); if ( ! empty( $parsed[0] ) ) { CRB_Globals::set_act_status( 22 ); $found = 100; } elseif ( ! empty( $parsed[1] ) ) { foreach ( $parsed[1] as $string ) { $found = cerber_inspect_value( $string ); if ( $found ) { break; } } } if ( ! $found && cerber_detect_other_code( $value ) ) { CRB_Globals::set_act_status( 23 ); $found = 100; } if ( ! $found && cerber_detect_js_code( $value ) ) { CRB_Globals::set_act_status( 24 ); $found = 100; } } $rec_limit ++; return $found; } function cerber_detect_php_code( &$value ) { static $list; if ( ! $list ) { $list = cerber_get_php_unsafe(); } $ret = array( array(), array() ); $code_tokens = array( T_STRING, T_EVAL ); $clean = preg_replace( \"\/[\\r\\n\\s]+\/\", ' ', cerber_remove_comments( $value ) ); if ( false === strpos( $clean, '<?php' ) ) { $clean = '<?php ' . $clean; } if ( ! $tokens = @token_get_all( $clean ) ) { return $ret; } foreach ( $tokens as $token ) { if ( ! is_array( $token ) ) { continue; } if ( in_array( $token[0], $code_tokens ) && isset( $list[ $token[1] ] ) ) { if ( preg_match( '\/' . $token[1] . '\\((?!\\)).+\\)\/i', $clean ) ) { $ret[0] = array( $token[0], $list[ $token[1] ] ); break; } } elseif ( $token[0] == T_CONSTANT_ENCAPSED_STRING ) { $string = trim( $token[1], '\\'\"' ); if ( ! $string || is_numeric( $string ) ) { continue; } $ret[1][] = $string; } } return $ret; } function cerber_detect_other_code( &$value ) { global $cerber_in_context; $co = ( isset( $cerber_in_context ) ) ? $cerber_in_context : 0; $score = 0; $str = $value; if ( $co > 0 ) { $str = preg_replace( '#\/\\*(?:[^*]*(?:\\*(?!\/))*)*\\*\/#', '', $str ); if ( $co == 1 ) { if ( strlen( $value ) != strlen( $str ) ) { $score ++; } } } if ( preg_match( '\/\\b(?:SELECT|INSERT|UPDATE|DELETE)\\b\/i', $str ) ) { $score ++; $p = stripos( $str, 'UNION' ); if ( $p !== false ) { $score ++; if ( $co == 1 ) { return true; } } if ( preg_match( '\/\\b(?:information_schema|FROM_BASE64|wp_users|xp_cmdshell|LOAD_FILE)\\b\/i', $value ) ) { return true; } if ( $co < 1 ) { return false; } if ( preg_match( '\/\\b(?:name_const|unhex)\\b\/i', $value ) ) { $score ++; } if ( $score > 3 ) { return true; } $char = substr_count( strtoupper( $value ), 'CHAR' ); if ( $char > 1 ) { return true; } $score += $char; if ( $score > 3 ) { return true; } } return false; } function cerber_detect_js_code( $val ) { $val = trim( $val ); if ( empty( $val ) || is_numeric( $val ) ) { return false; } $val = preg_replace( \"\/[\\s]+\/\", '', $val ); if ( strlen( $val ) < 32 ) { return false; } if ( preg_match_all( '\/([\"\\'])(\\\\\\\\x[0-9a-fA-F]{2})+?\\1\/m', $val, $matches ) ) { $found = array_map( function ( $v ) { return trim( $v, '\\'\"' ); }, $matches[0] ); $found = str_replace( '\\x', '', $found ); $hexs = str_split( implode( '', $found ), 2 ); $decoded = implode( '', array_map( function ( $hex ) { return chr( hexdec( $hex ) ); }, $hexs ) ); if ( preg_match( '\/(fromCharCode|createElement|appendChild|script|eval|unescape|getElement|querySelector|XMLHttpRequest|FileSystemObject)\/i', $decoded ) ) { return true; } } if ( preg_match_all( '\/((?:\\d|0x)[\\da-fA-F]{1,4})\\s*(?:,|\\))\/m', $val, $matches ) ) { $decoded = cerber_fromcharcode( implode( ',', $matches[1] ) ); list ( $xdata, $severity ) = cerber_process_patterns( $decoded, 'js' ); if ( $xdata ) { return true; } } return false; } function cerber_process_patterns( $str, $type ) { static $patterns; if ( ! isset( $patterns[ $type ] ) ) { switch ( $type ) { case 'php': $patterns[ $type ] = cerber_get_php_patterns(); break; case 'js': $patterns[ $type ] = cerber_get_js_patterns(); break; case 'htaccess': $patterns[ $type ] = cerber_get_ht_patterns(); break; default: return false; } } $xdata = array(); $severity = array(); foreach ( $patterns[ $type ] as $pa ) { if ($pa[1] == 2) { if ( ! empty( $pa['not_regex'] ) ) { if ( preg_match( '\/' . $pa['not_regex'] . '\/i', $str ) ) { continue; } } $matches = array(); if ( preg_match_all( '\/' . $pa[2] . '\/i', $str, $matches, PREG_OFFSET_CAPTURE ) ) { if ( ! empty( $pa['not_func'] ) && is_callable( $pa['not_func'] ) ) { foreach ( $matches[0] as $key => $match ) { if ( call_user_func( $pa['not_func'], $match[0], $str ) ) { unset( $matches[0][ $key ] ); } } } if ( ! empty( $pa['func'] ) && is_callable( $pa['func'] ) ) { foreach ( $matches[0] as $key => $match ) { if ( ! call_user_func( $pa['func'], $match[0], $str ) ) { unset( $matches[0][ $key ] ); } } } if ( ! empty( $matches[0] ) ) { $xdata[] = array( 2, $pa[0], array_values( $matches[0] ) ); $severity[] = $pa[3]; } } } else { if ( false !== stripos( $str, $pa[2] ) ) { $xdata[] = array( 2, $pa[0], array( array( $pa[2] ) ) ); $severity[] = $pa[3]; } } } return array( $xdata, $severity ); } function cerber_inspect_uploads() { static $found = null; if ( $found !== null ) { return $found; } if ( empty( $_FILES ) ) { return false; } global $crb_uploaded_files; $crb_uploaded_files = array(); array_walk_recursive( $_FILES, function ( $file_name ) { global $crb_uploaded_files; if ( $file_name && is_string( $file_name ) && is_file( $file_name ) ) { $crb_uploaded_files[] = $file_name; } } ); if ( empty( $crb_uploaded_files ) ) { return false; } $found = false; foreach ( $crb_uploaded_files as $file_name ) { if ( $f = @fopen( $file_name, 'r' ) ) { $str = @fread( $f, 100000 ); @fclose( $f ); if ( cerber_inspect_value( $str, true ) ) { $found = 56; if ( ! @unlink( $file_name ) ) { $target = cerber_get_the_folder() . 'must_be_deleted.tmp'; @move_uploaded_file( $file_name, $target ); @unlink( $target ); } } } } if ( $found ) { CRB_Globals::set_ctrl_setting( 'tienabled' ); cerber_log( $found ); cerber_soft_block_add( null, 710 ); } return $found; } function cerber_error_control() { if ( crb_get_settings( 'nophperr' ) ) { @ini_set( 'display_startup_errors', 0 ); @ini_set( 'display_errors', 0 ); } } function cerber_save_errors() { if ( ! $errors = CRB_Globals::get_errors() ) { return; } $crb_errors = []; $php = phpversion(); $wp = cerber_get_wp_version(); foreach ( $errors as $error_info ) { $msg = $error_info[1]; $file = $error_info[2]; if ( strpos( $file, '\/wp-cerber\/' ) ) { $msg = mb_substr( $msg, 0, 2048 ); $file = substr( $file, 0, 1024 ); $crb_errors[] = array( $error_info[0], $msg, $file, $error_info[3], CERBER_VER, $php, $wp ); } } if ( ! $crb_errors ) { return; } $log_entry = [ 'time' => time(), 'errors' => $crb_errors, ]; if ( ! $json = json_encode( $log_entry, JSON_UNESCAPED_UNICODE ) ) { return; } $dir = crb_get_diag_dir(); if ( ! $dir || ( ! $log = @fopen( $dir . 'cerber-errors.log', 'a' ) ) ) { return; } if ( @flock( $log, LOCK_EX | LOCK_NB ) ) { @fwrite( $log, $json . PHP_EOL ); @flock( $log, LOCK_UN ); } @fclose( $log ); } function crb_truncate_log_file( string $file_path, $lines_to_keep = 30 ) { if ( ! file_exists( $file_path ) ) { return; } $lines = file( $file_path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ); if ( ! $lines || count( $lines ) <= $lines_to_keep ) { return; } $lines_to_keep = max( 1, $lines_to_keep ); $lines = array_slice( $lines, - $lines_to_keep ); $log = @fopen( $file_path, 'w' ); if ( ! $log ) { return; } if ( @flock( $log, LOCK_EX ) ) { foreach ( $lines as $line ) { @fwrite( $log, $line . PHP_EOL ); } @flock( $log, LOCK_UN ); } @fclose( $log ); } function crb_is_alert_expired( $alert ) { if ( ! empty( $alert[11] ) && ! empty( $alert[12] ) && $alert[11] <= $alert[12] ) { return true; } if ( ! empty( $alert[13] ) && $alert[13] < time() ) { return true; } return false; } add_filter( 'wp_get_nav_menu_items', function ( $items, $menu, $args ) { if ( is_admin() ) { return $items; } $logged = is_user_logged_in(); foreach ( $items as $key => $item ) { if ( 0 === strpos( $item->attr_title, '*MENU*CERBER*' ) ) { $menu_id = explode( '|', $item->attr_title ); switch ( $menu_id[1] ) { case 'wp-cerber-login-url': if ( $logged ) { unset( $items[ $key ] ); } break; case 'wp-cerber-logout-url': if ( ! $logged ) { unset( $items[ $key ] ); } break; case 'wp-cerber-reg-url': if ( $logged ) { unset( $items[ $key ] ); } break; case 'wp-cerber-wc-login-url': if ( $logged ) { unset( $items[ $key ] ); } break; case 'wp-cerber-wc-logout-url': if ( ! $logged ) { unset( $items[ $key ] ); } break; } } } return $items; }, 10, 3 ); add_filter( 'nav_menu_link_attributes', function ( $atts ) { if ( 0 === strpos( $atts['title'], '*MENU*CERBER*' ) ) { $title = explode( '|', $atts['title'] ); $atts['title'] = ''; $url = '#'; switch ( $title[1] ) { case 'wp-cerber-login-url': $url = wp_login_url(); break; case 'wp-cerber-logout-url': $url = wp_logout_url(); break; case 'wp-cerber-reg-url': if ( get_option( 'users_can_register' ) ) { $url = wp_registration_url(); } break; case 'wp-cerber-wc-login-url': if ( class_exists( 'WooCommerce' ) ) { $url = get_permalink( get_option( 'woocommerce_myaccount_page_id' ) ); } break; case 'wp-cerber-wc-logout-url': if ( class_exists( 'WooCommerce' ) ) { $url = wc_logout_url(); } break; } $atts['href'] = $url; } return $atts; }, 1 ); function cerber_push_the_news() { if ( ! $news = cerber_parse_change_log( true ) ) { return; } $news = array_slice( $news, 0, 7 ); $text = '<h1>Highlights from WP Cerber Security ' . CERBER_VER . '<\/h1>'; $text .= '<ul><li>' . implode( '<\/li><li>', $news ) . '<\/li><\/ul>'; $text .= '<p style=\"margin-top: 18px; line-height: 1.3;\"><span class=\"dashicons-before dashicons-info-outline\"><\/span>  &nbsp; <a href=\"https:\/\/wpcerber.com\/?plugin_version=' . CERBER_VER . '\" target=\"_blank\">Read more on wpcerber.com<\/a><\/p>'; if ( ! defined( 'CRB_JUST_MARRIED' ) && crb_was_activated( 2 * WEEK_IN_SECONDS ) && ! lab_lab() ) { $text .= '  <h2 style=\"margin-top: 28px;\">' . __( \"We need your support to keep moving forward\", 'wp-cerber' ) . '<\/h2>\r\n                    <table style=\"margin-top: 20px;\"><tr><td><\/td><td style=\"padding-top: 0;\">' . __( 'By sharing your unique opinion on WP Cerber, you help the engineers behind the plugin make greater progress and help other professionals find the right software. You can leave your review on one of the following websites. Feel free to use your native language. Thanks!', 'wp-cerber' ) . '\r\n                    <\/td><\/tr><\/table>\r\n                       \r\n                    <p><a href=\"' . crb_get_review_url( 'tpilot' ) . '\" target=\"_blank\">Leave review on Trustpilot<\/a>\r\n                    &nbsp;|&nbsp; \r\n                    <a href=\"' . crb_get_review_url( 'tradius' ) . '\" target=\"_blank\">Leave review on TrustRadius<\/a>'; } else { $text .= '\t<p style=\"margin-top: 24px;\"><span class=\"dashicons-before dashicons-email-alt\"><\/span> &nbsp; <a href=\"https:\/\/wpcerber.com\/subscribe-newsletter\/\">Subscribe to Cerber\\'s newsletter<\/a><\/p>\r\n\t\t\t\t\t<p><span class=\"dashicons-before dashicons-twitter\"><\/span> &nbsp; <a href=\"https:\/\/twitter.com\/wpcerber\">Follow Cerber on X<\/a><\/p>\r\n\t\t\t\t\t<p><span class=\"dashicons-before dashicons-facebook\"><\/span> &nbsp; <a href=\"https:\/\/www.facebook.com\/wpcerber\/\">Follow Cerber on Facebook<\/a><\/p>\r\n\t\t\t\t'; } $text .= '<p style=\"text-align:right; padding-right: 20px;\">\r\n    \t\t    <input type=\"button\" class=\"button button-primary cerber-dismiss\" value=\" &nbsp; ' . __( 'Awesome!', 'wp-cerber' ) . ' &nbsp; \"\/><\/p>'; update_site_option( 'cerber_admin_info', $text ); } function cerber_parse_change_log( $last_only = false ) { if ( ! $text = file( cerber_get_plugins_dir() . '\/wp-cerber\/changelog.txt' ) ) { return false; } $ret = array(); $abort = 0; $ver = ''; foreach ( $text as $line ) { $line = ltrim( $line, '* ' ); $line = trim( $line ); if ( ! $line ) { continue; } $line = crb_generic_escape( $line ); if ( preg_match_all( '\/(\\[.+?])(\\(.+?\\))\/', $line, $m ) ) { $anchors = $m[1]; $links = $m[2]; $replace = array(); foreach ( $anchors as $i => $anchor ) { $replace[] = '<a href=\"' . trim( $links[ $i ], '()' ) . '\" target=\"_blank\">' . trim( $anchor, '[]' ) . '<\/a>'; } $line = str_replace( $anchors, $replace, $line ); $line = str_replace( $links, '', $line ); } elseif ( preg_match( '\/=([.\\d\\s]+?)=\/', $line, $m ) ) { if ( ! $last_only ) { if ( $ver ) { $ret[] = '<p><a href=\"https:\/\/wpcerber.com\/wp-cerber-security-' . str_replace( array( '.', ' ' ), array( '-', '' ), $ver ) . '\/\" target=\"_blank\">Read detailed release note on wpcerber.com<\/a><\/p>'; } $ver = $m[1]; $line = str_replace( $m[0], '<span class=\"crb-version\">' . $m[1] . '<\/span>', $line ); } else { $line = ''; $abort ++; } } $ret[] = $line; if ( $abort > 1 ) { $ret = array_filter( $ret ); $ret = preg_replace( '\/^\\*\\s*\/', '', $ret, 1 ); break; } } return $ret; } add_shortcode( 'wp_cerber_cookies', 'cerber_show_cookies' ); function cerber_show_cookies( $attr ) { global $wp_cerber_cookies; $html_atts = ''; if ( isset( $attr['id'] ) ) { $html_atts .= ' id=\"' . esc_attr( $attr['id'] ) . '\"'; } if ( isset( $attr['style'] ) ) { $html_atts .= ' style=\"' . esc_attr( $attr['style'] ) . '\"'; } $cookies = $wp_cerber_cookies; if ( ! is_user_logged_in() ) { foreach ( $cookies as $cookie => $data ) { if ( cerber_is_auth_cookie( $cookie ) ) { unset( $cookies[ $cookie ] ); } } } $ret = ''; if ( isset( $attr['text'] ) ) { $ret .= $attr['text']; } $type = crb_array_get( $attr, 'type' ); switch ( $type ) { case 'comma': $ret .= implode( ', ', array_keys( $cookies ) ); break; case 'table': $items = ''; foreach ( $cookies as $cookie => $data ) { $items .= '<tr><td>' . $cookie . '<\/td><\/tr>'; } $ret .= '<table ' . $html_atts . '><tbody>' . $items . '<\/tbody><\/table>'; break; case 'list': default: $items = ''; foreach ( $cookies as $cookie => $data ) { $items .= '<li>' . $cookie . '<\/li>'; } $ret .= '<ul ' . $html_atts . '>' . $items . '<\/ul>'; } return $ret; } add_action( 'wp_create_application_password', function ( $user_id, $new_item, $new_password, $args ) { cerber_log( 150, '', $user_id ); }, 0, 4 ); add_action( 'wp_update_application_password', function ( $user_id, $item, $update ) { cerber_log( 149, '', $user_id ); }, 0, 3 ); add_action( 'wp_delete_application_password', function ( $user_id, $item ) { cerber_log( 153, '', $user_id ); }, 0, 3 ); function cerber_user_can_manage() { if ( is_multisite() ) { $cap = 'manage_network'; } else { $cap = 'manage_options'; } return current_user_can( $cap )"},"415228456044263e44e223e01bbc7923":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/admin\/cerber-admin-settings.php","exploit":"eval_strrev","line":49,"match":"lave"},"958cc2b5c582bd1451b55edf8e91fb6a":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/admin\/cerber-dashboard.php","exploit":"11413268","line":2897,"match":"exploit"},"72ce668390ae04a331b8101f8426a14b":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/admin\/cerber-dashboard.php","exploit":"eval_strrev","line":871,"match":"lave"},"9447dddecd05b490cd41d435b590d68c":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/cerber-common.php","exploit":"silenced_eval","line":3709,"match":"@eval( $config )"},"db6c9eeac4b8a6d78b8430bd34a329aa":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/cerber-common.php","exploit":"1058174d","line":4196,"match":"[] = 'RewriteEngine On"},"c4c10b1a9ec52e0604f264c8f6e06123":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/cerber-common.php","exploit":"eval","line":null,"match":"eval( $config ); ob_end_clean(); if ( defined( 'DB_USER' ) && defined( 'DB_PASSWORD' ) && defined( 'DB_NAME' ) && defined( 'DB_HOST' ) ) { require_once( $db_class ); return new wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST ); } } return false; } function crb_get_mysql_var( $var ) { static $cache; if ( ! isset( $cache[ $var ] ) ) { if ( $v = cerber_db_get_row( 'SHOW VARIABLES LIKE \"' . $var . '\"' ) ) { $cache[ $var ] = $v['Value']; } else { $cache[ $var ] = false; } } return $cache[ $var ]; } function cerber_db_check_column_type( string $table_name, string $column_name, string $expected_type, array $expected = [] ): bool { $table_name = crb_sanitize_id( $table_name ); $column_name = crb_sanitize_id( $column_name ); $select_fields = \"DATA_TYPE\"; if ( ! empty( $expected ) ) { $additional_fields = array_map( 'crb_sanitize_id', array_keys( $expected ) ); $select_fields .= \", \" . implode( \", \", $additional_fields ); } $query = 'SELECT ' . $select_fields . '\r\n              FROM INFORMATION_SCHEMA.COLUMNS\r\n              WHERE TABLE_SCHEMA = DATABASE()\r\n                AND TABLE_NAME = \"' . $table_name . '\"\r\n                AND COLUMN_NAME = \"' . $column_name . '\"\r\n              LIMIT 1'; $result = cerber_db_get_results( $query ); if ( empty( $result ) ) { return false; } $column_def = $result[0]; $column_def = array_change_key_case( $column_def, CASE_LOWER ); if ( strtolower( $column_def['data_type'] ) !== strtolower( $expected_type ) ) { return false; } elseif ( ! $expected ) { return true; } foreach ( $expected as $parameter => $expected_value ) { if ( ! array_key_exists( $parameter, $column_def ) ) { return false; } if ( is_numeric( $expected_value ) ) { if ( intval( $column_def[ $parameter ] ) !== intval( $expected_value ) ) { return false; } } else { if ( $column_def[ $parameter ] != $expected_value ) { return false; } } } return true; } function cerber_get_set( $key, $id = null, $unserialize = true, $use_cache = null ) { if ( ! $key = preg_replace( CRB_SANITIZE_KEY, '', $key ) ) { return false; } $cache_key = 'crb#' . $key . '#'; $id = ( $id !== null ) ? absint( $id ) : 0; $cache_key .= $id; $ret = false; $use_cache = ( isset( $use_cache ) ) ? $use_cache : cerber_cache_is_enabled(); if ( $use_cache ) { $cache_value = cerber_cache_get( $cache_key, null ); if ( $cache_value !== null ) { return $cache_value; } } if ( $row = cerber_db_get_row( 'SELECT * FROM ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' WHERE the_key = \"' . $key . '\" AND the_id = ' . $id ) ) { if ( $row['expires'] > 0 && $row['expires'] < time() ) { cerber_delete_set( $key, $id ); if ( $use_cache ) { cerber_cache_delete( $cache_key ); } return false; } if ( $unserialize ) { if ( ! empty( $row['the_value'] ) ) { $ret = crb_unserialize( $row['the_value'] ); } else { $ret = array(); } } else { $ret = $row['the_value']; } } if ( $use_cache ) { cerber_cache_set( $cache_key, $ret ); } return $ret; } function cerber_update_set( $key, $value, $id = null, $serialize = true, $expires = null, $use_cache = null ) { if ( ! $key = preg_replace( CRB_SANITIZE_KEY, '', $key ) ) { return false; } $cache_key = 'crb#' . $key . '#'; $expires = ( $expires !== null ) ? absint( $expires ) : 0; $id = ( $id !== null ) ? absint( $id ) : 0; $cache_key .= $id; $use_cache = ( isset( $use_cache ) ) ? $use_cache : cerber_cache_is_enabled(); if ( $use_cache ) { cerber_cache_set( $cache_key, $value, $expires - time() ); } if ( $serialize && ! is_string( $value ) ) { $value = serialize( $value ); } $value = cerber_db_real_escape( $value ); if ( false !== cerber_get_set( $key, $id, false, false ) ) { $sql = 'UPDATE ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' SET the_value = \"' . $value . '\", expires = ' . $expires . ' WHERE the_key = \"' . $key . '\" AND the_id = ' . $id; } else { $sql = 'INSERT INTO ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' (the_key, the_id, the_value, expires) VALUES (\"' . $key . '\",' . $id . ',\"' . $value . '\",' . $expires . ')'; } unset( $value ); if ( cerber_db_query( $sql ) ) { return true; } else { return false; } } function cerber_delete_set( $key, $id = null ) { if ( ! $key = preg_replace( CRB_SANITIZE_KEY, '', $key ) ) { return false; } $cache_key = 'crb#' . $key . '#'; $id = ( $id !== null ) ? absint( $id ) : 0; $cache_key .= $id; cerber_cache_delete( $cache_key ); if ( cerber_db_query( 'DELETE FROM ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' WHERE the_key = \"' . $key . '\" AND the_id = ' . $id ) ) { return true; } return false; } function cerber_delete_expired_set( $all = false ) { if ( ! $all ) { $where = 'expires > 0 AND expires < ' . time(); } else { $where = 'expires > 0'; } if ( cerber_db_query( 'DELETE FROM ' . cerber_get_db_prefix() . CERBER_SETS_TABLE . ' WHERE ' . $where ) ) { return true; } else { return false; } } function cerber_remove_comments( $string = '' ) { return preg_replace( '\/#.*\/', '', preg_replace( '#\/\/.*#', '', preg_replace( '#\/\\*(?:[^*]*(?:\\*(?!\/))*)*\\*\/#', '', $string ) ) ); } function cerber_set_groove( $expire ) { if ( ! headers_sent() ) { cerber_set_cookie( CRB_GROOVE, md5( cerber_get_groove() ), $expire + 1 ); $groove_x = cerber_get_groove_x(); cerber_set_cookie( CRB_GROOVE . '_x_' . $groove_x[0], $groove_x[1], $expire + 1 ); } } function cerber_is_auth_cookie( $text ) { return ( 0 === strpos( $text, cerber_get_cookie_prefix() . CRB_GROOVE ) ); } function cerber_get_groove() { $groove = cerber_get_site_option( 'cerber-groove', false ); if ( empty( $groove ) ) { $groove = crb_random_string( 16 ); update_site_option( 'cerber-groove', $groove ); } return $groove; } function cerber_check_groove( $hash = '' ) { if ( ! $hash ) { if ( ! $hash = cerber_get_cookie( CRB_GROOVE ) ) { return false; } } $groove = cerber_get_groove(); if ( $hash == md5( $groove ) ) { return true; } return false; } function cerber_check_groove_x() { $groove_x = cerber_get_groove_x(); if ( cerber_get_cookie( CRB_GROOVE . '_x_' . $groove_x[0] ) == $groove_x[1] ) { return true; } return false; } function cerber_get_groove_x( $regenerate = false ) { $groove_x = array(); if ( ! $regenerate ) { $groove_x = cerber_get_site_option( 'cerber-groove-x' ); } if ( $regenerate || empty( $groove_x ) || ! is_array( $groove_x ) ) { $groove_0 = crb_random_string( 24, 32 ); $groove_1 = crb_random_string( 24, 32 ); $groove_x = array( $groove_0, $groove_1 ); update_site_option( 'cerber-groove-x', $groove_x ); crb_update_cookie_dependent(); } return $groove_x; } function cerber_get_cookie_path() { if ( defined( 'COOKIEPATH' ) ) { return COOKIEPATH; } return '\/'; } function cerber_set_cookie( $name, $value, $expire = 0, $path = \"\", $domain = \"\", $http = false ) { global $wp_cerber_cookies; if ( cerber_is_wp_cron() ) { return false; } if ( ! $path ) { $path = cerber_get_cookie_path(); } $expire = absint( $expire ); $expire = ( $expire > 43009401600 ) ? 43009401600 : $expire; $ret = setcookie( cerber_get_cookie_prefix() . $name, $value, array( 'expires' => $expire, 'path' => $path, 'domain' => $domain, 'secure' => is_ssl(), 'httponly' => false, 'samesite' => 'Strict', ) ); if ( $ret ) { $wp_cerber_cookies[ cerber_get_cookie_prefix() . $name ] = array( $expire, $value ); } return $ret; } function cerber_get_cookie( $name, $default = false ) { return crb_array_get( $_COOKIE, cerber_get_cookie_prefix() . $name, $default ); } function cerber_get_cookie_prefix() { if ( $p = (string) crb_get_settings( 'cookiepref' ) ) { return $p; } return ''; } function crb_update_cookie_dependent() { static $done = false; if ( $done ) { return; } register_shutdown_function( function () { cerber_htaccess_sync( 'main' ); } ); $done = true; } function cerber_htaccess_sync( $file, $settings = array() ) { if ( ! $settings ) { $settings = crb_get_settings(); } if ( 'main' == $file ) { $rules = array(); if ( ! empty( $settings['adminphp'] ) && ( ! defined( 'CONCATENATE_SCRIPTS' ) || ! CONCATENATE_SCRIPTS ) ) { if ( ! crb_is_apache_mod_loaded( 'mod_rewrite' ) ) { return new WP_Error( 'no_mod', 'The Apache mod_rewrite module is not enabled on your web server. Ask your server administrator for assistance.' ); } $groove_x = cerber_get_groove_x(); $cookie = cerber_get_cookie_prefix() . CRB_GROOVE . '_x_' . $groove_x[0]; $rules [] = '# Protection of admin scripts is enabled (CVE-2018-6389)'; $rules [] = '<IfModule mod_rewrite.c>'; $rules [] = 'RewriteEngine On'; $rules [] = 'RewriteBase \/'; $rules [] = 'RewriteCond %{REQUEST_URI} ^(.*)wp-admin\/+load-scripts\\.php$ [OR,NC]'; $rules [] = 'RewriteCond %{REQUEST_URI} ^(.*)wp-admin\/+load-styles\\.php$ [NC]'; $rules [] = 'RewriteCond %{HTTP_COOKIE} !' . $cookie . '=' . $groove_x[1]; $rules [] = 'RewriteRule (.*) - [R=403,L]'; $rules [] = '<\/IfModule>'; } return cerber_update_htaccess( $file, $rules ); } if ( 'media' == $file ) { $rules = array(); if ( ! empty( $settings['phpnoupl'] ) ) { $rules [] = '<Files *>'; $rules [] = 'SetHandler none'; $rules [] = 'SetHandler default-handler'; $rules [] = 'Options -ExecCGI'; $rules [] = 'RemoveHandler .cgi .php .php3 .php4 .php5 .php7 .php8 .phtml .pl .py .pyc .pyo'; $rules [] = '<\/Files>'; $rules [] = '<IfModule mod_php.c>'; $rules [] = 'php_flag engine off'; $rules [] = '<\/IfModule>'; $rules [] = '<IfModule mod_php7.c>'; $rules [] = 'php_flag engine off'; $rules [] = '<\/IfModule>'; $rules [] = '<IfModule mod_php5.c>'; $rules [] = 'php_flag engine off'; $rules [] = '<\/IfModule>'; } return cerber_update_htaccess( $file, $rules ); } return false; } function cerber_htaccess_clean_up() { cerber_update_htaccess( 'main', array() ); cerber_update_htaccess( 'media', array() ); } function cerber_update_htaccess( $file, $rules = array() ) { if ( $file == 'main' ) { $htaccess = cerber_get_htaccess_file(); $marker = CERBER_MARKER1; } elseif ( $file == 'media' ) { $htaccess = cerber_get_upload_dir() . '\/.htaccess'; $marker = CERBER_MARKER2; } else { return new WP_Error( 'htaccess-io', 'Unknown .htaccess file specified' ); } if ( ! is_file( $htaccess ) ) { if ( ! touch( $htaccess ) ) { return new WP_Error( 'htaccess-io', 'ERROR: Unable to create the file ' . $htaccess ); } } elseif ( ! is_writable( $htaccess ) ) { return new WP_Error( 'htaccess-io', 'ERROR: Unable to update the file ' . $htaccess ); } $result = crb_insert_with_markers( $htaccess, $marker, $rules ); if ( $result || $result === 0 ) { $result = 'The file ' . $htaccess . ' has been updated'; } else { $result = new WP_Error( 'htaccess-io', 'ERROR: Unable to update the file ' . $htaccess ); } return $result; } function cerber_get_htaccess_file() { require_once( ABSPATH . 'wp-admin\/includes\/file.php' ); $home_path = get_home_path(); return $home_path . '.htaccess'; } function cerber_check_remote_domain( $domain_mask ) { $hostname = @gethostbyaddr( cerber_get_remote_ip() ); if ( ! $hostname || filter_var( $hostname, FILTER_VALIDATE_IP ) ) { return false; } if ( ! is_array( $domain_mask ) ) { $domain_mask = array( $domain_mask ); } foreach ( $domain_mask as $mask ) { if ( substr_count( $mask, '.' ) != substr_count( $hostname, '.' ) ) { continue; } $parts = array_reverse( explode( '.', $hostname ) ); $ok = true; foreach ( array_reverse( explode( '.', $mask ) ) as $i => $item ) { if ( $item != '*' && $item != $parts[ $i ] ) { $ok = false; break; } } if ( $ok == true ) { return true; } } return false; } function cerber_set_boot_mode( $mode = null ) { if ( $mode === null ) { $mode = crb_get_settings( 'boot-mode' ); } $source = dirname( cerber_plugin_file() ) . '\/modules\/aaa-wp-cerber.php'; $target = WPMU_PLUGIN_DIR . '\/aaa-wp-cerber.php'; if ( $mode == 1 ) { if ( file_exists( $target ) ) { if ( sha1_file( $source, true ) == sha1_file( $target, true ) ) { return 1; } if ( ! wp_is_writable( $target ) ) { return new WP_Error( 'cerber-boot', __( 'Destination file is not writable', 'wp-cerber' ) . ' ' . $target ); } } if ( ! is_dir( WPMU_PLUGIN_DIR ) ) { if ( ! mkdir( WPMU_PLUGIN_DIR, 0755, true ) ) { return new WP_Error( 'cerber-boot', __( 'Unable to create required directory', 'wp-cerber' ) . ' ' . WPMU_PLUGIN_DIR ); } } if ( ! wp_is_writable( WPMU_PLUGIN_DIR ) ) { return new WP_Error( 'cerber-boot', __( 'Destination directory is not writable', 'wp-cerber' ) . ' ' . WPMU_PLUGIN_DIR ); } if ( ! file_exists( $source ) ) { return new WP_Error( 'cerber-boot', __( 'Source file not found', 'wp-cerber' ) . ' ' . $source ); } if ( ! copy( $source, $target ) ) { return new WP_Error( 'cerber-boot', __( 'Unable to copy file', 'wp-cerber' ) . ' ' . $target ); } else { return 2; } } if ( file_exists( $target ) ) { if ( ! unlink( $target ) ) { return new WP_Error( 'cerber-boot', __( 'Unable to delete the file', 'wp-cerber' ) . ' ' . $target ); } else { cerber_diag_log( 'MU module deleted. IP:' . cerber_get_remote_ip() . ' METHOD: ' . $_SERVER['REQUEST_METHOD'] . ' ' . print_r( crb_get_post_fields(), 1 ) . ' UA: ' . $_SERVER['HTTP_USER_AGENT'] . ' REQ: ' . $_SERVER['REQUEST_URI'] ); return 3; } } return 4; } function cerber_get_mode() { if ( function_exists( 'cerber_mode' ) ) { return cerber_mode(); } return 0; } function cerber_is_permalink_enabled() { static $ret; if ( ! isset( $ret ) ) { $ret = (bool) get_option( 'permalink_structure' ); } return $ret; } function crb_check_dir( $dir, &$msg = '', $none = '' ) { $ret = 0; if ( ! is_dir( $dir ) ) { $ret = 1; $msg = $none ?: 'Required directory does not exist: ' . crb_escape( $dir ); } elseif ( ! wp_is_writable( $dir ) ) { if ( ! chmod( $dir, 0755 ) ) { $ret = 2; $msg = 'Required directory is not writable. Please check write permissions and ownership of this directory: ' . crb_escape( $dir ); } } return $ret; } function cerber_mb_basename( $file_name ) { $pos = mb_strrpos( $file_name, DIRECTORY_SEPARATOR ); if ( $pos !== false ) { return mb_substr( $file_name, $pos + 1 ); } return $file_name; } function cerber_get_extension( $file_name ) { $file_name = cerber_mb_basename( $file_name ); $pos = mb_strpos( $file_name, '.' ); if ( $pos !== false ) { if ( $ext = mb_substr( $file_name, $pos + 1 ) ) { return mb_strtolower( $ext ); } } return ''; } function crb_wp_version_compare( $ver, $comp = '>=' ) { return version_compare( cerber_get_wp_version(), (string) $ver, $comp ); } function cerber_get_wp_version() { static $ver; if ( ! $ver ) { include( ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'version.php' ); $ver = (string) $wp_version; } return $ver; } function cerber_get_wp_locale() { static $lc; if ( ! $lc ) { include( ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'version.php' ); $lc = $wp_local_package ?? 'en_US'; } return $lc; } function crb_get_themes() { static $theme_headers = array( 'Name' => 'Theme Name', 'ThemeURI' => 'Theme URI', 'Description' => 'Description', 'Author' => 'Author', 'AuthorURI' => 'Author URI', 'Version' => 'Version', 'Template' => 'Template', 'Status' => 'Status', 'Tags' => 'Tags', 'TextDomain' => 'Text Domain', 'DomainPath' => 'Domain Path', ); $themes = array(); if ( $list = search_theme_directories() ) { foreach ( $list as $key => $info ) { $css = $info['theme_root'] . '\/' . $info['theme_file']; if ( is_readable( $css ) ) { $themes[ $key ] = get_file_data( $info['theme_root'] . '\/' . $info['theme_file'], $theme_headers, 'theme' ); $themes[ $key ]['theme_root'] = $info['theme_root']; $themes[ $key ]['theme_file'] = $info['theme_file']; } } } return $themes; } function cerber_is_base64_encoded( $val ) { $val = trim( $val ); if ( empty( $val ) || is_numeric( $val ) || strlen( $val ) < 8 || preg_match( '\/[^A-Z0-9\\+\\\/=]\/i', $val ) ) { return false; } if ( $val = @base64_decode( $val ) ) { if ( ! preg_match( '\/[\\x00-\\x08\\x0B-\\x0C\\x0E-\\x1F]\/', $val ) ) { if ( preg_match( '\/[A-Z]\/i', $val ) ) { return $val; } } } return false; } function crb_is_alphanumeric( $str ) { return ! preg_match( '\/[^\\w\\-]\/', $str ); } function crb_arrays_similar( &$arr, $fields ) { if ( crb_array_diff_keys( $arr, $fields ) ) { return false; } foreach ( $fields as $field => $pattern ) { if ( is_callable( $pattern ) ) { if ( ! call_user_func( $pattern, $arr[ $field ] ) ) { return false; } } else { if ( ! preg_match( $pattern, $arr[ $field ] ) ) { return false; } } } return true; } function cerber_get_html_label( int $iid ) { $c = ( $iid == CERBER_FOK ) ? '#33be84' : '#e94045'; return '<span style=\"background-color: ' . $c . '; color: #fff; margin-left: 6px; display: inline-block; line-height: 1em; padding: 3px 5px; font-size: 92%;\">' . cerber_get_issue_labels( $iid ) . '<\/span>'; } function crb_getallheaders() { static $headers; if ( function_exists( 'getallheaders' ) ) { return getallheaders(); } if ( ! $headers ) { $headers = array(); foreach ( $_SERVER as $name => $value ) { if ( substr( $name, 0, 5 ) == 'HTTP_' ) { $headers[ str_replace( ' ', '-', ucwords( strtolower( str_replace( '_', ' ', substr( $name, 5 ) ) ) ) ) ] = $value; } } } return $headers; } function crb_is_request_header( $search_header ) { static $headers; list( $name, $value ) = explode( ':', $search_header, 2 ); $name = strtolower( trim( $name ) ); $value = strtolower( trim( $value ) ); if ( ! $name || ! $value ) { return false; } if ( ! $headers ) { $headers = array_change_key_case( crb_getallheaders(), CASE_LOWER ); } if ( $header_value = $headers[ $name ] ?? false ) { return strtolower( trim( $header_value ) ) === $value; } return false; } function cerber_error_log( $msg, $source = '' ) { cerber_diag_log( $msg, $source, true ); } function cerber_diag_log( $msg, string $source = '', $error = false ) { if ( $source == 'CLOUD' && ( ! defined( 'CERBER_CLOUD_DEBUG' ) || ! CERBER_CLOUD_DEBUG || ( ! defined( 'WP_ADMIN' ) && ! defined( 'WP_NETWORK_ADMIN' ) ) ) ) { return false; } if ( ! $msg || ( ! $log_file = cerber_get_diag_log() ) || ( ! $log = @fopen( $log_file, 'a' ) ) ) { return false; } if ( $source ) { $source = '[' . $source . ']'; } if ( $error ) { $source .= ' ERROR: '; } if ( ! is_array( $msg ) ) { $msg = array( $msg ); } foreach ( $msg as $line ) { if ( is_array( $line ) ) { $line = print_r( $line, 1 ); } $ret = @fwrite( $log, '[' . cerber_date( time(), false ) . ']' . $source . ' ' . $line . PHP_EOL ); } @fclose( $log ); return $ret; } function cerber_get_diag_log(): string { if ( ! $dir = crb_get_diag_dir() ) { return ''; } return $dir . 'cerber-debug.log'; } function crb_get_diag_dir(): string { if ( defined( 'CERBER_DIAG_DIR' ) && is_dir( CERBER_DIAG_DIR ) ) { return rtrim( CERBER_DIAG_DIR, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR; } elseif ( $dir = cerber_get_the_folder() ) { return $dir; } return ''; } function cerber_truncate_log( $bytes = 10000000 ) { update_user_meta( get_current_user_id(), 'clast_log_view', array() ); $file = cerber_get_diag_log(); if ( ! is_file( $file ) || filesize( $file ) <= $bytes ) { return; } if ( $bytes == 0 ) { $log = @fopen( $file, 'w' ); @fclose( $log ); return; } if ( $text = file_get_contents( $file ) ) { $text = substr( $text, 0 - $bytes ); if ( ! $log = @fopen( $file, 'w' ) ) { return; } @fwrite( $log, $text ); @fclose( $log ); } } function crb_get_bloginfo( $what ) { static $info = array(); if ( ! isset( $info[ $what ] ) ) { $info[ $what ] = get_bloginfo( $what ); } return $info[ $what ]; } function crb_is_php_mod() { require_once( ABSPATH . 'wp-admin\/includes\/misc.php' ); if ( apache_mod_loaded( 'mod_php7' ) ) { return true; } if ( apache_mod_loaded( 'mod_php5' ) ) { return true; } return false; } function cerber_fromcharcode( $str ) { $vals = explode( ',', $str ); $vals = array_map( function ( $v ) { $v = trim( $v ); if ( $v[0] == '0' ) { $v = ( $v[1] == 'x' || $v[1] == 'X' ) ? hexdec( $v ) : octdec( $v ); } else { $v = intval( $v ); } return '&#' . $v . ';'; }, $vals ); return mb_convert_encoding( implode( '', $vals ), 'UTF-8', 'HTML-ENTITIES' ); } function cerber_empty_dir( $dir ) { if ( ! @is_dir( $dir ) || 0 === strpos( $dir, ABSPATH ) ) { return new WP_Error( 'no-dir', 'This directory cannot be emptied' ); } $files = @scandir( $dir ); if ( ! is_array( $files ) || empty( $files ) ) { return true; } $fs = cerber_init_wp_filesystem(); if ( crb_is_wp_error( $fs ) ) { return $fs; } $ret = true; foreach ( $files as $file ) { $full = $dir . $file; if ( @is_file( $full ) ) { if ( ! @unlink( $full ) ) { $ret = false; } } elseif ( ! in_array( $file, array( '..', '.' ) ) && is_dir( $full ) ) { if ( ! $fs->rmdir( $full, true ) ) { $ret = false; } } } if ( ! $ret ) { return new WP_Error( 'file-deletion-error', 'Some files or subdirectories in this directory cannot be deleted: ' . $dir ); } return $ret; } function crb_create_folder( $target_dir, $permissions = 0755 ) { if ( file_exists( $target_dir ) ) { return true; } $err = ''; if ( ! mkdir( $target_dir, $permissions, true ) ) { $err = 'Unable to create directory: <b>' . $target_dir . '<\/b>. Check permissions of parent directory.'; } elseif ( ! chmod( $target_dir, $permissions ) ) { $err = 'Unable to set directory permissions for ' . $target_dir; } if ( $err ) { return new WP_Error( 'cerber-dir', $err ); } return true; } function crb_raise_limits( $mem = null ) { @ini_set( 'max_execution_time', 180 ); if ( function_exists( 'set_time_limit' ) && false === strpos( ini_get( 'disable_functions' ), 'set_time_limit' ) ) { @set_time_limit( 0 ); } if ( $mem ) { @ini_set( 'memory_limit', $mem ); } } function cerber_mask_email( $email ) { list( $box, $host ) = explode( '@', $email ); $box = str_pad( $box[0], strlen( $box ), '*' ); $host = str_pad( substr( $host, strrpos( $host, '.' ) ), strlen( $host ), '*', STR_PAD_LEFT ); return str_replace( '*', '&#8727;', $box . '@' . $host ); } function crb_mask_login( $login ) { if ( is_email( $login ) ) { return cerber_mask_email( $login ); } $strlen = mb_strlen( $login ); return str_pad( mb_substr( $login, 0, intdiv( $strlen, 2 ) ), $strlen, '*' ); } function crb_mask_ip( $ip = '' ) { if ( cerber_is_ipv6( $ip ) ) { $pos = strpos( $ip, ':', strpos( $ip, ':', strpos( $ip, ':' ) + 1 ) + 1 ); $delimiter = ':'; } else { $pos = strpos( $ip, '.', strpos( $ip, '.' ) + 1 ); $delimiter = '.'; } if ( ! $pos ) { return $ip; } $net = substr( $ip, 0, $pos ); $sub = substr( $ip, $pos ); return $net . preg_replace( '\/[^' . $delimiter . ']\/', '*', $sub ); } function crb_insert_with_markers( $filename, $marker, $insertion ) { if ( ! file_exists( $filename ) ) { if ( ! is_writable( dirname( $filename ) ) ) { return false; } if ( ! touch( $filename ) ) { return false; } } elseif ( ! is_writeable( $filename ) ) { return false; } if ( ! is_array( $insertion ) ) { $insertion = explode( \"\\n\", $insertion ); } $start_marker = \"# BEGIN {$marker}\"; $end_marker = \"# END {$marker}\"; $fp = fopen( $filename, 'r+' ); if ( ! $fp ) { return false; } flock( $fp, LOCK_EX ); $lines = array(); while ( ! feof( $fp ) ) { $lines[] = rtrim( fgets( $fp ), \"\\r\\n\" ); } $pre_lines = array(); $post_lines = array(); $existing_lines = array(); $found_marker = false; $found_end_marker = false; foreach ( $lines as $line ) { if ( ! $found_marker && false !== strpos( $line, $start_marker ) ) { $found_marker = true; continue; } elseif ( ! $found_end_marker && false !== strpos( $line, $end_marker ) ) { $found_end_marker = true; continue; } if ( ! $found_marker ) { $pre_lines[] = $line; } elseif ( $found_marker && $found_end_marker ) { $post_lines[] = $line; } else { $existing_lines[] = $line; } } if ( $existing_lines === $insertion ) { flock( $fp, LOCK_UN ); fclose( $fp ); return true; } $new_file_data = implode( \"\\n\", array_merge( $pre_lines, array( $start_marker ), $insertion, array( $end_marker ), $post_lines ) ); fseek( $fp, 0 ); $bytes = fwrite( $fp, $new_file_data ); if ( $bytes ) { ftruncate( $fp, ftell( $fp ) ); } fflush( $fp ); flock( $fp, LOCK_UN ); fclose( $fp ); return (bool) $bytes; } function cerber_init_wp_filesystem() { global $wp_filesystem; if ( $wp_filesystem instanceof WP_Filesystem_Direct ) { return $wp_filesystem; } require_once( ABSPATH . 'wp-admin\/includes\/file.php' ); add_filter( 'filesystem_method', '__ret_direct' ); if ( ! WP_Filesystem() ) { return new WP_Error( 'cerber-file', 'Unable to init WP_Filesystem' ); } remove_filter( 'filesystem_method', '__ret_direct' ); return $wp_filesystem; } function __ret_direct() { return 'direct'; } function crb_redirect( string $url ) { CRB_Globals::$redirect_url = $url; return wp_redirect( $url ); } function crb_safe_redirect( string $url ) { CRB_Globals::$redirect_url = $url; return wp_safe_redirect( $url ); } function crb_get_alert_params() { $params = CRB_ALERT_PARAMS; $get = crb_get_query_params(); if ( ! array_intersect_key( $params, $get ) ) { return $params; } if ( ! empty( $get['filter_ip'] ) ) { $begin = 0; $end = 0; $ip = cerber_any2range( $get['filter_ip'] ); if ( is_array( $ip ) ) { $begin = $ip['begin']; $end = $ip['end']; $ip = 0; } elseif ( ! $ip ) { $ip = 0; } $params['begin'] = $begin; $params['end'] = $end; $params['filter_ip'] = $ip; } $temp = $params; unset( $temp['begin'], $temp['end'], $temp['filter_ip'] ); foreach ( array_keys( $temp ) as $key ) { if ( ! empty( $get[ $key ] ) ) { if ( is_array( $get[ $key ] ) ) { $params[ $key ] = array_map( 'trim', $get[ $key ] ); } else { $params[ $key ] = trim( $get[ $key ] ); } } else { $params[ $key ] = 0; } } if ( ! empty( $params['al_expires'] ) ) { $time = 24 * 3600 + strtotime( 'midnight ' . $params['al_expires'] ); $params['al_expires'] = $time - get_option( 'gmt_offset' ) * 3600; } $int_fields = array( 'al_limit', 'al_ignore_rate', 'al_send_emails', 'al_send_pushbullet', 'al_send_me', ); foreach ( $int_fields as $f ) { $params[ $f ] = crb_absint( $params[ $f ] ); } if ( ! is_array( $params['filter_activity'] ) ) { $params['filter_activity'] = array( $params['filter_activity'] ); } $params['filter_activity'] = array_filter( $params['filter_activity'] ); array_walk_recursive( $params, function ( &$item ) { $item = str_replace( array( '<', '>', '[', ']', '\"', \"'\" ), '', $item ); } ); return $params; } function crb_get_alert_id( $params ) { return sha1( json_encode( array_values( array_diff_key( $params, array_flip( CRB_NON_ALERT_PARAMS ) ) ) ) ); } function crb_random_string( $length_min, $length_max = null, $inc_num = true, $upper_case = true, $extra = '' ) { static $alpha1 = 'abcdefghijklmnopqrstuvwxyz'; static $alpha2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; static $digits = '0123456789'; if ( ! $length_max ) { $length_max = $length_min; } $str = $alpha1; if ( $inc_num ) { $str .= $digits; } if ( $upper_case ) { $str .= $alpha2; } if ( $extra ) { $str .= $extra; } $n = (int) ceil( $length_max \/ strlen( $str ) ); if ( $n > 1 ) { $str = implode( '', array_fill( 0, $n, $str ) ); } $length = ( $length_min != $length_max ) ? rand( $length_min, $length_max ) : $length_min; return substr( str_shuffle( $str ), 0, $length ); } function crb_auto_decode( &$text ) { if ( ! $text ) { return array(); } if ( $text[0] == 'a' ) { return crb_unserialize( $text ); } return @json_decode( $text, true ); } function crb_unserialize( &$string ) { return @unserialize( $string, [ 'allowed_classes' => false ] ); } function crb_get_review_url( $vendor = null ) { static $urls = array( 'tpilot' => array( 'https:\/\/www.trustpilot.com\/review\/wpcerber.com', 'https:\/\/www.trustpilot.com\/evaluate\/wpcerber.com' ), 'g2' => array( 'https:\/\/www.g2.com\/products\/cerber-security-antispam-malware-scan\/reviews\/start' ), 'wp' => array( 'https:\/\/wordpress.org\/support\/plugin\/wp-cerber\/reviews\/#new-post' ), 'cap' => array( 'https:\/\/reviews.capterra.com\/new\/187653' ), 'tradius' => array( 'https:\/\/www.trustradius.com\/products\/wp-cerber-security\/reviews' ), ); $ret = $urls[ $vendor ]; if ( $vendor == 'tpilot' ) { shuffle( $ret ); } return $ret[0]; } function crb_was_activated( $ago ) { static $actvd; if ( ! isset( $actvd ) ) { if ( ! $actvd = cerber_get_set( '_activated' ) ) { return true; } } return ( ( (int) crb_array_get( $actvd, 'time' ) + $ago ) <= time() ); } function cerber_hash_token( $token ) { if ( function_exists( 'hash' ) ) { return hash( 'sha256', $token ); } else { return sha1( $token ); } } function crb_absint( $val ) { return abs( (int) $val ); } function crb_is_apache_mod_loaded( $mod = '' ) { static $loaded = array(); if ( ! isset( $loaded[ $mod ] ) ) { $loaded[ $mod ] = apache_mod_loaded( 'mod_rewrite' ); } return $loaded[ $mod ]; } final class CRB_Cache { private static $cache = array(); private static $stat = array(); private static $wp_cache_group = 'wp_cerber'; private static $wp_key_list = 'wp_cerber_list'; static function set( $key, $value, $expire = 0 ) { $exp = 0; if ( $expire > 0 ) { $exp = time() + (int) $expire; if ( $exp < time() ) { return false; } } $element = array( $value, $exp ); self::$cache[ $key ] = $element; if ( self::checker() ) { wp_cache_set( $key, $element, self::$wp_cache_group ); $entries = wp_cache_get( self::$wp_key_list, self::$wp_key_list ); if ( ! $entries ) { $entries = array(); } $entries[ $key ] = $expire; wp_cache_set( self::$wp_key_list, $entries, self::$wp_key_list ); } if ( ! isset( self::$stat[ $key ] ) ) { self::$stat[ $key ] = array( 0, 0 ); } self::$stat[ $key ][0] ++; return true; } static function get( $key, $default = null ) { $element = crb_array_get( self::$cache, $key ); if ( ! is_array( $element ) ) { if ( self::checker() ) { $element = wp_cache_get( $key, self::$wp_cache_group ); } } if ( ! is_array( $element ) ) { return $default; } if ( ! empty( $element[1] ) && $element[1] < time() ) { self::delete( $key ); return $default; } if ( ! isset( self::$stat[ $key ] ) ) { self::$stat[ $key ] = array( 0, 0 ); } self::$stat[ $key ][1] ++; return $element[0]; } static function delete( $key ) { if ( isset( self::$cache[ $key ] ) ) { unset( self::$cache[ $key ] ); } if ( self::checker() ) { wp_cache_delete( $key, self::$wp_cache_group ); } } static function reset() { self::$cache = array(); if ( $entries = wp_cache_get( self::$wp_key_list, self::$wp_key_list ) ) { foreach ( $entries as $entry => $exp ) { wp_cache_delete( $entry, self::$wp_cache_group ); } wp_cache_delete( self::$wp_key_list, self::$wp_key_list ); } } static function get_stat( $recheck = false ) { $entries = wp_cache_get( self::$wp_key_list, self::$wp_key_list ); if ( $recheck && $entries ) { foreach ( $entries as $key => $exp ) { if ( ! $element = wp_cache_get( $key, self::$wp_cache_group ) ) { unset( $entries[ $key ] ); } } wp_cache_set( self::$wp_key_list, $entries, self::$wp_key_list ); } if ( empty( $entries ) ) { $entries = array(); } return array( self::$stat, $entries ); } static function checker() { $sid = get_wp_cerber()->getRequestID(); $check = wp_cache_get( '__checker__', self::$wp_cache_group ); if ( ! $check || ! isset( $check['t'] ) || ! isset( $check['s'] ) ) { wp_cache_set( '__checker__', array( 't' => time(), 's' => $sid ), self::$wp_cache_group ); return 0; } if ( $check['s'] == $sid ) { return 0; } return $check['t']; } } function cerber_cache_set( $key, $value, $expire = 0 ) { return CRB_Cache::set( $key, $value, $expire ); } function cerber_cache_get( $key, $default = null ) { return CRB_Cache::get( $key, $default ); } function cerber_cache_delete( $key ) { CRB_Cache::delete( $key ); } function cerber_cache_enable() { global $cerber_use_cache; $cerber_use_cache = true; } function cerber_cache_disable() { global $cerber_use_cache; $cerber_use_cache = false; } function cerber_cache_is_enabled() { global $cerber_use_cache; return ! empty( $cerber_use_cache ); } function crb_q_cache_get( $sql, $table, $cache_only = false, $hash_fields = array( 'stamp', 'ip', 'session_id' ), $order_by = 0 ) { global $wp_cerber_q_cache; if ( is_string( $sql ) ) { $sql = array( array( $sql ) ); } $single = ( count( $sql ) == 1 ); $run = true; $cache_key = 'q_cache_' . sha1( implode( '|', array_column( $sql, 0 ) ) ); $cache = cerber_get_set( $cache_key, 0, false, true ); if ( $cache ) { $cache = json_decode( $cache ); if ( $cache->hash == crb_get_table_hash( $table, $hash_fields, $order_by ) ) { $wp_cerber_q_cache = true; $run = false; } } if ( $run && $cache_only ) { return false; } if ( ! $run ) { $results = $cache->results; } else { $new_cache = array(); $new_cache['hash'] = crb_get_table_hash( $table, $hash_fields, $order_by ); $results = array(); foreach ( $sql as $query ) { $results[] = cerber_db_get_results( $query[0], crb_array_get( $query, 1 ) ); } $new_cache['results'] = $results; $new_cache = json_encode( $new_cache, JSON_UNESCAPED_UNICODE ); cerber_update_set( $cache_key, $new_cache, 0, false, time() + 7200, true ); } if ( $single ) { return $results[0]; } return $results; } function crb_get_table_hash( $table, $hash_fields, $order_by ) { static $hashes; $fields = implode( ',', $hash_fields ); $key = sha1( $table . '|' . $fields . '|' . $order_by ); if ( ! isset( $hashes[ $key ] ) ) { if ( $data = cerber_db_get_row( 'SELECT ' . $fields . ' FROM ' . $table . ' ORDER BY ' . $hash_fields[ $order_by ] . ' DESC LIMIT 1' ) ) { $hashes[ $key ] = sha1( implode( '|', $data ) ); } else { $hashes[ $key ] = ''; } } return $hashes[ $key ]; } add_filter( 'update_plugins_downloads.wpcerber.com', 'cerber_check_for_update', 10, 4 ); function cerber_check_for_update( $update, $plugin_data, $plugin_file, $locales ) { if ( ! crb_get_settings( 'cerber_sw_repo' ) || ! $uri = crb_array_get( $plugin_data, 'UpdateURI' ) ) { return false; } $response = wp_remote_get( $uri ); $err = ''; if ( crb_is_wp_error( $response ) ) { $err = $response->get_error_message(); } if ( ! $body = crb_array_get( $response, 'body' ) ) { cerber_update_set( 'last_update_check', array( 'error' => $err, 'no_body' => 1, 'uri' => $uri ) ); return false; } $package_data = json_decode( $body, true ); $update = crb_array_get( $package_data, $plugin_file, $update ); if ( isset( $update['requires_wp'] ) ) { $update['requires'] = $update['requires_wp']; } $update['tested'] = cerber_get_wp_version(); $update['slug'] = 'wp-cerber'; if ( ! is_array( $locales ) ) { $locales = array(); } $available = $update['trans_bucket'] ?? array(); if ( ! is_array( $available ) ) { $available = array(); } $update['translations'] = crb_process_locales( $locales, $available ); unset( $update['trans_bucket'] ); cerber_update_set( 'last_update_check', array( 'success' => time(), 'uri' => $uri ) ); return $update; } function crb_process_locales( array $wp_locales, array $available ): array { if ( ! $wp_locales || ! $available ) { return array(); } if ( $locale = crb_get_settings( 'admin_locale' ) ) { $wp_locales[] = $locale; } $wp_locales = array_filter( $wp_locales, function ( $value ) { return strpos( $value, 'en_' ) !== 0; }); if ( ! $wp_locales ) { return array(); } $translations = array(); foreach ( $wp_locales as $locale ) { if ( $hash = $available[ $locale ] ?? false ) { $mo_file = WP_LANG_DIR . '\/plugins\/wp-cerber-' . $locale . '.mo'; if ( file_exists( $mo_file ) && $hash == sha1_file( $mo_file ) ) { continue; } } $translations[] = array( 'language' => $locale, 'package' => 'https:\/\/downloads.wpcerber.com\/translations\/wp-cerber\/' . $locale . '.zip', 'autoupdate' => 1, 'version' => CERBER_VER, ); } return $translations; } add_filter( 'auto_update_plugin', function ( $update, $item ) { if ( crb_get_settings( 'cerber_sw_auto' ) && $item->plugin == CERBER_PLUGIN_ID ) { return true; } return $update; }, PHP_INT_MAX, 2 ); function crb_get_remote_json( string $url ) { if ( 0 !== strpos( $url, 'https:\/\/' ) ) { return new WP_Error( 'unsafe_url', 'Invalid URL. It must begin with https:\/\/' ); } if ( defined( 'CERBER_NETWORK_DEBUG' ) && CERBER_NETWORK_DEBUG ) { cerber_diag_log( 'Initiating downloading JSON payload from ' . $url ); } $response = wp_remote_get( $url ); if ( crb_is_wp_error( $response ) ) { return $response; } if ( ! $body = wp_remote_retrieve_body( $response ) ) { return new WP_Error( 'no_content', 'The response body is empty' ); } $decoded = json_decode( $body, true ); if ( ! $decoded || JSON_ERROR_NONE != json_last_error() ) { return new WP_Error( 'json_not_found', 'Unable to decode JSON payload. ' . json_last_error_msg() ); } if ( defined( 'CERBER_NETWORK_DEBUG' ) && CERBER_NETWORK_DEBUG ) { cerber_diag_log( 'Loaded and decoded successfully, size: ' . strlen( $body ) ); } return $decoded; } function crb_get_last_user_login( $user_id ) { $user_set = cerber_get_set( CRB_USER_SET, $user_id ); if ( $user_set['last_login']['cn'] ?? false ) { return $user_set['last_login']; } if ( ! $row = cerber_get_last_login( $user_id ) ) { return false; } $user_set['last_login']['ts'] = $row->stamp; $user_set['last_login']['cn'] = $row->country ?: lab_get_country( $row->ip, false ); cerber_update_set( CRB_USER_SET, $user_set, $user_id ); return $user_set['last_login']; } function crb_configure_curl( $curl, $params, $setting = 'main_use_proxy' ) { global $wp_cerber_relay; if ( crb_get_settings( $setting ) ) { if ( defined( 'WP_PROXY_HOST' ) && defined( 'WP_PROXY_PORT' ) ) { $params[ CURLOPT_PROXYTYPE ] = defined( 'CERBER_PROXY_TYPE' ) ? CERBER_PROXY_TYPE : CURLPROXY_HTTP; $params[ CURLOPT_PROXY ] = WP_PROXY_HOST; $params[ CURLOPT_PROXYPORT ] = WP_PROXY_PORT; if ( defined( 'WP_PROXY_USERNAME' ) && defined( 'WP_PROXY_PASSWORD' ) ) { $params[ CURLOPT_PROXYAUTH ] = CURLAUTH_ANY; $params[ CURLOPT_PROXYUSERPWD ] = WP_PROXY_USERNAME . ':' . WP_PROXY_PASSWORD; } } $wp_cerber_relay = 1; } else { $wp_cerber_relay = 0; } try { if ( ! curl_setopt_array( $curl, $params ) ) { throw new Exception( 'Failed to set cURL options.' ); } } catch ( Throwable $e ) { if ( defined( 'CERBER_NETWORK_DEBUG' ) && CERBER_NETWORK_DEBUG ) { cerber_error_log( $e->getMessage() . '. Error thrown on line ' . $e->getLine() . ' in file ' . $e->getFile() . '. cURL options provided: ' . print_r( $params, 1 ), 'NETWORK' ); } return false; } return true; } function crb_get_plugin_slug( string $path ): string { if ( strpos( $path, WP_PLUGIN_DIR ) === 0 ) { $path = str_replace( WP_PLUGIN_DIR, '', $path ); $path = ltrim( $path, '\/' ); } if ( strpos( $path, '\/' ) ) { $plugin_slug = dirname( $path ); } elseif ( $path === 'hello.php' ) { $plugin_slug = 'hello-dolly'; } else { $plugin_slug = preg_replace( '\/\\.php$\/', '', $path ); } return $plugin_slug; } function crb_load_dependencies( $func, $load_cons = false ) { if ( function_exists( $func ) ) { return false; } if ( $load_cons ) { cerber_load_wp_constants(); } $ret = true; switch ( $func ) { case 'wp_mail': case 'wp_create_nonce': case 'is_user_logged_in': case 'wp_get_current_user': require_once( ABSPATH . WPINC . '\/pluggable.php' ); break; case 'wp_is_auto_update_enabled_for_type': require_once( ABSPATH . 'wp-admin\/includes\/update.php' ); break; default: $ret = false; } return $ret; } add_filter( 'lang_dir_for_domain', 'crb_loc_exception_handler', 10, 3 ); function crb_loc_exception_handler( $path, $domain, $locale ) { if ( $domain == 'wp-cerber' && ( ! doing_action( 'after_setup_theme' ) && ! did_action( 'after_setup_theme' ) ) ) { $path = ''; } return $path; } function crb_load_localization() { if ( is_admin() || nexus_is_valid_request() ) { $locale = crb_get_admin_locale(); if ( $locale == 'en_US' ) { add_filter( 'override_load_textdomain', function ( $val, $domain, $mofile ) { if ( $domain == 'wp-cerber' ) { $val = true; } return $val; }, 100, 3 ); } else { add_filter( 'load_textdomain_mofile', function ( $mofile, $domain ) { if ( $domain != 'wp-cerber' ) { return $mofile; } $locale = crb_get_admin_locale(); $new_mofile = dirname( $mofile ) . '\/' . $domain . '-' . $locale . '.mo'; return file_exists( $new_mofile ) ? $new_mofile : $mofile; }, PHP_INT_MAX, 2 ); } } load_plugin_textdomain( 'wp-cerber', false, 'wp-cerber\/languages' ); } class CRB_Globals { static $session_status; static $act_status; static $do_not_log = array(); static $reset_pwd_msg = ''; static $reset_pwd_denied = false; static $retrieve_password = false; static $login_form_errors = array(); static $user_id; static $req_status = 0; private static $assets_url = ''; static $ajax_loader = ''; static $logged = array(); static $blocked; static $db_requests = array(); static $db_errors = array(); static $bot_status = 0; static $htaccess_failure = array(); static $php_errors = array(); static $prev_handler = null; private static $by_settings = array(); static $admin_footer_html = ''; static $redirect_url = ''; static $doing_upgrade; static function admin_init() { } static function get_errors() { if ( ! is_array( self::$php_errors ) ) { self::$php_errors = array(); } if ( $last_err = error_get_last() ) { $add = true; if ( self::$php_errors) { foreach ( self::$php_errors as $err ) { if ( $last_err['type'] == $err[0] && $last_err['line'] == $err[3] && $last_err['file'] == $err[2] ) { $add = false; break; } } } if ( $add ) { self::$php_errors[] = array( $last_err['type'], $last_err['message'], $last_err['file'], $last_err['line'] ); } } return self::$php_errors; } static function has_errors( $code ) { if ( ! self::get_errors() ) { return false; } $error_codes = array_column( self::$php_errors, 0 ); if ( is_array( $code ) ) { return (bool) array_intersect( $error_codes, $code ); } return in_array( $code, $error_codes ); } static function assets_url( $res = '', $echo = false ) { if ( ! self::$assets_url ) { self::$assets_url = crb_escape( cerber_plugin_dir_url() ) . 'assets\/'; } $ret = self::$assets_url; if ( $res ) { $ret .= $res; } if ( $echo ) { echo $ret; } return $ret; } static function set_assets_url( $url ) { self::$assets_url = crb_escape( $url ); } static function set_bot_status( $val ) { self::$bot_status = (int) $val; CRB_Globals::set_act_status( $val ); } static function set_act_status_if( $val, $setting_id = '' ) { if ( ! self::$act_status ) { self::$act_status = $val; if ( $setting_id ) { self::$by_settings[] = $setting_id; } } } static function set_act_status( $val, $setting_id = '' ) { self::$act_status = $val; if ( $setting_id ) { self::$by_settings[] = $setting_id; } } static function set_ctrl_setting( $setting_id ) { self::$by_settings[] = $setting_id; } static function get_ctrl_settings() { return self::$by_settings; } static function to_admin_footer( $html ) { self::$admin_footer_html .= (string)"},"62afd02ce0fe271ca3dbd8b11d8afa53":{"file":"\/reo.world\/wp-content\/plugins\/wp-cerber\/cerber-settings.php","exploit":"eval_strrev","line":52,"match":"lave"}}