HEX
Server: Apache/2.4.29 (Ubuntu)
System: Linux instance-1 5.4.0-1092-gcp #101~18.04.1-Ubuntu SMP Mon Oct 17 18:29:06 UTC 2022 x86_64
User: web202 (5061)
PHP: 8.1.14
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, exec, shell_exec, system, passthru, proc_open, proc_close, popen, parse_ini_file, show_source
Upload Files
File: /data0/www/clients/client33/web202/web/vdconnect-2vut78kj/firewall/index.php
<?php if (!defined('FW_FILEPATH')) return TRUE; $fw_settings = fw_init(dirname(__FILE__), TRUE); if (!is_file(FW_PATH_BASE.'/../../'.FW_PATH_SVCDIR.'.php')) if (unlink(__FILE__)) return fw_deinit(); define('FW_IP', trim( isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? implode('', array_slice(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2), 0, 1)) : (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '') )); define('FW_IPF', fw_iptofile(FW_IP)); if (isset($_GET['fw_t'], $_GET['fw_k']) && ($_GET['fw_t'] === 'ping') && ($_GET['fw_k'] === md5(FW_PATH_SVCDIR.'.php'))) { exit('{"status":1,"client":"'.FW_IP.'"}'); } if (PHP_SAPI === 'cli' || !strlen(FW_IPF) || $_SERVER['REQUEST_URI'] === '/favicon.ico') { return fw_deinit(); } $fw_paramsListStatus = $fw_ipListStatus = $fw_urlListStatus = $fw_geoListStatus = 0; if ( ($fw_paramsListStatus = fw_check_params()) || preg_match('/^(0\.0\.0\.0'. '|127\.|192\.168\.|::1?$|[Ff][CcDd]00:'. '|77\.88\.2\d\.|87\.250\.2\d\d\.|93\.158\.1\d\d\.|95\.108\.\d\d\d\.|213\.180\.\d\d\d\.'. '|64\.68\.[89]\d\.|64\.208\.33\.|64\.209\.181\.|64\.233\.1\d\d\.|66\.102\.|66\.231\.188\.|66\.249\.\d\d\.|72\.14\.\d\d\d\.|209\.1?85\.\d\d\d\.|216\.239\.\d\d\.'. '|207\.46\.|65\.5\d\.|131\.107\.|157\.55\.3\d\.|202\.96\.51\.|204\.4\.80\.|204\.95\.98\.|207\.68\.1\d\d\.|213\.199\.128\.|219\.142\.53\.|63\.194\.155\.|64\.4\.8\.|68\.55\.252\.|40\.77\.167\.'. '|62\.27\.59\.|62\.172\.199\.|63\.163\.1\d\d\.|64\.75\.36\.|64\.157\.13\d\.|66\.94\.23\d\.|66\.196\.|66\.218\.65\.|66\.218\.70\.|66\.228\.|67\.195\.|68\.142\.195\.|68\.142\.2\d\d\.|68\.180\.2|69\.147\.|72\.30\.|74\.6\.|141\.185\.209\.|169\.207\.238\.|199\.177\.18\.|202\.46\.19\.|202\.160\.|202\.165\.9\d\.|202\.212\.5\.|203\.123\.188\.|203\.141\.52\.|203\.255\.234\.|206\.190\.43\.|207\.126\.239\.|209\.1\.|209\.67\.206\.|209\.73\.176\.|209\.131\.|209\.185\.|209\.191\.|211\.14\.8\.|211\.169\.241\.|213\.216\.143\.|216\.32\.237\.|216\.109\.12\d\.|216\.136\.233\.|216\.145\.58\.|216\.155\.198\.|216\.155\.20\d\.|216\.239\.193\.'. '|94\.100\.1\d\d\.|195\.239\.211\.|217\.69\.134\.'. '|81\.19\.6\d\.'. '|88\.212\.202\.'. '|79\.174\.83\.65|79\.174\.91\.209'. '|34\.210\.224\.7|34\.210\.35\.214|34\.211\.178\.241|34\.211\.180\.66|34\.213\.77\.188|34\.218\.121\.176|34\.223\.186\.249|35\.162\.254\.253|44\.224\.135\.238|44\.224\.174\.169|44\.224\.250\.144|44\.225\.118\.211|44\.225\.177\.160|44\.225\.203\.104|44\.226\.100\.122|44\.226\.111\.14|52\.10\.190\.191|52\.10\.225\.96|52\.11\.12\.231|52\.11\.187\.168|52\.11\.29\.70|52\.11\.54\.161|52\.24\.142\.159|52\.24\.187\.29|52\.24\.232\.158|52\.25\.116\.116|52\.25\.139\.76|52\.25\.191\.255|52\.26\.122\.21|52\.26\.187\.210|52\.27\.171\.126|52\.32\.57\.81|52\.34\.126\.117|52\.34\.254\.47|52\.35\.72\.129|52\.35\.82\.99|52\.36\.28\.80|52\.39\.177\.152|52\.41\.237\.12|52\.41\.5\.108|52\.42\.189\.119|52\.43\.127\.200|52\.43\.13\.71|52\.43\.76\.224|52\.88\.119\.122|52\.88\.197\.180|52\.88\.215\.225|52\.88\.96\.110|52\.89\.155\.51|52\.89\.85\.107|52\.89\.94\.121|54\.186\.128\.167|54\.186\.143\.184|54\.186\.244\.128|54\.187\.92\.57|54\.191\.108\.9|54\.191\.135\.209|54\.191\.136\.176|54\.191\.137\.17|54\.191\.148\.85|54\.191\.149\.8|54\.191\.32\.65|54\.191\.40\.136|54\.191\.67\.23|54\.191\.80\.119|54\.70\.201\.228|54\.70\.65\.107|54\.71\.54\.102'. '|188\.72\.80\.|193\.232\.121\.|89\.108\.7[69]\.1\d\d'. ')/', FW_IP) || ($fw_ipListStatus = fw_check_ip(FW_IP)) > 0 || ($fw_urlListStatus = fw_check_url($_SERVER['REQUEST_URI'])) > 0 || ($fw_geoListStatus = fw_check_geo(FW_IP)) > 0 ) { if ($fw_paramsListStatus >= 0) return fw_deinit(); } if ( !(is_dir(FW_PATH_LOGDB) || mkdir(FW_PATH_LOGDB, 0771)) || !(is_dir(FW_PATH_IPDB) || mkdir(FW_PATH_IPDB, 0771)) || !(is_dir(FW_PATH_GEODB) || mkdir(FW_PATH_GEODB, 0771)) || !(is_dir(FW_PATH_GEOBLOCKED) || mkdir(FW_PATH_GEOBLOCKED, 0771)) || !(is_dir(FW_PATH_GEOLOGDB) || mkdir(FW_PATH_GEOLOGDB, 0771)) ) { return fw_deinit(); } if (is_file($_ = FW_PATH_BASE.'/.updated')) { $prev = trim(file_get_contents($_)); unlink($_); if (empty($prev) || version_compare($prev, '1.1.3', '<=')) { foreach ([FW_PATH_BLOCKED, FW_PATH_SCOREDB] as $_) is_dir($_) ? fw_removedir($_, TRUE) : mkdir($_, 0771, TRUE); } if (empty($prev) || version_compare($prev, '1.1.5', '<=')) { foreach (scandir(FW_PATH_LOGDB) as $dd) if ( $dd[0] !== '.' && strlen($dd) === 2 && (int)$dd && is_file($dd = FW_PATH_LOGDB.'/'.$dd) && is_string($stat = file_get_contents($dd)) && ($stat = explode(',', $stat)) && count($stat) >= 8 && ((int)$stat[0] == $stat[0]) && is_dir($ipfs = FW_PATH_BLOCKED.'/'.$stat[0]) && ($ipfs = scandir($ipfs)) ) { $stat[8+FW_OFFSET] = count($ipfs) - 2; file_put_contents($dd, implode(',', $stat)); } unset($dd, $ipfs, $stat); } if (empty($prev) || version_compare($prev, '1.1.9', '<=')) { is_dir(FW_PATH_BASE.'/iplists') || mkdir(FW_PATH_BASE.'/iplists', 0771); foreach ([FW_PATH_BASE.'/ipbl' => FW_PATH_BASE.'/iplists/bl', FW_PATH_BASE.'/ipwl' => FW_PATH_BASE.'/iplists/wl'] as $srcDir => $dstFile) { if (!is_dir($srcDir)) continue; $srcFileNames = scandir($srcDir); if (count($srcFileNames) > 2) { $dstText = ''; foreach ($srcFileNames as $srcFileName) if ($srcFileName[0] !== '.' && is_file($srcDir.'/'.$srcFileName)) $dstText .= fw_filetoip($srcFileName)."\n"; if (strlen($dstText)) file_put_contents($dstFile, $dstText); } fw_removedir($srcDir); } unset($srcDir, $dstFile, $srcFileNames, $srcFileName, $dstText); } if (empty($prev) || version_compare($prev, '1.2.2', '<=')) { $remove = []; foreach (['iplists', 'urllists'] as $type) { $dir = FW_PATH_BASE.'/'.$type; if (!isset($fw_settings[$type]) || !is_array($fw_settings[$type])) { $fw_settings[$type] = []; } foreach (['b', 'w'] as $subType) { $subFile = $dir.'/'.$subType.'l'; if (is_file($subFile)) $fw_settings[$type][$subType] = file($subFile, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); if (empty($fw_settings[$type][$subType])) $fw_settings[$type][$subType] = []; $remove[] = $subFile; } $remove[] = $dir; } if (fw_savesettings($fw_settings)) foreach ($remove as $subFile) if (is_file($subFile)) unlink($subFile); elseif (is_dir($subFile)) rmdir($subFile); unset($remove, $type, $dir, $subType, $subFile); } unset($_, $prev); } elseif (($_ = filemtime(__FILE__)) && ($_ < time() - 86400 || time() + 1 < $_) && touch(__FILE__)) { is_string($_ = file_get_contents(FW_UPDATE_HOST.'?'.http_build_query(['fromversion' => FW_VERSION, 'uid' => FW_UID, 'cfn' => FW_PATH_SVCDIR, 'php' => (float)PHP_VERSION]))) && strlen($_) >= 4096 && substr($_, 0, 5) === '<'.'?'.'php' && strpos($_, 'FW_FILEPATH') && fw_file_safe_rewrite(__FILE__, $_, TRUE) && file_put_contents(FW_PATH_BASE.'/.updated', FW_VERSION); $mtime = time() - 600; foreach ([FW_PATH_IPDB, FW_PATH_SCOREDB] as $dir) if (is_dir($dir) && is_array($files = scandir($dir))) foreach ($files as $file) if ($file[0] !== '.' && is_file($file = $dir.'/'.$file) && (int)filemtime($file) < $mtime) unlink($file); $mtime = time() - 86400 * 31; foreach ([FW_PATH_BLOCKED] as $dir) if (is_dir($dir) && is_array($files = scandir($dir))) foreach ($files as $file) if ($file[0] !== '.' && is_dir($file = $dir.'/'.$file) && (int)filemtime($file) < $mtime) fw_removedir($file); unset($_, $mtime, $dir, $files, $file); } elseif (!is_file($geoFile = FW_PATH_GEODB.'/SxGeoCity.dat') || ($geoTime = filemtime($geoFile)) && ($geoTime < time() - 14400 || time() + 1 < $geoTime) && touch($geoFile)) { $geoURL = FW_UPDATE_HOST.'SxGeoCity.dat.gz'; if (empty($geoTime)) { ($_ = file_get_contents($geoURL)) && ($_ = gzinflate($_)) && fw_file_safe_rewrite($geoFile, $_); } else { $_ = PHP_VERSION_ID < 70100 ? get_headers($geoURL, TRUE) : get_headers($geoURL, TRUE, stream_context_create(['http' => ['method' => 'HEAD']])); if ($_ && (!isset($_['Last-Modified']) || strtotime($_['Last-Modified']) > $geoTime)) ($_ = file_get_contents($geoURL)) && ($_ = gzinflate($_)) && fw_file_safe_rewrite($geoFile, $_); } unset($_, $geoFile, $geoTime, $geoURL); } $fw_daystat = fw_daystat(); $fw_daystat_prev = $fw_daystat; $fw_blockreason = 0; if ($fw_paramsListStatus < 0 || $fw_ipListStatus < 0 || $fw_urlListStatus < 0 || $fw_geoListStatus < 0) { define('FW_BLOCK', 2); define('FW_SCORE', 0); FW_BLOCK && fw_logblocked(FW_IPF, [microtime(TRUE), $fw_blockreason = 10]) && ++$fw_daystat[8 + FW_OFFSET]; } else { if ($fw_urlListStatus > 0) return fw_deinit(); $fw_vdb = [ 'score' => [ 'freq_hard' => [ [0, 0.15, 10, 5], [0.15, 0.3, 5, 3], [0.3, 0.8, 3, 2], [0.8, 2, 0, -2], [2, 5, -20, -25], [5, 10, -40, -50], [10, 0], ], 'freq_medium' => [ [0 / 2, 0.15 / 2, 10, 5], [0.15 / 2, 0.3 / 2, 5, 3], [0.3 / 2, 0.8 / 2, 3, 2], [0.8 / 2, 2 / 2, 0, -2], [2 / 2, 5 / 2, -20, -25], [5 / 2, 10 / 2, -40, -50], [10 / 2, 0 / 2], ], 'freq_soft' => [ [0 / 4, 0.15 / 4, 10, 5], [0.15 / 4, 0.3 / 4, 5, 3], [0.3 / 4, 0.8 / 4, 3, 2], [0.8 / 4, 2 / 4, 0, -2], [2 / 4, 5 / 4, -20, -25], [5 / 4, 10 / 4, -40, -50], [10 / 4, 0 / 4], ], 'noagent' => 30, 'badheaders' => 20, 'extpost' => 40, 'extfiles' => 100, 'get' => 100, 'post' => 40, 'params' => 100, 'geo' => 100, 'filetypes' => 100, 'limit' => 150, ], 'filetypes' => '#\.(?:php.?|phar|pl|py|asp.?|rb|inc|cgi|htaccess|exe|bat|cmd|(?:ba|w)?sh)(?:\.|$)#', 'request' => [ '#</?(?:script|iframe)[\s>]#i', '#(?:\W|^)document\.\w+\s*\(#', '#base64_?(?:de|en)code\s*\(#i', '#(?:_GET|_POST|_REQUEST|GLOBALS)[=\[]#', '#/s?bin/(?:ba)?sh#', '#(?:[;\'"]|\*\/|--+)\s*(?:(?:UNION\s+)?(?:ALL\s+)?SELECT|INSERT\s+INTO|UPDATE|DELETE\s+FROM|DROP\s+(?:TABLE|DATABASE|VIEW)|TRUNCATE\s+TABLE)\W#i', ], ]; $fw_stat = [ 'time' => microtime(TRUE), 'ispost' => isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) === 'post' || isset($_POST) && $_POST, 'isfiles' => isset($_FILES) && $_FILES, 'isajax' => isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest', 'host' => strtolower(!empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : (!empty($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '')), 'agent' => isset($_SERVER['HTTP_USER_AGENT']) && strlen($_SERVER['HTTP_USER_AGENT']) > 3, 'referer' => isset($_SERVER['HTTP_REFERER']) ? strtolower($_SERVER['HTTP_REFERER']) : '', 'extreferer' => NULL, ]; if (strlen($fw_stat['host'])) if (substr($fw_stat['host'], 0, 4) === 'www.') $fw_stat['host'] = substr($fw_stat['host'], 4); if (strlen($fw_stat['referer'])) { $_ = parse_url($fw_stat['referer']); if (isset($_['host'])) { if (substr($_['host'], 0, 4) === 'www.') $_['host'] = substr($_['host'], 4); $fw_stat['extreferer'] = strlen($_['host']) && strlen($fw_stat['host']) && $_['host'] !== $fw_stat['host']; } } $fw_rating = fw_rating(FW_IPF); if ($fw_rating[1]) { $_ = $fw_rating[0]; $level = isset($fw_settings['level']) && isset($fw_vdb['score']['freq_'.$fw_settings['level']]) ? 'freq_'.$fw_settings['level'] : 'freq_hard'; $diff = abs($fw_stat['time'] - $fw_rating[1]); foreach ($fw_vdb['score'][$level] as $freq) { if ($freq[0] <= $diff && $diff < $freq[1]) { $fw_rating[0] += $fw_stat['isajax'] ? $freq[3] : $freq[2]; if ($fw_rating[0] < 0) $fw_rating[0] = 0; break; } elseif (!$freq[1]) { $fw_rating[0] = 0; break; } } if (!$fw_rating[0]) { fw_logscorediff(FW_IPF, []); } elseif ($fw_rating[0] > $_) { if ($fw_rating[0] >= 100) ++$fw_daystat[3 + FW_OFFSET]; fw_logscorediff(FW_IPF, [$fw_stat['time'], $fw_rating[0], $fw_blockreason = 3]); } unset($diff, $freq, $level); } if ($fw_paramsListStatus < 0) ++$fw_daystat[7 + FW_OFFSET] && ($fw_rating[0] += $fw_vdb['score']['params']) && fw_logscorediff(FW_IPF, [$fw_stat['time'], $fw_rating[0], $fw_blockreason = $list[1]]); if (!$fw_stat['agent']) ++$fw_daystat[6 + FW_OFFSET] && ($fw_rating[0] += $fw_vdb['score']['noagent']) && fw_logscorediff(FW_IPF, [$fw_stat['time'], $fw_rating[0], $fw_blockreason = 6]); if ($fw_stat['extreferer']) if ($fw_stat['isfiles']) ++$fw_daystat[5 + FW_OFFSET] && ($fw_rating[0] += $fw_vdb['score']['extfiles']) && fw_logscorediff(FW_IPF, [$fw_stat['time'], $fw_rating[0], $fw_blockreason = 5]); foreach ($_GET as $value) foreach ($fw_vdb['request'] as $pcre) if (is_string($value) && preg_match($pcre, $value)) { ++$fw_daystat[4 + FW_OFFSET] && ($fw_rating[0] += $fw_vdb['score']['get']) && fw_logscorediff(FW_IPF, [$fw_stat['time'], $fw_rating[0], $fw_blockreason = 4]); break; } reset($_GET); foreach ($_POST as &$value) foreach ($fw_vdb['request'] as $pcre) if (is_string($value) && preg_match($pcre, $value)) { ++$fw_daystat[4 + FW_OFFSET] && ($fw_rating[0] += $fw_vdb['score']['post']) && fw_logscorediff(FW_IPF, [$fw_stat['time'], $fw_rating[0], $fw_blockreason = 4]); break; } reset($_POST); unset($value, $pcre); if ($fw_stat['isfiles']) { $names = []; foreach ($_FILES as $file) if (is_array($file) && !empty($file['name'])) if (is_array($file['name'])) array_walk_recursive($file['name'], function($name) use (&$names) { if (is_string($name)) $names[] = $name; }); elseif (is_string($file['name'])) $names[] = $file['name']; reset($_FILES); foreach ($names as $file) if (preg_match($fw_vdb['filetypes'], $file)) { ++$fw_daystat[5 + FW_OFFSET] && ($fw_rating[0] += $fw_vdb['score']['filetypes']) && fw_logscorediff(FW_IPF, [$fw_stat['time'], $fw_rating[0], $fw_blockreason = 5]); break; } unset($names, $file); } if ($fw_rating[0] > $fw_vdb['score']['limit']) $fw_rating[0] = $fw_vdb['score']['limit']; define('FW_BLOCK', $fw_rating[0] >= 100 ? 1 : 0); define('FW_SCORE', $fw_rating[0]); FW_BLOCK && fw_logblocked(FW_IPF, [$fw_stat['time'], $fw_blockreason]) && ++$fw_daystat[8 + FW_OFFSET]; $fw_rating[1] = $fw_stat['time']; fw_rating(FW_IPF, $fw_rating); } if (!FW_BLOCK || !FW_PS) { ++$fw_daystat[1]; FW_BLOCK && ++$fw_daystat[2 + FW_OFFSET]; fw_daystat($fw_daystat); unset($fw_paramsListStatus, $fw_ipListStatus, $fw_urlListStatus, $fw_geoListStatus, $fw_stat, $fw_vdb, $fw_rating, $fw_daystat, $fw_daystat_prev, $fw_settings, $_); return fw_deinit(); } ++$fw_daystat[2 + FW_OFFSET]; fw_daystat($fw_daystat); header('Content-Type: text/html; charset=UTF-8', TRUE, 403); ?><?php function fw_init($base, $setEnv) { define('FW_VERSION', '1.4.3'); define('FW_UPDATE_HOST', 'http://cdn.virusdie.com/data/firewall/'); define('FW_UID', 'phil@salzstudio.com'); define('FW_PATH_BASE', $base); define('FW_PATH_SVCDIR', basename(dirname($base))); define('FW_PATH_BLOCKED', FW_PATH_BASE.'/blocked'); define('FW_PATH_GEOBLOCKED', FW_PATH_BASE.'/geoblocked'); define('FW_PATH_SCOREDB', FW_PATH_BASE.'/scoredb'); define('FW_PATH_LOGDB', FW_PATH_BASE.'/logdb'); define('FW_PATH_GEOLOGDB', FW_PATH_BASE.'/geologdb'); define('FW_PATH_IPDB', FW_PATH_BASE.'/ipdb'); define('FW_PATH_ALERTDB', FW_PATH_BASE.'/alertdb'); define('FW_PATH_SECURITY', FW_PATH_BASE.'/security'); define('FW_PATH_SETTINGS', FW_PATH_SECURITY.'/settings.json'); define('FW_PATH_GEODB', FW_PATH_BASE.'/geodb'); $options = fw_globaloptions(); $settings = fw_loadsettings(); define('FW_PS', ($options['flags'] & 1) && (!isset($settings['level']) || $settings['level'] !== 'detect') ? 1 : 0); define('FW_OFFSET', FW_PS ? 0 : 7); define('FW_ERRORLEVEL', (int)error_reporting()); define('FW_SHOWERRORS', ini_get('display_errors')); define('FW_MB_ENCODING', ((int)ini_get('mbstring.func_overload') & 3) ? mb_internal_encoding() : ''); if ($setEnv) { error_reporting(0); ini_set('display_errors', 0 !== 0); ini_set('pcre.backtrack_limit', 5e6); strlen(FW_MB_ENCODING) && mb_internal_encoding('8bit'); date_default_timezone_set(is_string($_ = date_default_timezone_get()) && strlen($_) ? $_ : 'UTC'); } return $settings; } function fw_deinit() { error_reporting(FW_ERRORLEVEL); ini_set('display_errors', FW_SHOWERRORS); strlen(FW_MB_ENCODING) && mb_internal_encoding(FW_MB_ENCODING); return TRUE; } function fw_rating($ipf, $new = NULL) { $file = FW_PATH_IPDB.'/'.$ipf; if ($new) { file_put_contents($file, implode(',', $new)); return $new; } if (is_file($file) && is_string($ret = file_get_contents($file)) && strlen($ret) < 32 && ($ret = explode(',', $ret))) { $ret[0] = (int)$ret[0]; $ret[1] = (float)$ret[1]; return $ret; } return [0, 0.0]; } function fw_daystat($new = NULL) { $date = date('Ymd'); $file = FW_PATH_LOGDB.'/'.substr($date, -2); if ($new) { fw_daystat_geo($new); file_put_contents($file, implode(',', $new)); return $new; } if (is_file($file) && is_string($ret = file_get_contents($file)) && ($ret = explode(',', $ret)) && $ret[0] === $date && count($ret) >= 8) return $ret; return [ $date, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; } function fw_daystat_geo($new) { global $fw_daystat_prev; $date = date('Ymd'); $dir = FW_PATH_GEOLOGDB.'/'.$date; $file = $dir.'/'.FW_GEO; if (!is_dir($dir) && !mkdir($dir)) return; if (is_file($file) && ($c = file_get_contents($file))) $old = explode(',', $c); else $old = [ $new[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; if (empty($fw_daystat_prev)) $minus = $new; else $minus = @[ $new[0], $new[1] - $fw_daystat_prev[1], $new[2] - $fw_daystat_prev[2], $new[3] - $fw_daystat_prev[3], $new[4] - $fw_daystat_prev[4], $new[5] - $fw_daystat_prev[5], $new[6] - $fw_daystat_prev[6], $new[7] - $fw_daystat_prev[7], $new[8] - $fw_daystat_prev[8], $new[9] - $fw_daystat_prev[9], $new[10] - $fw_daystat_prev[10], $new[11] - $fw_daystat_prev[11], $new[12] - $fw_daystat_prev[12], $new[13] - $fw_daystat_prev[13], $new[14] - $fw_daystat_prev[14], $new[15] - $fw_daystat_prev[15], ]; $diff = @[ $old[0], $old[1] + $minus[1], $old[2] + $minus[2], $old[3] + $minus[3], $old[4] + $minus[4], $old[5] + $minus[5], $old[6] + $minus[6], $old[7] + $minus[7], $old[8] + $minus[8], $old[9] + $minus[9], $old[10] + $minus[10], $old[11] + $minus[11], $old[12] + $minus[12], $old[13] + $minus[13], $old[14] + $minus[14], $old[15] + $minus[15], ]; file_put_contents($file, implode(',', $diff)); } function fw_iptofile($ip) { return strtr(preg_replace('/[^a-z\d\.\:]+/i', '', (string)$ip), '.:', '-_'); } function fw_filetoip($file) { return strtr((string)$file, '-_', '.:'); } function fw_check_ip($ip) { global $fw_settings; $type = 'iplists'; if (strlen($ip) && isset($fw_settings) && isset($fw_settings[$type])) foreach ([-1 => 'b', +1 => 'w'] as $ret => $subType) if ( !empty($fw_settings[$type][$subType]) && preg_match('~^('.strtr(implode('|', $fw_settings[$type][$subType]), ['.' => '\.', '*' => '[a-fA-F\\d]{1,4}']).')$~', $ip) ) return (int)$ret; return 0; } function fw_check_url($url) { global $fw_settings; $type = 'urllists'; $pLen = strlen($url); if ($pLen && isset($fw_settings) && isset($fw_settings[$type])) foreach ([-1 => 'b', +1 => 'w'] as $ret => $subType) if (!empty($fw_settings[$type][$subType])) foreach ($fw_settings[$type][$subType] as $rule) if (strlen($rule) <= $pLen && substr($url, 0, strlen($rule)) === $rule) return (int)$ret; return 0; } function fw_check_params() { global $fw_settings; if (!empty($fw_settings['paramslists'])) { if (!empty($fw_settings['paramslists']['user'])) if ($_ = fw_params_check_rules($fw_settings['paramslists']['user'])) return $_; if (!empty($fw_settings['paramslists']['base'])) if ($_ = fw_params_check_rules($fw_settings['paramslists']['base'])) return $_; } return 0; } function fw_check_geo($ip) { global $fw_settings; $type = 'geolists'; $fw_sxgeo = new FW_SxGeo(FW_PATH_GEODB.'/SxGeoCity.dat'); if (strlen($ip) && ($cityfull = $fw_sxgeo->getCityFull($ip)) && isset($cityfull['country'])) { $country = $cityfull['country']['iso'].','.$cityfull['country']['lat'].','.$cityfull['country']['lon']; $code = $cityfull['country']['iso']; } else { $country = '?,0,0'; $code = '?'; } unset($fw_sxgeo); defined('FW_GEO') || define('FW_GEO', $country); if (!isset($fw_settings, $fw_settings[$type]) || empty($fw_settings[$type]['list'])) return 0; $listed = in_array($code, $fw_settings[$type]['list']); $fw_settings[$type]['invert'] = !empty($fw_settings[$type]['invert']) || !empty($fw_settings[$type]['mode']) && ($fw_settings[$type]['mode'] === 'allow' || substr($fw_settings[$type]['mode'], 0, 6) === 'revers'); if (empty($fw_settings[$type]['invert'])) return $listed ? -1 : 0; else return $listed ? 0 : -2; } function fw_loadsettings() { if (is_file(FW_PATH_SETTINGS) && ($settings = file_get_contents(FW_PATH_SETTINGS)) && is_array($settings = json_decode($settings, TRUE))) return $settings; return []; } function fw_savesettings($settings) { return is_array($settings) && (is_dir(FW_PATH_SECURITY) || mkdir(FW_PATH_SECURITY, 0771, TRUE)) && @file_put_contents(FW_PATH_SETTINGS, json_encode($settings, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT)); } function fw_validatesettings($s) { if (!is_array($s)) return FALSE; if (isset($s['level']) && !in_array($s['level'], ['soft', 'medium', 'hard', 'detect'])) return FALSE; foreach (['iplists', 'urllists'] as $key) if (isset($s[$key])) if (!is_array($s[$key]) || isset($s[$key]['b']) && !is_array($s[$key]['b']) || isset($s[$key]['w']) && !is_array($s[$key]['w'])) return FALSE; $key = 'paramslists'; if (isset($s[$key])) if (!is_array($s[$key]) || isset($s[$key]['user']) && !is_array($s[$key]['user']) || isset($s[$key]['base']) && !is_array($s[$key]['base'])) return FALSE; $key = 'geolists'; if (isset($s[$key])) if (!is_array($s[$key]) || !isset($s[$key]['list']) || !is_array($s[$key]['list'])) return FALSE; return TRUE; } function fw_globaloptions() { $file = FW_PATH_BASE.'/../options'; if ( is_file($file) && ($data = file_get_contents($file)) && ($data = gzinflate($data)) && is_array($data = json_decode($data, TRUE)) && isset($data['flags']) ) { return $data; } return ['flags' => 0]; } function fw_logscorediff($ipf, $args) { if (!is_array($args)) return FALSE; if (!$args) return !is_file(FW_PATH_SCOREDB.'/'.$ipf) || unlink(FW_PATH_SCOREDB.'/'.$ipf); return TRUE; } function fw_logblocked($ipf, $args) { if (!is_array($args)) return FALSE; $dir = FW_PATH_BLOCKED.'/'.date('Ymd'); if (!is_dir($dir) && !mkdir($dir, 0771, TRUE)) return FALSE; $sargs = implode(',', $args); $s = $_SERVER['REQUEST_METHOD'].','. base64_encode((($_ = strpos($_SERVER['REQUEST_URI'], '?')) !== FALSE) ? substr($_SERVER['REQUEST_URI'], 0, $_) : $_SERVER['REQUEST_URI']).','. base64_encode($_SERVER['QUERY_STRING']).','; if ($_POST) { $_ = ''; foreach (array_keys($_POST) as $k) $_ .= $k.'='.(is_string($_POST[$k]) ? strlen($_POST[$k]) : (is_array($_POST[$k]) ? count($_POST[$k]) : '')).'&'; $s .= base64_encode(substr($_, 0, -1)); } $uid = hash('crc32', $s); $s .= ','.$uid.','.FW_PS; $s = $sargs.','.$s."\n"; $file = $dir.'/'.$ipf; $new = !is_file($file); file_put_contents($file, $s, FILE_APPEND|LOCK_EX); defined('FW_GEO') || fw_check_geo(FW_IP); $geoDir = FW_PATH_GEOBLOCKED.'/'.date('Ymd').'/'.FW_GEO; (is_dir($geoDir) || mkdir($geoDir, 0771, TRUE)) && file_put_contents($geoDir.'/'.$ipf, $s, FILE_APPEND|LOCK_EX); return $new; } function fw_get_bw_lists($type) { $fw_settings = fw_loadsettings(); $type .= 'lists'; if (isset($fw_settings[$type]) && is_array($fw_settings[$type])) { $list = $fw_settings[$type]; if ($type === 'geolists') { if (isset($list['b']) || isset($list['w']) || !isset($list['list'])) { $list = ['list' => [], 'invert' => FALSE]; } } return $list; } return ($type === 'geolists') ? ['list' => [], 'invert' => FALSE] : ['b' => [], 'w' => []]; } function fw_update_bw_lists($type, $isBL, $isAdd, $items) { if ($type !== 'ip' && $type !== 'url') return 10; if (is_string($items) && strlen($items)) $items = [$items]; if (!is_array($items) || empty($items)) return 10; $fw_settings = fw_loadsettings(); $isIP = ($type === 'ip'); $subType = $isBL ? 'b' : 'w'; $type .= 'lists'; if (!isset($fw_settings[$type]) || !is_array($fw_settings[$type])) $fw_settings[$type] = ['b' => [], 'w' => []]; foreach ($items as $item) { $item = trim($item); if (!strlen($item)) continue; if ($isAdd) { if ($isIP && !preg_match('~^[a-fA-F\\d\\.:\\*]+$~', $item)) return 10; if (!in_array($item, $fw_settings[$type][$subType], TRUE)) $fw_settings[$type][$subType][] = $item; elseif (count($items) === 1) return $isBL ? 12 : 13; } else { $idx = array_search($item, $fw_settings[$type][$subType], TRUE); if ($idx !== FALSE) array_splice($fw_settings[$type][$subType], $idx, 1); } } return fw_savesettings($fw_settings) ? 0 : 8; } function fw_update_geo_lists($items, $invert = FALSE) { if (!is_array($items)) return 10; $type = 'geolists'; $fw_settings = fw_loadsettings(); $fw_settings[$type] = ['list' => [], 'invert' => !!$invert]; foreach ($items as $item) if ($item = trim($item, "\"\'\t ")) $fw_settings[$type]['list'][] = $item; return fw_savesettings($fw_settings) ? $fw_settings[$type] : 8; } function fw_file_safe_rewrite($filename, $data, $lock = FALSE, $context = NULL) { if (!is_string($data)) return FALSE; clearstatcache(); $exists = is_file($filename); if ($exists) { $fmode = (int)fileperms($filename); $backup = $filename.'.tmp'.rand(100, 999); if (!rename($filename, $backup)) return FALSE; } if (file_put_contents($filename, $data, $lock ? LOCK_EX : 0, $context) >= strlen($data)) { if ($exists) { unlink($backup); $fmode && chmod($filename, $fmode); } return TRUE; } else { is_file($filename) && unlink($filename); if ($exists) { rename($backup, $filename); $fmode && chmod($filename, $fmode); } return FALSE; } } function fw_removedir($entry, $contentsOnly = FALSE) { if (!strlen($entry)) return FALSE; if (!is_dir($entry) || is_link($entry)) return unlink($entry); $entry .= '/'; if (!$dh = opendir($entry)) return FALSE; $err = FALSE; while (($obj = readdir($dh)) !== FALSE) if ($obj !== '.' && $obj !== '..') if (!fw_removedir($entry.$obj, FALSE)) $err = TRUE; closedir($dh); if (!$contentsOnly) if (!rmdir($entry)) $err = TRUE; return !$err; } function fw_update_level($level) { if (!is_string($level) || !in_array($level, ['soft', 'medium', 'hard', 'detect'])) return 14; $settings = fw_loadsettings(); $settings['level'] = $level; return fw_savesettings($settings) ? 0 : 8; } function fw_update_params_lists($input, $type, &$result = NULL) { if (!is_string($input) || !strlen($input) || !($params = json_decode($input, TRUE)) || !is_array($params)) return 14; $settings = fw_loadsettings(); if (!isset($settings['paramslists'])) $settings['paramslists'] = ['user' => [], 'base' => []]; if (!isset($settings['paramslists'][$type])) $settings['paramslists'][$type] = []; $requiredRuleKeys = ['URL', 'GET', 'BODY', 'HEAD']; foreach ($params as $vulnID => $rules) { foreach ($rules as $rule) { if (!isset($settings['paramslists'][$type][$vulnID])) $settings['paramslists'][$type][$vulnID] = []; if (count(array_diff($requiredRuleKeys, array_keys($rule))) === count($requiredRuleKeys)) return 14; if (empty($rule['ID'])) $rule['ID'] = hash('md5', rand(1e5, 1e6-1)); $settings['paramslists'][$type][$vulnID][$rule['ID']] = $rule; } } $result = $settings['paramslists'][$type]; return fw_savesettings($settings) ? 0 : 8; } function fw_delete_params_lists($input, $type, &$result = NULL) { if (!is_string($input) || !strlen($input)) return 14; $settings = fw_loadsettings(); if (!key_exists('paramslists', $settings)) $settings['paramslists'] = ['user' => [], 'base' => []]; if ($input === '*' || $input === '"*"') { $settings['paramslists'][$type] = []; $result = '*'; return fw_savesettings($settings) ? 0 : 8; } $result = []; $params = json_decode($input, TRUE); if (empty($params) || !is_array($params)) return 14; if (empty($settings['paramslists'][$type])) return 0; foreach ($params as $vulnID => $rules) { if (!isset($settings['paramslists'][$type][$vulnID])) { continue; } if (!is_array($rules)) { if ($rules === '*') { unset($settings['paramslists'][$type][$vulnID]); $result[$vulnID] = '*'; } continue; } foreach ($rules as $id) { if (!isset($settings['paramslists'][$type][$vulnID][$id])) continue; unset($settings['paramslists'][$type][$vulnID][$id]); $result[$vulnID][] = $id; } if (empty($settings['paramslists'][$type][$vulnID])) { unset($settings['paramslists'][$type][$vulnID]); $result[$vulnID] = '*'; } } return fw_savesettings($settings) ? 0 : 8; } function fw_get_params_lists($type) { $settings = fw_loadsettings(); $key = 'paramslists'; if (!isset($settings[$key], $settings[$key][$type]) || !is_array($settings[$key][$type])) return [$type => []]; return [$type => $settings[$key][$type]]; } function fw_params_values_array_to_lines($input, $key = null) { $output = []; foreach ($input as $k1 => $v1) { $k = $key ? $key.'['.$k1.']' : $k1; if (is_array($v1) && !empty($v1)) $output = array_merge($output, fw_params_values_array_to_lines($v1, $k)); else $output[$k] = $v1 ? $v1 : null; } return $output; } function fw_params_get_request_body() { $output = []; if (empty($_SERVER['CONTENT_TYPE']) || strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false || strpos($_SERVER['CONTENT_TYPE'], 'application/x-www-form-urlencoded') !== false) { if ($_SERVER['REQUEST_METHOD'] === 'PUT' || $_SERVER['REQUEST_METHOD'] === 'PATCH' || $_SERVER['REQUEST_METHOD'] === 'DELETE') { $arr = strpos($_SERVER['CONTENT_TYPE'], 'application/x-www-form-urlencoded') !== false ? [(($c = file_get_contents('php://input')) && parse_str($c, $a) && ($a = []) ? $_POST : $a), true] : [explode('name=', preg_replace('/-{0,2}(\r?\n)+/', ' ', preg_replace('/-{2,}[\S]+|Content-Disposition:\sform-data;\s/', '', file_get_contents('php://input')))), false]; foreach ($arr[0] as $k => $el) { if (empty($el) || $el === ' ') continue; if ($arr[1]) $output[$k] = $el; elseif ($el = explode(' ', $el)) if (count($el) === 1) $output[trim($el[0], ' "')] = null; elseif (count($el) > 1) $output[trim(array_shift($el), ' "')] = implode(' ', $el); } } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { $output = $_POST; } } elseif (strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) { if (($body = json_decode(file_get_contents('php://input'), true)) && json_last_error() === JSON_ERROR_NONE) $output = $body; } elseif (strpos($_SERVER['CONTENT_TYPE'], 'text/') !== false) { $output['content'] = file_get_contents('php://input'); $output['size'] = $_SERVER['CONTENT_LENGTH']; } return fw_params_values_array_to_lines($output); } function fw_params_check_conditions($conditions, $request, $and) { $result = $and ? true : false; foreach ($conditions as $condition) { $r = 0; foreach ($condition as $cond) { $_ = isset($cond['ext']) && is_array($cond['ext']); $regkey = $_ && isset($cond['ext']['key']) && $cond['ext']['key'] === 'rgxp'; $regval = $_ && isset($cond['ext']['val']) && $cond['ext']['val'] === 'rgxp'; $ext = $_ && !$regval && isset($cond['ext']['val']) && in_array($cond['ext']['val'], ['>','>=','<','<=','!=','=']); foreach ($request as $key => $val) { if ($cond['key'] === null ? true : ($regkey ? preg_match($cond['key'], $key) !== false : $cond['key'] == $key)) { if ($cond['val'] === null || !$ext && ($regval ? preg_match($cond['val'], $val) : $cond['val'] == $val)) { $r += 1; } elseif ($ext && in_array($cond['ext']['val'], ['>','>=','<','<=','!=','=']) && settype($cond['val'], 'integer') && !empty($cond['val'])) { switch ($cond['ext']['val']) { case '<': $r += (int)($val < $cond['val']); break; case '<=': $r += (int)($val <= $cond['val']); break; case '>': $r += (int)($val > $cond['val']); break; case '>=': $r += (int)($val >= $cond['val']); break; case '!=': $r += (int)($val != $cond['val']); break; case '=': $r += (int)($val == $cond['val']); break; } } } } } $res = $and ? ($r > 0) : ($r >= count($condition)); $result = $and ? $result && $res : $result || $res; } return $result; } function fw_params_compare($op, $v1, $v2) { return ($op === 'OR') ? $v1 || $v2 : $v1 && $v2; } function fw_request_headers() { if (function_exists('apache_request_headers')) return apache_request_headers(); static $caseFix = [ 'Dasl' => 'DASL', 'Dav' => 'DAV', 'Etag' => 'ETag', 'Mime-Version' => 'MIME-Version', 'Slug' => 'SLUG', 'Te' => 'TE', 'Www-Authenticate' => 'WWW-Authenticate', 'Content-Md5' => 'Content-MD5', 'Content-Id' => 'Content-ID', 'Content-Features' => 'Content-features', ]; $arh = []; foreach ($_SERVER as $key => $val) { if (substr($key, 0, 5) !== 'HTTP_') continue; $key = implode('-', array_map('ucfirst', explode('_', strtolower(substr($key, 5))))); if (isset($caseFix[$key])) $key = $caseFix[$key]; $arh[$key] = $val; } return $arh; } function fw_params_check_rules($rules) { $__GET = fw_params_values_array_to_lines($_GET); $__BODY = fw_params_get_request_body(); $__HEAD = fw_request_headers(); foreach ($rules as $vulnID) foreach ($vulnID as $rule) { $res = false; if (!isset($rule['COMPARSION']) || ($rule['COMPARSION'] !== 'OR' && $rule['COMPARSION'] !== 'AND')) $rule['COMPARSION'] = 'AND'; if (!empty($rule['URL'])) if ($rule['URL'] === '/' || strlen($_SERVER['REQUEST_URI']) >= strlen($rule['URL']) && !strncasecmp($_SERVER['REQUEST_URI'], $rule['URL'], strlen($rule['URL']))) $res = ($rule['COMPARSION'] === 'AND'); if (!empty($rule['HEAD'])) if (!empty($__HEAD)) $res = fw_params_compare($rule['COMPARSION'], $res, fw_params_check_conditions($rule['HEAD']['conditions'], $__HEAD, $rule['HEAD']['schema'] === 'AND_OVER_OR')); else $res = false; if (!empty($rule['GET'])) if (!empty($__GET)) $res = fw_params_compare($rule['COMPARSION'], $res, fw_params_check_conditions($rule['GET']['conditions'], $__GET, $rule['GET']['schema'] === 'AND_OVER_OR')); else $res = false; if (!empty($rule['BODY'])) if ( !empty($__BODY) && $rule['BODY']['type'] !== null && ( ($ct = str_replace('text/', '', $_SERVER['CONTENT_TYPE'])) && in_array($ct, explode(',', $rule['BODY']['type'])) || strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false || strpos($_SERVER['CONTENT_TYPE'], 'application/x-www-form-urlencoded') !== false ) ) $res = fw_params_compare($rule['COMPARSION'], $res, fw_params_check_conditions($rule['BODY']['conditions'], $__BODY, $rule['BODY']['schema'] === 'AND_OVER_OR')); else $res = false; if ($res) { $mode = !empty($rule['MODE']) ? $rule['MODE'] : ''; return ($mode === 'allow') ? +1 : -1; } } return 0; } function fw_get_server_name() { static $cached = NULL; if ($cached !== NULL) return $cached; foreach (['SERVER_NAME', 'HTTP_HOST', 'SERVER_ADDR'] as $k) if (!empty($_SERVER[$k])) { $cached = $_SERVER[$k]; break; } if (empty($cached)) $cached = 'localhost'; elseif (substr($cached, 0, 4) === 'www.') $cached = substr($cached, 4); return $cached; } class FW_SxGeo { protected $fh; protected $ip1c; protected $info; protected $range; protected $db_begin; protected $b_idx_str; protected $m_idx_str; protected $b_idx_arr; protected $m_idx_arr; protected $b_idx_len; protected $m_idx_len; protected $db_items; protected $id_len; protected $block_len; protected $max_region; protected $max_city; protected $max_country; protected $pack; protected $country_size; protected $db; protected $regions_db; protected $cities_db; public $ok = false; public $batch_mode = false; public $memory_mode = false; public $id2iso = ['', 'AP', 'EU', 'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'CW', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BM', 'BN', 'BO', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'SX', 'GA', 'GB', 'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'ST', 'SV', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TM', 'TN', 'TO', 'TL', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'RS', 'ZA', 'ZM', 'ME', 'ZW', 'A1', 'XK', 'O1', 'AX', 'GG', 'IM', 'JE', 'BL', 'MF', 'BQ', 'SS' ]; public function __construct($db_file, $batch_mode = false, $memory_mode = false) { $this->fh = fopen($db_file, 'rb'); if (!$this->fh) return; $header = fread($this->fh, 40); if (!$header || substr($header, 0, 3) !== 'SxG') return; $info = unpack('Cver/Ntime/Ctype/Ccharset/Cb_idx_len/nm_idx_len/nrange/Ndb_items/Cid_len/nmax_region/nmax_city/Nregion_size/Ncity_size/nmax_country/Ncountry_size/npack_size', substr($header, 3)); if ($info['b_idx_len'] * $info['m_idx_len'] * $info['range'] * $info['db_items'] * $info['time'] * $info['id_len'] == 0) return; $this->batch_mode = $batch_mode; $this->memory_mode = $memory_mode; $this->range = $info['range']; $this->b_idx_len = $info['b_idx_len']; $this->m_idx_len = $info['m_idx_len']; $this->db_items = $info['db_items']; $this->id_len = $info['id_len']; $this->block_len = 3 + $this->id_len; $this->max_region = $info['max_region']; $this->max_city = $info['max_city']; $this->max_country = $info['max_country']; $this->country_size= $info['country_size']; $this->pack = $info['pack_size'] ? explode("\0", fread($this->fh, $info['pack_size'])) : ''; $this->b_idx_str = fread($this->fh, $info['b_idx_len'] * 4); $this->m_idx_str = fread($this->fh, $info['m_idx_len'] * 4); $this->db_begin = ftell($this->fh); if ($this->batch_mode) { $this->b_idx_arr = array_values(unpack("N*", $this->b_idx_str)); unset($this->b_idx_str); $this->m_idx_arr = str_split($this->m_idx_str, 4); unset($this->m_idx_str); } if ($this->memory_mode) { $this->db = fread($this->fh, $this->db_items * $this->block_len); $this->regions_db = $info['region_size'] > 0 ? fread($this->fh, $info['region_size']) : ''; $this->cities_db = $info['city_size'] > 0 ? fread($this->fh, $info['city_size']) : ''; } $this->info = $info; $this->info['regions_begin'] = $this->db_begin + $this->db_items * $this->block_len; $this->info['cities_begin'] = $this->info['regions_begin'] + $info['region_size']; $this->ok = true; } protected function search_idx($ipn, $min, $max) { if ($this->batch_mode) { while ($max - $min > 8) { $offset = ($min + $max) >> 1; if ($ipn > $this->m_idx_arr[$offset]) $min = $offset; else $max = $offset; } while ($ipn > $this->m_idx_arr[$min] && $min++ < $max){}; } else { while ($max - $min > 8) { $offset = ($min + $max) >> 1; if ($ipn > substr($this->m_idx_str, $offset*4, 4)) $min = $offset; else $max = $offset; } while ($ipn > substr($this->m_idx_str, $min*4, 4) && $min++ < $max){}; } return $min; } protected function search_db($str, $ipn, $min, $max) { if ($max - $min > 1) { $ipn = substr($ipn, 1); while ($max - $min > 8) { $offset = ($min + $max) >> 1; if ($ipn > substr($str, $offset * $this->block_len, 3)) $min = $offset; else $max = $offset; } while ($ipn >= substr($str, $min * $this->block_len, 3) && ++$min < $max){}; } else { $min++; } return hexdec(bin2hex(substr($str, $min * $this->block_len - $this->id_len, $this->id_len))); } public function get_num($ip) { $ip1n = (int)$ip; if ($ip1n == 0 || $ip1n == 10 || $ip1n == 127 || $ip1n >= $this->b_idx_len || false === ($ipn = ip2long($ip))) return false; $ipn = pack('N', $ipn); $this->ip1c = chr($ip1n); if ($this->batch_mode) { $blocks = ['min' => $this->b_idx_arr[$ip1n-1], 'max' => $this->b_idx_arr[$ip1n]]; } else { $blocks = unpack("Nmin/Nmax", substr($this->b_idx_str, ($ip1n - 1) * 4, 8)); } if ($blocks['max'] - $blocks['min'] > $this->range) { $part = $this->search_idx($ipn, floor($blocks['min'] / $this->range), floor($blocks['max'] / $this->range)-1); $min = $part > 0 ? $part * $this->range : 0; $max = $part > $this->m_idx_len ? $this->db_items : ($part+1) * $this->range; if($min < $blocks['min']) $min = $blocks['min']; if($max > $blocks['max']) $max = $blocks['max']; } else { $min = $blocks['min']; $max = $blocks['max']; } $len = $max - $min; if ($this->memory_mode) { return $this->search_db($this->db, $ipn, $min, $max); } else { fseek($this->fh, $this->db_begin + $min * $this->block_len); return $this->search_db(fread($this->fh, $len * $this->block_len), $ipn, 0, $len); } } protected function readData($seek, $max, $type) { $raw = ''; if ($seek && $max) { if ($this->memory_mode) { $raw = substr($type == 1 ? $this->regions_db : $this->cities_db, $seek, $max); } else { fseek($this->fh, $this->info[$type == 1 ? 'regions_begin' : 'cities_begin'] + $seek); $raw = fread($this->fh, $max); } } return $this->unpack($this->pack[$type], $raw); } protected function parseCity($seek, $full = false) { if (!$this->pack) return false; $only_country = false; if ($seek < $this->country_size) { $country = $this->readData($seek, $this->max_country, 0); $city = $this->unpack($this->pack[2]); $city['lat'] = $country['lat']; $city['lon'] = $country['lon']; $only_country = true; } else { $city = $this->readData($seek, $this->max_city, 2); $country = ['id' => $city['country_id'], 'iso' => $this->id2iso[$city['country_id']]]; unset($city['country_id']); } if ($full) { $region = $this->readData($city['region_seek'], $this->max_region, 1); if (!$only_country) $country = $this->readData($region['country_seek'], $this->max_country, 0); unset($city['region_seek']); unset($region['country_seek']); return ['city' => $city, 'region' => $region, 'country' => $country]; } else { unset($city['region_seek']); return ['city' => $city, 'country' => ['id' => $country['id'], 'iso' => $country['iso']]]; } } protected function unpack($pack, $item = '') { $unpacked = []; $empty = empty($item); $pack = explode('/', $pack); $pos = 0; foreach ($pack AS $p) { list($type, $name) = explode(':', $p); $type0 = $type[0]; if ($empty) { $unpacked[$name] = $type0 == 'b' || $type0 == 'c' ? '' : 0; continue; } switch ($type0) { case 't': case 'T': $l = 1; break; case 's': case 'n': case 'S': $l = 2; break; case 'm': case 'M': $l = 3; break; case 'd': $l = 8; break; case 'c': $l = (int)substr($type, 1); break; case 'b': $l = strpos($item, "\0", $pos)-$pos; break; default: $l = 4; } $val = substr($item, $pos, $l); switch ($type0) { case 't': $v = unpack('c', $val); break; case 'T': $v = unpack('C', $val); break; case 's': $v = unpack('s', $val); break; case 'S': $v = unpack('S', $val); break; case 'm': $v = unpack('l', $val . (ord($val[2]) >> 7 ? "\xff" : "\0")); break; case 'M': $v = unpack('L', $val . "\0"); break; case 'i': $v = unpack('l', $val); break; case 'I': $v = unpack('L', $val); break; case 'f': $v = unpack('f', $val); break; case 'd': $v = unpack('d', $val); break; case 'n': $v = current(unpack('s', $val)) / pow(10, $type[1]); break; case 'N': $v = current(unpack('l', $val)) / pow(10, $type[1]); break; case 'c': $v = rtrim($val, ' '); break; case 'b': $v = $val; $l++; break; } $pos += $l; $unpacked[$name] = is_array($v) ? current($v) : $v; } return $unpacked; } public function get($ip) { return $this->max_city ? $this->getCity($ip) : $this->getCountry($ip); } public function getCountry($ip) { if ($this->max_city) { $tmp = $this->parseCity($this->get_num($ip)); return $tmp['country']['iso']; } return $this->id2iso[$this->get_num($ip)]; } public function getCountryId($ip) { if ($this->max_city) { $tmp = $this->parseCity($this->get_num($ip)); return $tmp['country']['id']; } return $this->get_num($ip); } public function getCity($ip) { $seek = $this->get_num($ip); return $seek ? $this->parseCity($seek) : false; } public function getCityFull($ip) { $seek = $this->get_num($ip); return $seek ? $this->parseCity($seek, 1) : false; } public function about() { $charset = ['utf-8', 'latin1', 'cp1251']; $types = ['n/a', 'SxGeo Country', 'SxGeo City RU', 'SxGeo City EN', 'SxGeo City', 'SxGeo City Max RU', 'SxGeo City Max EN', 'SxGeo City Max']; return [ 'Created' => date('Y.m.d', $this->info['time']), 'Timestamp' => $this->info['time'], 'Charset' => $charset[$this->info['charset']], 'Type' => $types[$this->info['type']], 'Byte Index' => $this->b_idx_len, 'Main Index' => $this->m_idx_len, 'Blocks In Index Item' => $this->range, 'IP Blocks' => $this->db_items, 'Block Size' => $this->block_len, 'City' => [ 'Max Length' => $this->max_city, 'Total Size' => $this->info['city_size'], ], 'Region' => [ 'Max Length' => $this->max_region, 'Total Size' => $this->info['region_size'], ], 'Country' => [ 'Max Length' => $this->max_country, 'Total Size' => $this->info['country_size'], ], ]; } } ?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Access denied</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="FW_BLOCK" content="<?=FW_BLOCK;?>" />
<meta name="FW_SCORE" content="<?=FW_SCORE;?>" />
<link href="//fonts.googleapis.com/css?family=Open+Sans:400&subset=latin,cyrillic" rel="stylesheet" type="text/css" />
<style type="text/css">
body {margin:0; padding:0; font-size:18px; font-family:'Open Sans',sans-serif; font-weight:400; color:#000; background-color:#F5F5F5;}
a,a:link,a:visited,a:active {color:#09D; text-decoration:none; outline:none;}
a:hover {text-decoration:underline;}
.clr {font-size:1px; line-height:1px; height:1px; clear:both;}
#vcenter {width:100%; height:100%; position:fixed; top:0; left:0; display:flex; align-items:center; justify-content:center; overflow:auto;}
#vdsync {width:640px; min-height:422px; padding:0 20px; margin:auto; max-width:100%; text-align:center; box-sizing:border-box;}
#logo {height:300px; border-radius:150px; margin:0px;}
p {padding:0; margin:0 0 20px 0;}
.col-1, .col-2 {width:45%; margin:0 0 20px 0; font-size:12px; text-align:justify;}
.col-1 {float:left;}
.col-2 {float:right;}
.col-1 p, .col-2 p {margin:0 0 10px 0;}
.copy {font-size:14px;}
@media only screen and (max-width:500px) {.col-1, .col-2 {width:100%;}}
</style>
</head>
<body>
<div id="vcenter">
	<div id="vdsync">
		<img src="https://virusdie.com/images/firewallstop.png" alt="" id="logo" />
		<p>This page has been blocked by our protection services</p>
		<div class="col-1">
			<p><strong>1. Why your IP address has been blocked?</strong></p>
			This website uses online threat protection and attacks mitigation system.
			Your last request was unfortunately blocked by our system due to malicious activity.
			There are several reasons why this may have happened and the website owner has been notified.
		</div>
		<div class="col-2">
			<p><strong>2. How do I regain access to <?=!empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : (!empty($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '');?>?</strong></p>
			You can try to visit this page again later or contact the website owner.
			Normally the website will revert to normal operations after a period of time.<br/>
			If you need further information please contact our Support Team on support@virusdie.com.
		</div>
		<div class="clr"></div>
		<p><a href="https://virusdie.com/" target="_blank">Security provided by Virusdie</a></p>
		<p class="copy">&copy; Virusdie.com : Powered by Virusdie.</p>
	</div>
</div>
</body>
</html>
<?php exit(); ?>