* @license PHP License * @package WB * @subpackage service */ WBClass::load('WBService' , 'WBString' ); /** * Detect Junk Requests * * See if request path looks like junk and change it to invalid URL * * Usually there are lots of requests just to check for any volnerability * Those request are useless and polute logs and database, therefore this services tries * to detect those request in an early stage and replaces the request path to something harmless * * @version 0.3.1 * @package WB * @subpackage service */ class WBService_Junk extends WBStdClass { /** * Logger * @var WBLog */ private $log; /** * @var int */ private $badness = 0; /** * Constructor * */ public function __construct($parameter = array()) { $this->log = WBLog::start(__CLASS__); } /** * Clean Path * * @param array */ public function cleanPath(&$path) { $log = array( 'status' => 'check', 'path' => implode('/', $path) ); $junkPath = array('junk_path'); if(!$this->checkChars($path)) { $log['status'] = 'chars'; $this->log->warn($log); $path = $junkPath; return; } if(!$this->checkSQLInjection($path)) { $log['status'] = 'sqlinjection'; $this->log->warn($log); $path = $junkPath; return; } if(!$this->checkUsualSuspects($path)) { $log['status'] = 'usualSuspect'; $this->log->warn($log); $path = $junkPath; return; } if(!$this->checkExtension($path)) { $log['status'] = 'extension'; $this->log->warn($log); $path = $junkPath; return; } $log['status'] = 'passed'; $this->log->debug($log); } /** * * @return int */ public function getSeverity() { return $this->badness; } /** * Check Path for Well Known * * @param array */ private function checkChars($path) { if (empty($path[0])) { return true; } // bad characters in path $bad = array( '{', '\\' ); if (in_array($path[0][0], $bad)) { $this->badness += 10; return false; } // useless request path that fills up database $path = implode('/', $path); if (strstr($path, 'ÃÆ')) { $this->badness += 51; return false; } return true; } /** * Check Path SQL Injection * * @param array */ private function checkSQLInjection($path) { $tmp = sprintf('/%s/', implode('/', $path)); // first round $bad = array( ' OR ', '1=1', '1=2', '-- ', ); foreach ($bad as $b) { if (stristr($tmp, $b)) { return false; } } // second round $tmp = str_replace(' ', '', $tmp); $bad = array( 'UNIONSELECT', '(SELECT', 'SLEEP(' ); foreach ($bad as $b) { if (stristr($tmp, $b)) { $this->badness += 100; return false; } } return true; } /** * Check Path for Well Known * * @param array */ private function checkUsualSuspects($path) { $bad = array( '..', '.ds_store', '.env', '.ftpconfig', '.git', '.svn', '.vscode', 'alfa_data', 'autodiscover', 'cgi-bin', 'config.json', 'dispatcher.php', 'ftp-sync.json', 'gponform', 'jenkins', 'mailman', 'mysql', 'phpmyadmin', 'pma', 'server-status', 'sftp.json', 'sftp-config.json', 'script', 'tmp', 'wp.php', 'wp-admin', 'wp-includes', 'wp-content', 'wp-signup.php', 'wp-update.php', '_ignition' ); // check if first part of path is bad if (in_array(strtolower($path[0]), $bad)) { $this->badness += 100; return false; } $bad = array( 'cgi-bin', '.env', 'Moxie.swf', 'silverlight', 'swagger', 'wp-includes' ); // bad everywhere $tmp = sprintf('/%s/', implode('/', $path)); foreach ($bad as $b) { // $b = sprintf('/%s/', $b); if (stristr($tmp, $b)) { $this->badness += 100; return false; } } return true; } /** * Check if File-Name-Extension is OK * * @param array */ private function checkExtension($path) { $last = end($path); if (!strstr($last, '.')) { return true; } $ext = explode('.', $last); $ext = strtolower(trim(array_pop($ext))); // list is bad extensions $bad = array( 'asp', 'cfg', 'cfm', 'cgi', 'env', 'html', 'jsp', 'local', 'ows', 'php', 'settings', 'shtml', 'swf', 'tpl', 'tmpl' ); switch ($path[0]) { case 'js': $bad[] = 'css'; break; case 'css': $bad[] = 'js'; break; default: $bad[] = 'js'; $bad[] = 'css'; break; } if (in_array($ext, $bad)) { $this->badness += 100; return false; } return true; } }