/home/altere25/infinet.finance/wp-content/plugins/ninjafirewall/lib
NameSizeModeActions
share/-0755rm
.htaccess3780644editdlrm
anti_malware.php26510644editdlrm
custom_firewall.php19440644editdlrm
custom_plugin.php19400644editdlrm
dashboard.php236880644editdlrm
dashboard_about.php27270644editdlrm
dashboard_statistics.php73490644editdlrm
email_sodium.php71630644editdlrm
events.php114230644editdlrm
event_notifications.php194280644editdlrm
event_updates.php93580644editdlrm
firewall.php633850644editdlrm
firewall_options.php172620644editdlrm
firewall_policies.php719870644editdlrm
fw_centlog.php24220644editdlrm
fw_fileguard.php36890644editdlrm
fw_livelog.php56840644editdlrm
help.php485860644editdlrm
i18n-extra.php310210644editdlrm
index.html830644editdlrm
init_update.php75410644editdlrm
install.php123810644editdlrm
install_default.php105260644editdlrm
loader.php5470644editdlrm
login_protection.php231210644editdlrm
logs.php33540644editdlrm
logs_firewall_log.php117970644editdlrm
logs_live_log.php202850644editdlrm
monitoring.php31560644editdlrm
monitoring_file_check.php291850644editdlrm
monitoring_file_guard.php62180644editdlrm
network.php34470644editdlrm
nfw_log.php42250644editdlrm
scheduled_tasks.php55990644editdlrm
security_rules.php28590644editdlrm
security_rules_editor.php73150644editdlrm
security_rules_update.php203090644editdlrm
sign.pub8010644editdlrm
thickbox.php207990644editdlrm
utils.php576700644editdlrm
widget.php48280644editdlrm
wpplus.php175210644editdlrm
Edit: /home/altere25/infinet.finance/wp-content/plugins/ninjafirewall/lib/firewall.php (63385B)
system.multicall') !== FALSE ) { nfw_log('Access to WordPress XML-RPC API (system.multicall method)', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } } if (! empty($nfw_['nfw_options']['no_xmlrpc_pingback']) ) { if ( @strpos( $HTTP_RAW_POST_DATA, 'pingback.ping') !== FALSE ) { nfw_log('Access to WordPress XML-RPC API (pingback.ping)', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } } } } if (! empty($nfw_['nfw_options']['no_xmlrpc_pingback']) && strpos($_SERVER['HTTP_USER_AGENT'], '; verifying pingback from ') !== FALSE) { nfw_log('Blocked pingback verification', $_SERVER['HTTP_USER_AGENT'], 2, 0); nfw_block(); } // WordPress Aplication Passwords if (! empty($nfw_['nfw_options']['no_appswd']) && strpos( $_SERVER['SCRIPT_NAME'], '/wp-admin/authorize-application.php' ) !== FALSE ) { nfw_log('Access to WordPress Application Passwords', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } if (! empty($nfw_['nfw_options']['no_post_themes']) && $_SERVER['REQUEST_METHOD'] == 'POST' && strpos($_SERVER['SCRIPT_NAME'], $nfw_['nfw_options']['no_post_themes']) !== FALSE ) { nfw_log('POST request in the themes folder', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } if (! empty($nfw_['nfw_options']['wp_dir']) && preg_match( '`' . $nfw_['nfw_options']['wp_dir'] . '`', $_SERVER['SCRIPT_NAME']) ) { nfw_log('Forbidden direct access to PHP script', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } nfw_check_upload(); // Fetch rules $ret = nfw_get_data( 'nfw_rules' ); if ( $ret !== true ) { nfw_quit( $ret ); return; } nfw_check_request( $nfw_['nfw_rules'], $nfw_['nfw_options'] ); if (! empty($nfw_['nfw_options']['get_sanitise']) && ! empty($_GET) ){ $_GET = nfw_sanitise( $_GET, 1, 'GET'); } if (! empty($nfw_['nfw_options']['post_sanitise']) && ! empty($_POST) ){ $_POST = nfw_sanitise( $_POST, 1, 'POST'); } if (! empty($nfw_['nfw_options']['request_sanitise']) && ! empty($_REQUEST) ){ $_REQUEST = nfw_sanitise( $_REQUEST, 1, 'REQUEST'); } if (! empty($nfw_['nfw_options']['cookies_sanitise']) && ! empty($_COOKIE) ) { $_COOKIE = nfw_sanitise( $_COOKIE, 3, 'COOKIE'); } if (! empty($nfw_['nfw_options']['ua_sanitise']) && ! empty($_SERVER['HTTP_USER_AGENT']) ) { $_SERVER['HTTP_USER_AGENT'] = nfw_sanitise( $_SERVER['HTTP_USER_AGENT'], 1, 'HTTP_USER_AGENT'); } if (! empty($nfw_['nfw_options']['referer_sanitise']) && ! empty($_SERVER['HTTP_REFERER']) ) { $_SERVER['HTTP_REFERER'] = nfw_sanitise( $_SERVER['HTTP_REFERER'], 1, 'HTTP_REFERER'); } if (! empty($nfw_['nfw_options']['php_path_i']) && ! empty($_SERVER['PATH_INFO']) ) { $_SERVER['PATH_INFO'] = nfw_sanitise( $_SERVER['PATH_INFO'], 2, 'PATH_INFO'); } if (! empty($nfw_['nfw_options']['php_path_t']) && ! empty($_SERVER['PATH_TRANSLATED']) ) { $_SERVER['PATH_TRANSLATED'] = nfw_sanitise( $_SERVER['PATH_TRANSLATED'], 2, 'PATH_TRANSLATED'); } if (! empty($nfw_['nfw_options']['php_self']) && ! empty($_SERVER['PHP_SELF']) ) { $_SERVER['PHP_SELF'] = nfw_sanitise( $_SERVER['PHP_SELF'], 2, 'PHP_SELF'); } nfw_quit(20); return; // ===================================================================== // Close the SQL link, set the firewall status, clear the $nfw_ array // and close the session before leaving. function nfw_quit( $status ) { global $nfw_; define( 'NFW_STATUS', $status ); if ( isset( $nfw_['mysqli'] ) ) { $nfw_['mysqli']->close(); } $nfw_ = array(); } // ===================================================================== // Connect to the DB. function nfw_connect() { global $nfw_, $wp_config; // WPWAF mode? if ( defined('NFW_WPWAF') && NFW_WPWAF == 2 ) { $nfw_['wp_waf'] = 2; return true; } // Check if we have a SQL link that was defined in the .htninja. // See "Giving NinjaFirewall a MySQLi link identifier" // at https://blog.nintechnet.com/ninjafirewall-wp-edition-the-htninja-configuration-file/ if (! empty( $GLOBALS['nfw_mysqli'] ) && ! empty( $GLOBALS['nfw_table_prefix'] ) ) { $nfw_['mysqli'] = $GLOBALS['nfw_mysqli']; $nfw_['table_prefix'] = $GLOBALS['nfw_table_prefix']; return true; } // DB if (! file_exists( $wp_config ) ) { if (! @file_exists( $wp_config = dirname( dirname($nfw_['wp_content']) ) . '/wp-config.php') ) { return 1; } } if (! $nfw_['fh'] = fopen($wp_config, 'r') ) { return 2; } // Potential SQL flags $nfw_['MYSQL_CLIENT_FLAGS'] = 0; while (! feof($nfw_['fh'])) { $nfw_['line'] = fgets($nfw_['fh']); if ( preg_match('/^\s*define\s*\(\s*[\'"]DB_NAME[\'"]\s*,\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_NAME'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]DB_USER[\'"]\s*,\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_USER'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]DB_PASSWORD[\'"]\s*,\s*([\'"])(.+?)\1\s*\);/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_PASSWORD'] = str_replace( '\\'.$nfw_['match'][1], $nfw_['match'][1], $nfw_['match'][2] ); if ( $nfw_['match'][1] == '"' ) { $nfw_['DB_PASSWORD'] = str_replace( '\$', '$', $nfw_['DB_PASSWORD'] ); } } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]DB_HOST[\'"]\s*,\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_HOST'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*\$table_prefix\s*=\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['table_prefix'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]MYSQL_CLIENT_FLAGS[\'"]\s*,\s*(.+?)\s*\)/', $nfw_['line'], $nfw_['match']) ) { if ( empty( $nfw_['MYSQL_CLIENT_FLAGS'] ) ) { $available_flags = array( 'MYSQLI_CLIENT_COMPRESS' => MYSQLI_CLIENT_COMPRESS, 'MYSQLI_CLIENT_FOUND_ROWS' => MYSQLI_CLIENT_FOUND_ROWS, 'MYSQLI_CLIENT_IGNORE_SPACE' => MYSQLI_CLIENT_IGNORE_SPACE, 'MYSQLI_CLIENT_INTERACTIVE' => MYSQLI_CLIENT_INTERACTIVE, 'MYSQLI_CLIENT_SSL' => MYSQLI_CLIENT_SSL, 'MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT' => MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT ); // There could be one or more flags, e.g., 'MYSQLI_CLIENT_SSL | MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT' $tmp_flags = explode( '|', $nfw_['match'][1] ); foreach( $tmp_flags as $tmp_flag ) { $tmp_flag = trim( $tmp_flag ); if ( isset( $available_flags[$tmp_flag] ) ) { $nfw_['MYSQL_CLIENT_FLAGS'] += $available_flags[$tmp_flag]; } } } } } fclose($nfw_['fh']); unset($wp_config); if (! isset($nfw_['DB_NAME']) || ! isset($nfw_['DB_USER']) || ! isset($nfw_['DB_PASSWORD']) || ! isset($nfw_['DB_HOST']) || ! isset($nfw_['table_prefix']) ) { return 3; } nfw_check_dbhost(); // Make sure mysqli extension is loaded if (! function_exists( 'mysqli_real_connect' ) ) { return 14; } @$nfw_['mysqli'] = mysqli_init(); @mysqli_real_connect( $nfw_['mysqli'], $nfw_['DB_HOST'], $nfw_['DB_USER'], $nfw_['DB_PASSWORD'], $nfw_['DB_NAME'], $nfw_['port'], $nfw_['socket'], $nfw_['MYSQL_CLIENT_FLAGS'] ); if ($nfw_['mysqli']->connect_error) { return 4; } return true; } // ===================================================================== // Fetch rules and options. function nfw_get_data( $what ) { global $nfw_; if ( $what != 'nfw_rules' ) { $what = 'nfw_options'; } // WP API if ( isset( $nfw_['wp_waf'] ) && $nfw_['wp_waf'] == 2 ) { if ( is_multisite() ) { $nfw_[ $what ] = get_site_option( $what ); } else { $nfw_[ $what ] = get_option( $what ); } return true; // DB } else { // Rules if ( $what == 'nfw_rules' ) { if (! $nfw_['result'] = @$nfw_['mysqli']->query('SELECT * FROM `' . $nfw_['mysqli']->real_escape_string($nfw_['table_prefix']) . "options` WHERE `option_name` = 'nfw_rules'") ) { return 7; } if (! $nfw_['rules'] = @$nfw_['result']->fetch_object() ) { return 8; } if (! $nfw_['nfw_rules'] = @unserialize( $nfw_['rules']->option_value ) ) { return 12; } // Options } else { if (! $nfw_['result'] = @$nfw_['mysqli']->query('SELECT * FROM `' . $nfw_['mysqli']->real_escape_string($nfw_['table_prefix']) . "options` WHERE `option_name` = 'nfw_options'") ) { // Maybe this is an old multisite install where the main site // options table is named 'wp_1_options' instead of 'wp_options' if (! $nfw_['result'] = @$nfw_['mysqli']->query('SELECT * FROM `' . $nfw_['mysqli']->real_escape_string($nfw_['table_prefix']) . "1_options` WHERE `option_name` = 'nfw_options'") ) { return 5; } // Change the table prefix to match 'wp_1_options' $nfw_['table_prefix'] = "{$nfw_['table_prefix']}1_"; } if (! $nfw_['options'] = @$nfw_['result']->fetch_object() ) { return 6; } if (! $nfw_['nfw_options'] = @unserialize( $nfw_['options']->option_value ) ) { return 11; } } // Make sure we have something or return an error if ( $what == 'nfw_rules' && ! isset( $nfw_['nfw_rules']['1'] ) ) { return 16; } elseif ( $what == 'nfw_options' && ! isset( $nfw_['nfw_options']['enabled'] ) ) { return 15; } // All good return true; } } // ===================================================================== // Check for HTTPS. function nfw_is_https() { // Can be defined in the .htninja: if ( defined('NFW_IS_HTTPS') ) { return; } if ( ( isset( $_SERVER['SERVER_PORT'] ) && $_SERVER['SERVER_PORT'] == 443 ) || ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') || ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ) ) { define('NFW_IS_HTTPS', true); } else { define('NFW_IS_HTTPS', false); } } // ===================================================================== function nfw_check_session() { global $nfw_; if (! function_exists('session_status') ) { if (session_id() ) return; } else { if (session_status() === PHP_SESSION_ACTIVE) return; } // Prepare session: @ini_set('session.cookie_httponly', 1); @ini_set('session.use_only_cookies', 1); if ( defined('NFW_IS_HTTPS') && NFW_IS_HTTPS == true ) { @ini_set('session.cookie_secure', 1); } if (! headers_sent() ) { session_start(); $nfw_['session_id'] = 1; } } // ===================================================================== function nfw_check_ip() { if ( defined('NFW_REMOTE_ADDR') ) { return; } global $nfw_; if (! isset( $_SERVER['REMOTE_ADDR'] ) ) { $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; } if (strpos($_SERVER['REMOTE_ADDR'], ',') !== false) { // Ensure we have a proper and single IP (a user may use the .htninja file // to redirect HTTP_X_FORWARDED_FOR, which may contain more than one IP, // to REMOTE_ADDR): $nfw_['match'] = array_map('trim', @explode(',', $_SERVER['REMOTE_ADDR'])); foreach($nfw_['match'] as $nfw_['m']) { if ( filter_var($nfw_['m'], FILTER_VALIDATE_IP) ) { define( 'NFW_REMOTE_ADDR', $nfw_['m']); break; } } } if (! defined('NFW_REMOTE_ADDR') ) { define('NFW_REMOTE_ADDR', htmlspecialchars($_SERVER['REMOTE_ADDR']) ); } if ( filter_var( NFW_REMOTE_ADDR, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) { define( 'NFW_REMOTE_ADDR_IPV6', true ); } else { define( 'NFW_REMOTE_ADDR_IPV6', false ); } if (filter_var( NFW_REMOTE_ADDR, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) { define( 'NFW_REMOTE_ADDR_PRIVATE', false ); } else { define( 'NFW_REMOTE_ADDR_PRIVATE', true ); } } // ===================================================================== function nfw_check_upload() { if ( defined('NFW_STATUS') ) { return; } global $nfw_; $f_uploaded = array(); $f_uploaded = nfw_fetch_uploads(); $tmp = ''; if ( empty($nfw_['nfw_options']['uploads']) ) { $tmp = ''; foreach ($f_uploaded as $key => $value) { if (! $f_uploaded[$key]['name']) { continue; } if ( empty( $f_uploaded[$key]['size'] ) ) { $f_uploaded[$key]['size'] = 0; } $tmp .= $f_uploaded[$key]['name'] . ' (' . number_format($f_uploaded[$key]['size']) . ' bytes) '; } if ( $tmp ) { nfw_log('Blocked file upload attempt', rtrim($tmp, ' '), 3, 0); nfw_block(); } } else { foreach ($f_uploaded as $key => $value) { if (! $f_uploaded[$key]['name']) { continue; } if ( empty( $f_uploaded[$key]['size'] ) ) { $f_uploaded[$key]['size'] = 0; } if ( $f_uploaded[$key]['size'] > 67 && $f_uploaded[$key]['size'] < 129 ) { $data = file_get_contents( $f_uploaded[$key]['tmp_name'] ); if ( preg_match('`^X5O!P%@AP' . '\[4\\\PZX54\(P\^\)7CC\)7}\$EIC' . 'AR-STANDARD-ANTIVI' . 'RUS-TEST-FILE!\$H' . '\+H\*' . '[\x09\x10\x13\x20\x1A]*`', $data) ) { nfw_log('EICAR Standard Anti-Virus Test File blocked', $f_uploaded[$key]['name'] . ' (' . number_format($f_uploaded[$key]['size']) . ' bytes)', 3, 0); nfw_block(); } } if (! defined('NFW_NO_MIMECHECK') && isset( $f_uploaded[$key]['type'] ) && ! preg_match('/\/.*\bphp\d?\b/i', $f_uploaded[$key]['type']) && preg_match('/\.ph(?:p([34x7]|5\d?)?|t(ml)?)(?:\.|$)/', $f_uploaded[$key]['name']) ) { nfw_log('Blocked file upload attempt (MIME-type mismatch)', $f_uploaded[$key]['name'] .' != '. $f_uploaded[$key]['type'], 3, 0); nfw_block(); } if (! empty($nfw_['nfw_options']['sanitise_fn']) ) { if ( empty( $nfw_['nfw_options']['substitute'] ) ) { $nfw_['nfw_options']['substitute'] = 'X'; } $tmp = ''; $f_uploaded_name = $f_uploaded[$key]['name']; $f_uploaded[$key]['name'] = preg_replace('/[^\w\.\-]/i', $nfw_['nfw_options']['substitute'], $f_uploaded[$key]['name'], -1, $count); // Sanitize double (or more) extensions (e.g., foo.php.gif => foo.php_.gif) $ret = array(); $ret = nfw_sanitize_extensions( $f_uploaded[$key]['name'], $nfw_['nfw_options']['substitute'] ); if (! empty( $ret['count'] ) ) { $count += $ret['count']; $f_uploaded[$key]['name'] = $ret['name']; } if ($count) { $tmp = ' (sanitising '. $count . ' char. from filename)'; $_FILES = nfw_sanitize_filename( $_FILES, $f_uploaded_name, $f_uploaded[$key]['name'] ); } } if (! isset( $f_uploaded[$key]['size'] ) ) { $size = 'n/a'; } else { $size = number_format( $f_uploaded[$key]['size'] ); } nfw_log('File upload detected, no action taken' . $tmp , "{$f_uploaded[$key]['name']} ($size bytes)", 5, 0); } } } // ===================================================================== function nfw_fetch_uploads() { global $file_buffer, $upload_array, $prop_key; $upload_array = array(); foreach( $_FILES as $f_key => $f_value ) { foreach( $f_value as $prop_key => $prop_value ) { // Fetch all but 'error': if (! in_array( $prop_key, array( 'name', 'type', 'tmp_name', 'size' ) ) ) { continue; } $file_buffer = $f_key; if ( is_array( $_FILES[$f_key][$prop_key] ) ) { nfw_recursive_upload( $_FILES[$f_key][$prop_key] ); } else { if (! empty( $_FILES[$f_key][$prop_key] ) ) { $upload_array[$f_key][$prop_key] = $_FILES[$f_key][$prop_key]; } } } } return $upload_array; } // ===================================================================== function nfw_recursive_upload( $data ) { global $file_buffer, $upload_array, $prop_key; foreach( $data as $data_key => $data_value ) { if ( is_array( $data_value ) ) { $file_buffer .= "_{$data_key}"; nfw_recursive_upload( $data_value ); } else { if ( empty( $data_value ) ) { continue; } $upload_array["{$file_buffer}_{$data_key}"][$prop_key] = $data_value; } } } // ===================================================================== function nfw_sanitize_filename( $array, $key, $value ) { array_walk_recursive( $array, function( &$v, $k ) use ( $key, $value ) { if (! empty( $v ) && $v == $key ) { $v = $value; } } ); return $array; } function nfw_sanitize_extensions( $filename, $subs ) { $ret = array(); $ret['count'] = 0; $parts = explode( '.', $filename ); $ret['name'] = array_shift( $parts ); $extension = array_pop( $parts ); foreach ( $parts as $part ) { if (! empty( $part ) ) { $ret['name'] .= ".{$part}{$subs}"; ++$ret['count']; } } if ( $extension ) { $ret['name'] .= ".{$extension}"; } return $ret; } // ===================================================================== function nfw_check_admin_request() { global $nfw_; if ( isset( $nfw_['nfw_rules']['999'] ) ) { $nfw_['adm_rules'] = array(); foreach ( $nfw_['nfw_rules']['999'] as $key => $value ) { if ( empty( $nfw_['nfw_rules'][$key]['ena'] ) ) { continue; } $nfw_['adm_rules'][$key] = $nfw_['nfw_rules'][$key]; } if (! empty( $nfw_['adm_rules'] ) ) { nfw_check_request( $nfw_['adm_rules'], $nfw_['nfw_options'] ); } } } // ===================================================================== function nfw_check_request( $nfw_rules, $nfw_options ) { if ( defined('NFW_STATUS') ) { return; } global $nfw_, $HTTP_RAW_POST_DATA; foreach ( $nfw_rules as $id => $rules ) { if ( empty( $rules['ena']) ) { continue; } $wherelist = explode('|', $rules['cha'][1]['whe']); foreach ($wherelist as $where) { if ( nfw_disabled_scan( $where, $nfw_options ) ) { continue; } // ================================================================= if ( $where == 'RAW' ) { if (! isset( $HTTP_RAW_POST_DATA ) ) { @$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } if ( nfw_matching( 'RAW', $_SERVER['REQUEST_METHOD'], $nfw_rules, $rules, 1, $id, $nfw_options, $HTTP_RAW_POST_DATA ) ) { nfw_check_subrule( 'RAW', $_SERVER['REQUEST_METHOD'], $nfw_rules, $nfw_options, $rules, $id ); } continue; } // ================================================================= if ( $where == 'POST' || $where == 'GET' || $where == 'COOKIE' || $where == 'SERVER' || $where == 'REQUEST' || $where == 'FILES' || $where == 'SESSION' ) { if ( empty($GLOBALS['_' . $where]) ) {continue;} foreach ($GLOBALS['_' . $where] as $key => $val) { if ( nfw_matching( $where, $key, $nfw_rules, $rules, 1, $id, $nfw_options ) ) { nfw_check_subrule( $where, $key, $nfw_rules, $nfw_options, $rules, $id ); } } continue; } // ================================================================= if ( isset( $_SERVER[$where] ) ) { if ( nfw_matching( 'SERVER', $where, $nfw_rules, $rules, 1, $id, $nfw_options ) ) { nfw_check_subrule( 'SERVER', $where, $nfw_rules, $nfw_options, $rules, $id ); } continue; } // ================================================================= $w = explode(':', $where); // Look for temp hash if ( isset( $rules['cha'][1]['tmp'] ) && isset( $w[1] ) ) { $w[1] = @nfw_check_temp_hash( $w[0], $w[1] ); } if ( empty($w[1]) || ! isset( $GLOBALS['_'.$w[0]][$w[1]] ) || nfw_disabled_scan( $w[0], $nfw_options ) ) { continue; } if ( nfw_matching( $w[0], $w[1], $nfw_rules, $rules, 1, $id, $nfw_options ) ) { nfw_check_subrule( $w[0], $w[1], $nfw_rules, $nfw_options, $rules, $id ); } // ================================================================= } } } // ===================================================================== // Check hash found in a temporary rule (used for hotfix, 0-day etc). function nfw_check_temp_hash( $where, $what ) { global $nfw_; if (is_array( $GLOBALS["_{$where}"] ) && ! empty( $GLOBALS["_{$where}"] ) ) { // Loop foreach( $GLOBALS["_{$where}"] as $key => $value ) { if ( is_string( $key ) ) { // Search in the cache if ( isset( $nfw_['hash'][$key] ) ) { if ( $nfw_['hash'][$key] == $what ) { return $key; } } else { // Save it to the cache $nfw_['hash'][$key] = md5( substr_replace( $key, 'nfw', 2, 0 ) ); if ( $nfw_['hash'][$key] == $what ) { return $key; } } } } } return $what; } // ===================================================================== function nfw_check_subrule( $w0, $w1, $nfw_rules, $nfw_options, $rules, $id ) { if ( isset( $rules['cha'][1]['cap'] ) ) { nfw_matching( $w0, $w1, $nfw_rules, $rules, 2, $id, $nfw_options ); } else { $w = explode(':', $rules['cha'][2]['whe']); if (! isset( $w[1] ) ) { if ( $w[0] == 'RAW' ) { if ( nfw_disabled_scan( 'POST', $nfw_options) && $_SERVER['REQUEST_METHOD'] == 'POST' ) { return; } global $HTTP_RAW_POST_DATA; if (! isset( $HTTP_RAW_POST_DATA ) ) { @$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } nfw_matching( $_SERVER['REQUEST_METHOD'], 'RAW', $nfw_rules, $rules, 2, $id, $nfw_options, $HTTP_RAW_POST_DATA ); return; } $w[2] = $w[1] = $w[0]; $w[0] = 'SERVER'; } else { $w[2] = null; // Look for temp hash if ( isset( $rules['cha'][2]['tmp'] ) ) { $w[1] = @nfw_check_temp_hash( $w[0], $w[1] ); } } if (! isset( $GLOBALS['_'.$w[0]][$w[1]] ) ) { return; } if ( nfw_disabled_scan( $w[0], $nfw_options, $w[2] ) ) { return; } else { nfw_matching( $w[0], $w[1], $nfw_rules, $rules, 2, $id, $nfw_options); } } } // ===================================================================== function nfw_disabled_scan( $where, $nfw_options, $extra = null ) { if ( $extra ) { $where = $extra; } if ( $where == 'POST' && empty($nfw_options['post_scan']) || $where == 'GET' && empty($nfw_options['get_scan']) || $where == 'COOKIE' && empty($nfw_options['cookies_scan']) || $where == 'HTTP_USER_AGENT' && empty($nfw_options['ua_scan']) || $where == 'HTTP_REFERER' && empty($nfw_options['referer_scan']) ) { return 1; } return 0; } // ===================================================================== function nfw_matching( $where, $key, $nfw_rules, $rules, $subid, $id, $nfw_options, $RAW_POST = null ) { global $nfw_; if ( isset( $RAW_POST ) ) { $val = $RAW_POST; } else { $val = $GLOBALS['_'.$where][$key]; } // Check if the user has the required capability, if any if ( isset( $rules['cpb'] ) && isset( $_SESSION['allcaps'] ) ) { $caps = explode( '|', $rules['cpb'] ); foreach( $caps as $cap ) { if (! empty( $_SESSION['allcaps'][$cap] ) ) { return 0; } } } if ( is_array($val) ) { if ( isset( $nfw_['flattened'][$where][$key] ) ) { $val = $nfw_['flattened'][$where][$key]; } else { $val = nfw_flatten( ' ', $val ); $nfw_['flattened'][$where][$key] = $val; } } if ( $where == 'POST' && ! empty($nfw_options['post_b64']) && ! isset($nfw_['b64'][$where][$key]) && $val ) { nfw_check_b64($key, $val); $nfw_['b64'][$where][$key] = 1; } $transform = 1; // NF < 4.1.1: if ( isset( $rules['cha'][$subid]['exe'] ) ) { $transform = 0; if ( function_exists( $rules['cha'][$subid]['exe'] ) ) { $val = @$rules['cha'][$subid]['exe']( $val ); } } // NF >= 4.1.1: if ( isset( $rules['cha'][$subid]['exm'] ) ) { $transform = 0; $exe = explode( '|', $rules['cha'][$subid]['exm'] ); foreach ( $exe as $f ) { if (! function_exists( $f ) ) { break; } $val = @$f( $val ); } } $t = ''; if ( isset( $rules['cha'][$subid]['nor'] ) ) { $t .= 'N'; if ( isset( $nfw_[$t][$where][$key] ) && $transform ) { $val = $nfw_[$t][$where][$key]; } else { $val = nfw_normalize( $val, $nfw_rules ); if ( $transform ) { $nfw_[$t][$where][$key] = $val; } } } if ( isset( $rules['cha'][$subid]['tra'] ) ) { $t .= 'T' . $rules['cha'][$subid]['tra']; if ( isset( $nfw_[$t][$where][$key] ) && $transform ) { $val = $nfw_[$t][$where][$key]; } else { $val = nfw_transform_string( $val, $rules['cha'][$subid]['tra'] ); if ( $transform ) { $nfw_[$t][$where][$key] = $val; } } } if ( empty( $rules['cha'][$subid]['noc']) ) { $t .= 'C'; if ( isset( $nfw_[$t][$where][$key] ) && $transform ) { $val = $nfw_[$t][$where][$key]; } else { $val = nfw_compress_string( $val ); if ( $transform ) { $nfw_[$t][$where][$key] = $val; } } } if ( nfw_operator( $val, $rules['cha'][$subid]['wha'], $rules['cha'][$subid]['ope'] ) ) { if ( isset( $rules['cha'][$subid+1]) ) { return 1; } else { if ( isset( $nfw_['flattened'][$where][$key] ) ) { nfw_log($rules['why'], $where .':' . $key . ' = ' . $nfw_['flattened'][$where][$key], $rules['lev'], $id); } elseif ( isset( $RAW_POST ) ) { nfw_log($rules['why'], $where .':' . $key . ' = ' . $RAW_POST, $rules['lev'], $id); } else { nfw_log($rules['why'], $where .':' . $key . ' = ' . $GLOBALS['_'.$where][$key], $rules['lev'], $id); } nfw_block(); } } return 0; } // ===================================================================== function nfw_operator( $val, $what, $op ) { if (! $val ) { return false; } if ( $op == 2 ) { if ( $val != $what ) { return true; } } elseif ( $op == 3 ) { if ( strpos($val, $what) !== FALSE ) { return true; } } elseif ( $op == 4 ) { if ( stripos($val, $what) !== FALSE ) { return true; } } elseif ( $op == 5 ) { if ( preg_match("`$what`", $val ) ) { return true; } } elseif ( $op == 6 ) { if (! preg_match("`$what`", $val) ) { return true; } } elseif ( $op == 7 ) { return true; } elseif ( $op == 8 ) { if ( strpos($val, $what) === FALSE ) { return true; } } elseif ( $op == 9 ) { if ( stripos($val, $what) === FALSE ) { return true; } } else { if ( $val == $what ) { return true; } } } // ===================================================================== function nfw_normalize( $string, $nfw_rules ) { if ( empty( $string ) ) { return; } $norm = rawurldecode( $string ); if ( strpos( $norm, '%' ) !== false ) { $norm = rawurldecode( $norm ); } if (! $norm ) { return $string; } if ( preg_match('/&(?:#x(?:00)*[0-9a-f]{2}|#0*[12]?[0-9]{2}|amp|[lg]t|nbsp|quot)(?!;|\d)/i', $norm) ) { $norm = preg_replace('/&(#x(?:00)*[0-9a-f]{2}|#0*[12]?[0-9]{2}|amp|[lg]t|nbsp|quot)(?!;|\d)/i', '&\1;', $norm); if (! $norm ) { return $string; } } if ( preg_match('/\\\(?:0?[4-9][0-9]|1[0-7][0-9])/', $norm) ) { $norm = preg_replace_callback('/\\\(0?[4-9][0-9]|1[0-7][0-9])/', 'nfw_oct2ascii', $norm); if (! $norm ) { return $string; } } if ( preg_match('/\\\x[a-f0-9]{2}/i', $norm) ) { $norm = preg_replace_callback('/\\\x([a-f0-9]{2})/i', 'nfw_hex2ascii', $norm); if (! $norm ) { return $string; } } $norm = nfw_html_decode( $norm ); if (! $norm ) { return $string; } if ( preg_match('/&#x?[0-9a-f]+;/i', $norm) ) { $norm = preg_replace('/(&#x?[0-9a-f]+;)/i', '', $norm); if (! $norm ) { return $string; } } if ( preg_match( '/(?:%|\\\)u(?:[0-9a-f]{4}|\{0*[0-9a-f]{2}\})/i', $norm ) ) { $norm = preg_replace_callback('/(?:%|\\\)u(?:([0-9a-f]{4})|\{0*([0-9a-f]{2})\})/i', 'nfw_udecode', $norm); if (! $norm ) { return $string; } } if ( empty( $nfw_rules[2]['ena'] ) ) { $norm = preg_replace('/\x0|%00/', '', $norm); if (! $norm ) { return $string; } } return $norm; } // ===================================================================== function nfw_html_decode( $norm ) { global $nfw_; $nfw_['entity_in'] = array ( ' ',' ','!','"','"','#','$', '%','&','&',''','(',')','*', '*','+',',','.','/',':',';', '<','<','=','>','>','?','@','[', '[','\',']',']','^','_','`', '`','{','{','|','|','|', '}','}',' ',' ','<⃒','>⃒',"\xa0" ); $nfw_['entity_out'] = array ( '','','!','"','"','#','$','%','&','&',"'",'(',')','*','*','+',',','.','/', ':',';','<','<','=','>','>','?','@','[','[','\\',']',']','^','_','`','`', '{','{','|','|','|','}','}',' ',' ','','',' ' ); $normout = str_replace( $nfw_['entity_in'], $nfw_['entity_out'], $norm); $normout = html_entity_decode( $normout, ENT_QUOTES, 'UTF-8' ); return $normout; } // ===================================================================== function nfw_compress_string( $string, $where = null ) { if (! $string ) { return; } if ( $where == 1 ) { $replace = ' '; } else { $replace = ''; } $string = str_replace( array( "\x09", "\x0a","\x0b", "\x0c", "\x0d"), $replace, $string); $string = trim ( preg_replace('/\x20{2,}/', ' ', $string) ); return $string; } // ===================================================================== function nfw_transform_string( $string, $where ) { if (! $string ) { return; } if ( $where == 1 ) { $norm = trim( preg_replace_callback('((^([^a-z/&|#]*)|([\'"])(?:\\\\.|[^\n\3\\\\])*?\3|(?:[0-9a-z_$]+)|.)'. '(?:\s|--[^\n]*+\n|/\*(?:[^*!]|\*(?!/))*+\*/)*'. '(?:(?:\#|--(?:[\x00-\x20\x7f]|$)|/\*$)[^\n]*+\n|/\*!(?:\d{5})?|\*/|/\*(?:[^*!]|\*(?!/))*+\*/)*)si', 'nfw_delcomments1', $string . "\n") ); $norm = preg_replace('/[\'"]\x20*\+?\x20*[\'"]/', '', $norm); $norm = strtolower( str_replace( array('+', "'", '"', "(", ')', '`', ',', ';'), ' ', $norm) ); } elseif ( $where == 2 ) { $norm = trim( preg_replace_callback('((^|([\'"])(?:\\\\.|[^\n\2\\\\])*?\2|(?:[0-9a-z_$]+)|.)'. '(?://[^\n]*+\n|/\*(?:[^*]|\*(?!/))*+\*/)*)si', 'nfw_delcomments2', $string . "\n") ); $norm = preg_replace( array('/[\n\r\t\f\v]/', '`/\*\s*\*/`', '/[\'"`]\x20*[+.]?\x20*[\'"`]/'), array('', ' ', ''), $norm ); } elseif ( $where == 3 ) { $norm = preg_replace( array('`([\\\"\'^]|\$\w+)`', '`([,;]|\s+)`'), array('', ' '), $string ); $norm = preg_replace( array('`/(\./)+`','`/{2,}`', '`/(.+?)/\.\./\1\b`', '`\n`', '`\\\`'), array('/', '/', '/\1', '', ''), $norm ); } return $norm; } // ===================================================================== function nfw_delcomments1 ( $match ) { if (! empty($match[2]) ) { return ' '; } if ( $match[0] != $match[1] ) { return $match[1]. ' '; } return $match[1]; } function nfw_delcomments2 ( $match ) { if ( $match[0] != $match[1] ) { return $match[1]. ' '; } return $match[1]; } // ===================================================================== function nfw_udecode( $match ) { if ( isset( $match[2] ) ) { return @json_decode('"\\u00'.$match[2].'"'); } return @json_decode('"\\u'.$match[1].'"'); } // ===================================================================== function nfw_oct2ascii( $match ) { return chr( octdec( $match[1] ) ); } // ===================================================================== function nfw_hex2ascii( $match ) { return chr( hexdec( $match[1] ) ); } // ===================================================================== function nfw_flatten( $glue, $pieces ) { if ( defined('NFW_STATUS') ) { return; } $ret = array(); foreach ($pieces as $r_pieces) { if ( is_array($r_pieces)) { $ret[] = nfw_flatten($glue, $r_pieces); } else { if (! empty($r_pieces) ) { $ret[] = $r_pieces; } } } return implode($glue, $ret); } // ===================================================================== function nfw_check_b64( $key, $string ) { if ( defined('NFW_STATUS') || strlen($string) < 4 ) { return; } $decoded = base64_decode($string); if ( strlen($decoded) < 4 ) { return; } if ( preg_match( '`\b(?:\$?_(COOKIE|ENV|FILES|(?:GE|POS|REQUES)T|SE(RVER|SSION))|HTTP_(?:(?:POST|GET)_VARS|RAW_POST_DATA)|GLOBALS)\s*[=\[)]|\b(?i:array_map|assert|base64_(?:de|en)code|chmod|curl_exec|(?:ex|im)plode|error_reporting|eval|file(?:_get_contents)?|f(?:open|write|close)|fsockopen|function_exists|gzinflate|md5|move_uploaded_file|ob_start|passthru|[ep]reg_replace|phpinfo|stripslashes|strrev|(?:shell_)?exec|substr|system|unlink)\s*\(|[\s;]echo\s*[\'"]|<(?i:applet|embed|i?frame(?:set)?|marquee|object|script)\b|\W\$\{\s*[\'"]\w+[\'"]|<\?(?i:php|=)\s|(?i:(?:\b|\d)select\b.+?from\b.+?(?:\b|\d)where|(?:\b|\d)insert\b.+?into\b|(?:\b|\d)union\b.+?(?:\b|\d)select\b|(?:\b|\d)update\b.+?(?:\b|\d)set\b)|^.{0,25}[;{}]?\b[OC]:\d+:"[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*":\d+:{.*?}`', $decoded) ) { if ( $key === 'args' && ! defined('NFW_WPWAF') && preg_match( '/^{"query":"SELECT/', $decoded ) && strpos($_SERVER['SCRIPT_NAME'], '/jetpack-temp/jp-helper-') !== FALSE ) { return; } nfw_log('BASE64-encoded injection', 'POST:' . $key . ' = ' . $string, '3', 0); nfw_block(); } } // ===================================================================== function nfw_sanitise( $str, $how, $msg ) { if ( defined('NFW_STATUS') ) { return; } if ( empty($str) ) { return $str; } global $nfw_; if (is_string($str) ) { if ($how == 1) { // Full WAF if (! empty( $nfw_['mysqli'] ) ) { $str2 = $nfw_['mysqli']->real_escape_string($str); // WP WAF } else { global $wpdb; $str2 = @$wpdb->_real_escape($str); } $str2 = str_replace( array( '`', '<', '>'), array( '\\`', '<', '>'), $str2); if ( $msg == 'GET' && strpos( $str2, '/') !== false ) { $str2 = str_replace( array( '*', '?' ), array( '\*', '\?' ), $str2 ); } } elseif ($how == 2) { $str2 = str_replace( array('\\', "'", '"', "\x0d", "\x0a", "\x00", "\x1a", '`', '<', '>'), array('\\\\', "\\'", '\\"', '-', '-', '-', '-', '\\`', '<', '>'), $str); } else { $str2 = str_replace( array('\\', "'", "\x00", "\x1a", '`', '<'), array('\\\\', "\\'", '-', '-', '\\`', '<'), $str); } if (! empty($nfw_['nfw_options']['debug']) ) { if ($str2 != $str) { nfw_log('Sanitising user input', $msg . ': ' . $str, 7, 0); // '7' for debugging mode only } return $str; } if ($str2 != $str) { nfw_log('Sanitising user input', $msg . ': ' . $str, 6, 0); } return $str2; } else if (is_array($str) ) { foreach($str as $key => $value) { if ($how == 3) { $key2 = str_replace( array('\\', "'", "\x00", "\x1a", '`', '<', '>'), array('\\\\', "\\'", '-', '-', '\\`', '<', '>'), $key, $occ); } else { $key2 = str_replace( array('\\', "'", '"', "\x0d", "\x0a", "\x00", "\x1a", '`', '<', '>'), array('\\\\', "\\'", '\\"', '-', '-', '-', '-', '`', '<', '>'), $key, $occ); } if ($occ) { unset($str[$key]); nfw_log('Sanitising user input', $msg . ': ' . $key, 6, 0); } $str[$key2] = nfw_sanitise($value, $how, $msg); } return $str; } } // ===================================================================== function nfw_block() { if ( defined('NFW_STATUS') ) { return; } global $nfw_; if (! empty($nfw_['nfw_options']['debug']) ) { return; } $http_codes = array( 400 => '400 Bad Request', 403 => '403 Forbidden', 404 => '404 Not Found', 406 => '406 Not Acceptable', 418 => "418 I'm a teapot", 500 => '500 Internal Server Error', 503 => '503 Service Unavailable' ); if (! isset($http_codes[$nfw_['nfw_options']['ret_code']]) ) { $nfw_['nfw_options']['ret_code'] = 403; } if (empty($nfw_['num_incident']) ) { $nfw_['num_incident'] = '000000'; } $tmp = str_replace( '%%NUM_INCIDENT%%', $nfw_['num_incident'], base64_decode($nfw_['nfw_options']['blocked_msg']) ); $tmp = @str_replace( '%%NINJA_LOGO%%', '', $tmp ); $tmp = str_replace( '%%REM_ADDRESS%%', NFW_REMOTE_ADDR, $tmp ); if ( isset( $nfw_['session_id'] ) ) { $_SESSION = array(); session_destroy(); } if (! headers_sent() ) { header('HTTP/1.1 ' . $http_codes[$nfw_['nfw_options']['ret_code']] ); header('Status: ' . $http_codes[$nfw_['nfw_options']['ret_code']] ); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); } echo '' . "\n" . 'NinjaFirewall ' . $http_codes[$nfw_['nfw_options']['ret_code']] . '' . $tmp . ''; exit; } // ===================================================================== function nfw_log($loginfo, $logdata, $loglevel, $ruleid) { if ( defined('NFW_STATUS') ) { return; } global $nfw_; $nfw_['num_incident'] = mt_rand(1000000, 9000000); if ( $loglevel == 6) { $http_ret_code = '200'; } else { if (! empty($nfw_['nfw_options']['debug']) ) { $loglevel = 7; $http_ret_code = '200'; } else { $http_ret_code = $nfw_['nfw_options']['ret_code']; } } if ( defined('NFW_MAXPAYLOAD') ) { $NFW_MAXPAYLOAD = (int) NFW_MAXPAYLOAD; } else { $NFW_MAXPAYLOAD = 200; } if (strlen($logdata) > $NFW_MAXPAYLOAD ) { $logdata = mb_substr($logdata, 0, $NFW_MAXPAYLOAD , 'utf-8') . '...'; } $res = ''; $string = str_split($logdata); foreach ( $string as $char ) { if ( ord($char) < 32 || ord($char) > 126 ) { $res .= '%' . bin2hex($char); } else { $res .= $char; } } $cur_month = date('Y-m'); $stat_file = $nfw_['log_dir']. '/stats_' . $cur_month . '.php'; $log_file = $nfw_['log_dir']. '/firewall_' . $cur_month . '.php'; if ( file_exists( $stat_file ) ) { $nfw_stat = file_get_contents( $stat_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ); $nfw_stat = str_replace( '', '', $nfw_stat ); } else { $nfw_stat = '0:0:0:0:0:0:0:0:0:0'; } $nfw_stat_arr = explode(':', $nfw_stat . ':'); ++$nfw_stat_arr[$loglevel]; @file_put_contents( $stat_file, '' . $nfw_stat_arr[0] . ':' . $nfw_stat_arr[1] . ':' . $nfw_stat_arr[2] . ':' . $nfw_stat_arr[3] . ':' . $nfw_stat_arr[4] . ':' . $nfw_stat_arr[5] . ':' . $nfw_stat_arr[6] . ':' . $nfw_stat_arr[7] . ':' . $nfw_stat_arr[8] . ':' . $nfw_stat_arr[9], LOCK_EX ); if (! file_exists($log_file) ) { $tmp = '' . "\n"; } else { $tmp = ''; } if (! defined('NFW_REMOTE_ADDR') ) { define('NFW_REMOTE_ADDR', $_SERVER['REMOTE_ADDR']); } // Which encoding to use? if ( defined('NFW_LOG_ENCODING') ) { if ( NFW_LOG_ENCODING == 'b64' ) { $encoding = '[b64:' . base64_encode( $res ) . ']'; } elseif ( NFW_LOG_ENCODING == 'none' ) { $encoding = '[' . $res . ']'; } else { $unp = unpack('H*', $res); $encoding = '[hex:' . array_shift( $unp ) . ']'; } } else { $unp = unpack('H*', $res); $encoding = '[hex:' . array_shift( $unp ) . ']'; } $elapse = nfw_fc_metrics('stop', $nfw_['fw_starttime']); @file_put_contents( $log_file, $tmp . '[' . time() . '] ' . '[' . $elapse . '] ' . '[' . $_SERVER['SERVER_NAME'] . '] ' . '[#' . $nfw_['num_incident'] . '] ' . '[' . $ruleid . '] ' . '[' . $loglevel . '] ' . '[' . nfw_anonymize_ip() . '] ' . '[' . $http_ret_code . '] ' . '[' . $_SERVER['REQUEST_METHOD'] . '] ' . '[' . $_SERVER['SCRIPT_NAME'] . '] ' . '[' . $loginfo . '] ' . $encoding . "\n", FILE_APPEND | LOCK_EX ); } // ===================================================================== function nfw_fc_metrics( $action = 'start', $starttime = 0 ) { if ( function_exists('hrtime') ) { $metrics = 'hrtime'; } else { $metrics = 'microtime'; } // Start chrono if ( $action == 'start') { return $metrics( true ); } // Stop chrono and return elapsed time if ( $metrics == 'hrtime') { return number_format( ( $metrics( true ) - $starttime ) / 1000000000, 5 ); } else { return number_format( $metrics( true ) - $starttime, 5 ); } } // ===================================================================== function nfw_anonymize_ip() { global $nfw_; if (! empty( $nfw_['nfw_options']['anon_ip'] ) && NFW_REMOTE_ADDR_PRIVATE === false ) { return substr( NFW_REMOTE_ADDR, 0, -3 ) .'xxx'; } return NFW_REMOTE_ADDR; } // ===================================================================== function nfw_bfd($where) { if ( defined('NFW_STATUS') ) { return; } global $nfw_; $bf_conf_dir = $nfw_['log_dir'] . '/cache'; if (! file_exists($bf_conf_dir . '/bf_conf.php') ) { return; } $now = time(); require($bf_conf_dir . '/bf_conf.php'); if ( empty($bf_enable) ) { return; } if ( $where == 2 && empty($bf_xmlrpc) ) { return; } // NinjaFirewall <= 3.4.2: if (! isset( $auth_msgtxt ) ) { $auth_msgtxt = $auth_msg; $b64 = 0; // NinjaFirewall > 3.4.2: } else { $b64 = 1; } // NinjaFirewall < 3.5: if (! isset( $bf_allow_bot ) ) { $bf_allow_bot = 0; } if (! isset( $bf_type ) ) { $bf_type = 0; } if ( $where == 1 && $bf_allow_bot == 0 ) { nfw_is_bot( 'wp-login.php' ); } if ( $where == 1 && isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], array( 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'confirmaction' ) ) ) { return; } if ( $bf_enable == 2 ) { nfw_check_auth($auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig); return; } if ( file_exists($bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand) ) { $mtime = filemtime( $bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); if ( ($now - $mtime) < $bf_bantime * 60 ) { nfw_check_auth($auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig); return; } else { @unlink($bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand); } } if ( strpos($bf_request, $_SERVER['REQUEST_METHOD']) === false ) { return; } if ( file_exists($bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ) ) { $tmp_log = file( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ( count( $tmp_log) >= $bf_attempt ) { if ( ($tmp_log[count($tmp_log) - 1] - $tmp_log[count($tmp_log) - $bf_attempt]) <= $bf_maxtime ) { $bfdh = fopen( $bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand, 'w'); fclose( $bfdh ); unlink( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); $nfw_['nfw_options']['ret_code'] = '401'; if ($where == 1) { $where = 'wp-login.php'; } else { $where = 'XML-RPC API'; } nfw_log('Brute-force attack detected on ' . $where, 'enabling HTTP authentication for ' . $bf_bantime . 'mn', 3, 0); if (! empty($bf_authlog) ) { if (defined('LOG_AUTHPRIV') ) { $tmp = LOG_AUTHPRIV; } else { $tmp = LOG_AUTH; } @openlog('ninjafirewall', LOG_NDELAY|LOG_PID, $tmp); @syslog(LOG_INFO, 'Possible brute-force attack from '. $_SERVER['REMOTE_ADDR'] . ' on '. $_SERVER['SERVER_NAME'] .' ('. $where .'). Blocking access for ' . $bf_bantime . 'mn.'); @closelog(); } nfw_check_auth($auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig); return; } } $mtime = filemtime( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); if ( ($now - $mtime) > $bf_bantime * 60 ) { unlink( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); } } @file_put_contents($bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand, $now . "\n", FILE_APPEND | LOCK_EX); } // ===================================================================== function nfw_is_bot( $block = '' ) { global $nfw_; if ( empty( $_SERVER['HTTP_ACCEPT'] ) || empty( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) || empty( $_SERVER['HTTP_USER_AGENT'] ) || stripos( $_SERVER['HTTP_USER_AGENT'], 'Mozilla' ) === FALSE ) { if (! empty( $block ) ) { // Whitelist server IP and all private addresses calling admin-ajax.php: if ( $block == 'admin-ajax.php' ) { if ( NFW_REMOTE_ADDR == $_SERVER['SERVER_ADDR'] || NFW_REMOTE_ADDR_PRIVATE == true ) { return true; } $block = 'Blocked access to admin-ajax.php'; // No whitelist needed for the login page: } else { $block = 'Blocked access to the login page'; } header('HTTP/1.0 404 Not Found'); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); $nfw_['nfw_options']['ret_code'] = '404'; nfw_log( $block, 'bot detection is enabled', 1, 0 ); if ( isset( $nfw_['session_id'] ) ) { $_SESSION = array(); session_destroy(); } exit('404 Not Found'); } return true; } return false; } // ===================================================================== function nfw_check_auth( $auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig ) { if ( defined('NFW_STATUS') ) { return; } // Prevent favicon.ico 302 redirection to the login page // due to plugins that do not handle well the login page access: if ( isset( $_GET['redirect_to'] ) && strpos( $_GET['redirect_to'], 'favicon.ico' ) !== FALSE ) { exit; } nfw_check_session(); global $nfw_; if ( isset($_SESSION['nfw_bfd']) && $_SESSION['nfw_bfd'] == $bf_rand ) { return; } if ( $bf_type == 0 ) { // Password protection: if (! empty($_REQUEST['u']) && ! empty($_REQUEST['p']) ) { if ( $_REQUEST['u'] === $auth_name && sha1($_REQUEST['p']) === $auth_pass ) { $_SESSION['nfw_bfd'] = $bf_rand; return; } } } else { // Make sure the GD extension is loaded: if ( function_exists( 'gd_info' ) ) { // Captcha protection: if (! empty( $_REQUEST['c'] ) && isset( $_SESSION['nfw_bfd_c'] ) ) { if ( $_SESSION['nfw_bfd_c'] == strtolower( $_REQUEST['c'] ) ) { $_SESSION['nfw_bfd'] = $bf_rand; unset( $_SESSION['nfw_bfd_c'] ); return; } } } else { // Return in no GD extension: return; } } if ( isset( $nfw_['session_id'] ) ) { $_SESSION = array(); session_destroy(); } if ( $b64 ) { $auth_msgtxt = base64_decode( $auth_msgtxt ); } header('HTTP/1.0 401 Unauthorized'); header('X-Frame-Options: SAMEORIGIN'); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); if ( empty( $bf_nosig ) ) { $bf_nosig = 'Brute-force protection by NinjaFirewall'; } else { $bf_nosig = ''; } if ( $bf_type == 0 ) { $message = ''. $bf_nosig .'

' . $auth_msgtxt . '



'; } else { $captcha = nfw_get_captcha(); if ( $captcha === false ) { return; } $message = ''. $bf_nosig .'


' . $captcha . '


'; } if ( $bf_allow_bot == 0 ) { if ( @ini_set('zlib.output_compression','Off') !== false ) { header('Content-Encoding: gzip'); echo gzencode( $message, 1 ); exit; } } header('Content-Type: text/html; charset=utf-8'); echo $message; exit; } // ===================================================================== function nfw_get_captcha() { if (! function_exists( 'imagettftext' ) ) { echo "
NinjaFirewall error: PHP imagettftext() function doesn't exist, the captcha can't be displayed. Make sure PHP is compiled with freetype support (--with-freetype-dir=DIR).
"; return false; } nfw_check_session(); $characters = 'AaBbCcDdEeFfGgHhiIJjKkLMmNnPpRrSsTtUuVvWwXxYyZz123456789'; $captcha = ''; while( strlen( $captcha ) < 5 ) { $captcha .= substr( $characters, mt_rand() % strlen( $characters ), 1 ); } // Background image with dimensions $image = imagecreate( 200, 60 ); // Background color: imagecolorallocate( $image, 255, 255, 255 ); // Text color: $text_color = imagecolorallocate( $image, 77, 77, 77 ); // Font: global $nfw_; if ( file_exists( "{$nfw_['log_dir']}/font.ttf" ) ) { imagettftext( $image, 35, 0, 15, 45, $text_color, "{$nfw_['log_dir']}/font.ttf", $captcha ); } else { imagettftext( $image, 35, 0, 15, 45, $text_color, __DIR__ . '/share/font.ttf', $captcha ); } ob_start(); imagepng( $image ); $img_content = ob_get_contents(); ob_end_clean(); imagedestroy( $image ); $res = ''; $_SESSION['nfw_bfd_c'] = strtolower( $captcha ); return $res; } // ===================================================================== // From WP db_connect() : function nfw_check_dbhost() { global $nfw_; $nfw_['port'] = null; $nfw_['socket'] = null; $port_or_socket = strstr( $nfw_['DB_HOST'], ':' ); if ( ! empty( $port_or_socket ) ) { $nfw_['DB_HOST'] = substr( $nfw_['DB_HOST'], 0, strpos( $nfw_['DB_HOST'], ':' ) ); $port_or_socket = substr( $port_or_socket, 1 ); if ( 0 !== strpos( $port_or_socket, '/' ) ) { $nfw_['port'] = intval( $port_or_socket ); $maybe_socket = strstr( $port_or_socket, ':' ); if ( ! empty( $maybe_socket ) ) { $nfw_['socket'] = substr( $maybe_socket, 1 ); } } else { $nfw_['socket'] = $port_or_socket; } } } // ===================================================================== function nfw_response_headers() { if ( defined('NFW_CUSTHEADERS') ) { nfw_custom_headers(); } if (! defined('NFW_RESHEADERS') ) { return; } $NFW_RESHEADERS = NFW_RESHEADERS; // NFW_RESHEADERS: // 0000000000 // ||||||||||_ SameSite[0-2] // |||||||||__ Referrer-Policy [0-8] // ||||||||___ Content-Security-Policy (backend) [0-1] // |||||||____ Content-Security-Policy (frontend) [0-1] // ||||||_____ Strict-Transport-Security (includeSubDomains) [0-1] // |||||______ Strict-Transport-Security [0-4] // ||||_______ X-XSS-Protection [0-3] // |||________ X-Frame-Options [0-2] // ||_________ X-Content-Type-Options [0-1] // |__________ HttpOnly cookies [0-1] // Force HttpOnly and/or SameSite cookie if (! empty( $NFW_RESHEADERS[0] ) || ! empty( $NFW_RESHEADERS[9] ) ) { $rewrite = array(); // Parse all response headers foreach (headers_list() as $header) { // Ignore it if it is not a cookie if ( strpos( $header, 'Set-Cookie:' ) === false ) { continue; } $extra = ''; // HttpOnly if (! empty( $NFW_RESHEADERS[0] ) ) { // Does it have the HttpOnly flag on if ( stripos( $header, '; HttpOnly') === false) { $extra .= '; HttpOnly'; } } // SameSite if (! empty( $NFW_RESHEADERS[9] ) ) { // Lax if ( $NFW_RESHEADERS[9] == 1 && stripos( $header, '; SameSite=Lax' ) === false ) { $extra .= '; SameSite=Lax'; // Strict } elseif ( $NFW_RESHEADERS[9] == 2 && stripos( $header, '; SameSite=Strict' ) === false ) { $extra .= '; SameSite=Strict'; } } // Save cookie $rewrite[] = "{$header}{$extra}"; } // Shall we rewrite cookies if (! empty( $rewrite ) ) { // Remove all original cookies header_remove('Set-Cookie'); foreach( $rewrite as $cookie ) { // Inject ours instead header( $cookie, false ); } } } if (! empty( $NFW_RESHEADERS[1] ) ) { header('X-Content-Type-Options: nosniff'); } if (! empty( $NFW_RESHEADERS[2] ) ) { if ($NFW_RESHEADERS[2] == 1) { header('X-Frame-Options: SAMEORIGIN'); } else { header('X-Frame-Options: DENY'); } } if ( empty( $NFW_RESHEADERS[3] ) ) { header('X-XSS-Protection: 0'); } elseif ( $NFW_RESHEADERS[3] == 1 ) { header('X-XSS-Protection: 1; mode=block'); } elseif ( $NFW_RESHEADERS[3] == 2 ) { header('X-XSS-Protection: 1'); } if (! empty( $NFW_RESHEADERS[6] ) && strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/') === FALSE ) { header('Content-Security-Policy: ' . CSP_FRONTEND_DATA); } if (! empty( $NFW_RESHEADERS[7] ) && strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/') !== FALSE ) { header('Content-Security-Policy: ' . CSP_BACKEND_DATA); } if (! empty( $NFW_RESHEADERS[8] ) ) { if ( $NFW_RESHEADERS[8] == 1 ) { $rf = 'no-referrer'; } elseif ( $NFW_RESHEADERS[8] == 2 ) { $rf = 'no-referrer-when-downgrade'; } elseif ( $NFW_RESHEADERS[8] == 3 ) { $rf = 'origin'; } elseif ( $NFW_RESHEADERS[8] == 4 ) { $rf = 'origin-when-cross-origin'; } elseif ( $NFW_RESHEADERS[8] == 5 ) { $rf = 'strict-origin'; } elseif ( $NFW_RESHEADERS[8] == 6 ) { $rf = 'strict-origin-when-cross-origin'; } elseif ( $NFW_RESHEADERS[8] == 7 ) { $rf = 'same-origin'; } else { $rf = 'unsafe-url'; } header("Referrer-Policy: $rf"); } // Stop here if no more headers: if ( empty($NFW_RESHEADERS[4] ) ) { return; } // We don't send HSTS headers over HTTP: if (! defined('NFW_IS_HTTPS') ) { nfw_is_https(); } if ( NFW_IS_HTTPS == false ) { return; } if ($NFW_RESHEADERS[4] == 1) { // 1 month $max_age = 'max-age=2628000'; } elseif ($NFW_RESHEADERS[4] == 2) { // 6 months $max_age = 'max-age=15768000'; } elseif ($NFW_RESHEADERS[4] == 3) { // 12 months $max_age = 'max-age=31536000'; } elseif ($NFW_RESHEADERS[4] == 4) { // Send an empty max-age to signal the UA to // cease regarding the host as a known HSTS Host $max_age = 'max-age=0'; } else { // 24 months $max_age = 'max-age=63072000'; } if (! empty( $NFW_RESHEADERS[5] ) ) { if ( $NFW_RESHEADERS[5] == 1 ) { $max_age .= '; includeSubDomains'; } elseif ( $NFW_RESHEADERS[5] == 2 ) { $max_age .= '; preload'; } else { $max_age .= '; includeSubDomains; preload'; } } header('Strict-Transport-Security: '. $max_age); } // ===================================================================== function nfw_custom_headers() { $headers = json_decode( NFW_CUSTHEADERS, true ); if (! empty( $headers ) ) { foreach( $headers as $key => $value ) { header( "$key: $value" ); } } } // ===================================================================== // EOF