Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save taidos/4a93fe8ae98e5fdcda9e3d6b0bb35e7d to your computer and use it in GitHub Desktop.

Select an option

Save taidos/4a93fe8ae98e5fdcda9e3d6b0bb35e7d to your computer and use it in GitHub Desktop.
Function - WAF - Look for common injection, traversal, or escalation hits, then init an action
<?php
// @@TODO@@ classify this as a pub pre-controller
// @@TODO@@ semicolin var, might help edge \xYZ style hexors -- might affect speed though
// @@TOTO@@ make vars to turn on blocking of common WP and enterprise requests
// @@TODO@@ make modes to check in user agent, referrer, post, headers
// @@TODO@@ mode for strict validation of IP in addr + forwarder style headers
// @@TODO@@ testing mode (still allows traffic)
// @@TODO@@ log wrapper and modes
// $invalid = "(\'|\"|\(\))"; // looking for () since technically parenthesis arent valid
$invalid = "(\(\))"; // lets not look for quotes. [good]bots use them constantly. looking for () since technically parenthesis arent valid
$period = "(\\002e|%2e|%252e|%c0%2e|\.)";
$slash = "(\\2215|%2f|%252f|%5c|%255c|%c0%2f|%c0%af|\/|\\\)"; // http://security.stackexchange.com/questions/48879/why-does-directory-traversal-attack-c0af-work
$routes = "(etc|dev|irj)" . $slash . "(passwds?|group|null|portal)|allow_url_include|auto_prepend_file|route_*=http";
$filetypes = $period . "+(sql|db|sqlite|log|ini|cgi|bak|rc|apk|pkg|deb|rpm|exe|msi|bak|old|cache|lock|autoload|gitignore|ht(access|passwds?)|cpanel_config|history|zip|bz2|tar|(t)?gz)";
$cgis = "cgi(-|_){0,1}(bin(-sdb)?|mod|sys)?";
$phps = "(changelog|version|license|command|xmlrpc|admin-ajax|wsdl|tmp|shell|stats|echo|(my)?sql|sample|modx|load-config|cron|wp-(up|tmp|sitemaps|sitemap(s)?|signup|settings|" . $period . "?config(uration|-sample|bak)?))" . $period . "php";
$doors = "(" . $cgis . $slash . "(common" . $period . "(cgi|php))|manager" . $slash . "html|stssys" . $period . "htm|((mysql|phpmy|db|my)admin|pma|sqlitemanager|sqlite|websql)" . $slash . "|(jmx|web)-console|bitrix|invoker|muieblackcat|w00tw00t|websql|xampp|cfide|wordpress|wp-admin|hnap1|tmunblock|soapcaller|zabbix|elfinder)";
$sqls = "((un)?hex\(|name_const\(|char\(|a=0)";
$nulls = "(%00|%2500)";
$truth = "(.{1,4})=\1"; // catch OR always-true (1=1) clauses via sql inject - not used atm, its too broad and may capture search=chowder (ch=ch) for example
$regex = "/$invalid|$period{1,2}$slash|$routes|$filetypes|$phps|$doors|$sqls|$nulls/i";
$regex_ignore = "/captcha=0/i";
$results = '';
$matches = array();
$str = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$has_agent = isset($_SERVER['HTTP_USER_AGENT']);
$user_agent = ($has_agent ? $_SERVER['HTTP_USER_AGENT'] : 'no user agent');
if (preg_match_all($regex, preg_replace($regex_ignore, '', $str), $matches) || !$has_agent) {
if ($matches[0]) {
$matches[0] = array_unique($matches[0]);
foreach ($matches[0] as $match) {
$results .= $match . ' ';
}
}
if (!$has_agent) {
$results .= ' | No User Agent';
}
syslog(LOG_NOTICE, 'waf: Malformed URL from IP ' . $_SERVER['REMOTE_ADDR'] . ' with user agent [' . $user_agent . '] - requests: ' . $str . ' - Matches: ' . $results);
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
$output = '<html><head>';
$output.= '<style type="text/css">body{font-family: Arial,Helvetica,sans-serif,sans;margin:0;}.centerIn{text-align:center;}.head{background:#DCDCDC;padding:12px;}</style>';
$output.= '</head><body class="centerIn">';
$output.= '<br /><br /><br /><h1>Error 403 - Forbidden</h1><h2 class="head">Sorry, the URL you are requesting appears to be malicious or malformed.<br />Our systems have logged this attempt. Please repair the URL to continue.<br /><br />We found the following results: ' . $results . '</h2>';
$output.= '</body></html>';
exit($output);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment