View file File name : REQUEST-933-APPLICATION-ATTACK-PHP.conf Content :# ------------------------------------------------------------------------ # OWASP CRS ver.4.7.0-dev # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. # Copyright (c) 2021-2024 CRS project. All rights reserved. # # The OWASP CRS is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ # # -= Paranoia Level 0 (empty) =- (apply unconditionally) # SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:933011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.7.0-dev',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:933012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.7.0-dev',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" # # -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) # # # -=[ PHP Injection Attacks ]=- # # [ References ] # https://rips-scanner.sourceforge.net/ # https://wiki.owasp.org/index.php/PHP_Top_5#P1:_Remote_Code_Executionh # # # [ PHP Open Tag Found ] # # Detects PHP open tags "<?" and "<?php". # http://www.php.net/manual/en/language.basic-syntax.phptags.php # # Care is taken to avoid false positives in XML declarations "<?xml..." # # Also detects "[php]", "[/php]" and "[\php]" tags used by some applications # to indicate PHP dynamic content. # # Previously, this rule also checked for the PHP close tag '?>', but # this resulted in false positives which were difficult to prevent. # Therefore, that pattern is now checked by rule 933190 in paranoia levels # 3 or higher. # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)<\?(?:[^x]|x(?:[^m]|m(?:[^l]|l(?:[^\s\x0b]|[\s\x0b]+[^a-z]|$)))|$|php)|\[[/\x5c]?php\]" \ "id:933100,\ phase:2,\ block,\ capture,\ t:none,\ msg:'PHP Injection Attack: PHP Open Tag Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP Script Uploads ] # # Block file uploads with filenames ending in PHP related extensions # (.php, .phps, .phtml, .php5 etc). # # Many application contain Unrestricted File Upload vulnerabilities. # https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload # # Attackers may use such a vulnerability to achieve remote code execution # by uploading a .php file. If the upload storage location is predictable # and not adequately protected, the attacker may then request the uploaded # .php file and have the code within it executed on the server. # # Also block files with just dot (.) characters after the extension: # https://www.rapid7.com/blog/post/2013/08/15/time-to-patch-joomla/ # # Some AJAX uploaders use the nonstandard request headers X-Filename, # X_Filename, or X-File-Name to transmit the file name to the server; # scan these request headers as well as multipart/form-data file names. # SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.ph(?:p\d*|tml|ar|ps|t|pt)\.*$" \ "id:933110,\ phase:2,\ block,\ capture,\ t:none,t:lowercase,\ msg:'PHP Injection Attack: PHP Script File Upload Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP Configuration Directives ] # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-config-directives.data" \ "id:933120,\ phase:2,\ block,\ capture,\ t:none,t:normalisePath,\ msg:'PHP Injection Attack: Configuration Directive Found',\ logdata:'Matched Data: %{TX.1} found within %{TX.933120_MATCHED_VAR_NAME}: %{TX.933120_MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.933120_matched_var=%{MATCHED_VAR}',\ setvar:'tx.933120_matched_var_name=%{MATCHED_VAR_NAME}',\ chain" SecRule MATCHED_VARS "@rx \b([^\s]+)\s*=" \ "capture,\ chain" SecRule TX:1 "@pmFromFile php-config-directives.data" \ "setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP Variables ] # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-variables.data" \ "id:933130,\ phase:2,\ block,\ capture,\ t:none,t:normalisePath,t:urlDecodeUni,\ msg:'PHP Injection Attack: Variables Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP I/O Streams ] # # The "php://" syntax can be used to refer to various objects, such as local files (for LFI), # remote urls (for RFI), or standard input/request body. Its occurrence indicates a possible attempt # to either inject PHP code or exploit a file inclusion vulnerability in a PHP web app. # # Examples: # php://filter/resource=./../../../wp-config.php # php://filter/resource=http://www.example.com # php://stdin # php://input # # http://php.net/manual/en/wrappers.php.php # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)php://(?:std(?:in|out|err)|(?:in|out)put|fd|memory|temp|filter)" \ "id:933140,\ phase:2,\ block,\ capture,\ t:none,\ msg:'PHP Injection Attack: I/O Stream Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP Wrappers ] # # PHP comes with many built-in wrappers for various URL-style protocols for use with the filesystem # functions such as fopen(), copy(), file_exists() and filesize(). Abusing of PHP wrappers like phar:// # could lead to RCE as describled by Sam Thomas at BlackHat USA 2018 (https://bit.ly/2yaKV5X), even # wrappers like zlib://, glob://, rar://, zip://, etc... could lead to LFI and expect:// to RCE. # # Valid PHP wrappers can be found in the PHP documentation here: # https://www.php.net/manual/en/wrappers.php # # Regular expression generated from regex-assembly/933200.ra. # To update the regular expression run the following shell script # (consult https://coreruleset.org/docs/development/regex_assembly/ for details): # crs-toolchain regex update 933200 # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:bzip2|expect|glob|ogg|(?:ph|r)ar|ssh2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?|z(?:ip|lib))://" \ "id:933200,\ phase:2,\ block,\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,t:cmdLine,\ msg:'PHP Injection Attack: Wrapper scheme detected',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP Functions ] # # Detecting PHP function names is useful to block PHP code injection attacks. # There are many PHP functions. We have to strike a balance between robust detection # of PHP code in content, and the risk of false positives. # # The list of PHP functions is divided into four groups of varying attack/false positive risk. # Four separate rules are used to detect these groups of functions: # # - Rule 933150: ~40 words highly common to PHP injection payloads and extremely rare in # natural language or other contexts. # Examples: 'base64_decode', 'file_get_contents'. # These words are detected as a match directly using @pmFromFile. # Function names are defined in php-function-names-933150.data # # - Rule 933160: ~220 words which are common in PHP code, but have a higher chance to cause # false positives in natural language or other contexts. # Examples: 'chr', 'eval'. # To mitigate false positives, a regexp looks for PHP function syntax, e.g. 'eval()'. # Regexp is generated from function names in /regexp-assemble/data/933160.ra # # - Rule 933151: ~1300 words of lesser importance. This includes most PHP functions and keywords. # Examples: 'addslashes', 'array_diff'. # For performance reasons, the @pmFromFile operator is used, and many functions from lesser # used PHP extensions are removed. # To mitigate false positives, we only match when the '(' character is also found. # This rule only runs in paranoia level 2 or higher. # Function names are defined in php-function-names-933151.data # # - Rule 933161: ~200 words with short or trivial names, possibly leading to false positives. # Examples: 'abs', 'cos'. # To mitigate false positives, a regexp matches on function syntax, e.g. 'abs()'. # This rule only runs in paranoia level 3 or higher. # Regexp is generated from function names in /regexp-assemble/data/933161.ra # # # [ PHP Functions: High-Risk PHP Function Names ] # # Rule 933150 contains a small list of function names which are highly indicative of a PHP # injection attack, for example 'base64_decode'. # We block these function names outright, without using a complex regexp or chain. # This could make the detection a bit more robust against possible bypasses. # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-function-names-933150.data" \ "id:933150,\ phase:2,\ block,\ capture,\ t:none,\ msg:'PHP Injection Attack: High-Risk PHP Function Name Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP Functions: High-Risk PHP Function Calls ] # # Some PHP function names have a certain risk of false positives, due to short # names, full or partial overlap with common natural language terms, uses in # other contexts, et cetera. Some examples are 'eval', 'exec', 'system'. # # For these function names, we apply a regexp to look for PHP function syntax. # The regexp looks for a word boundary and adjoining parentheses. # For instance, we want to block 'eval()', but we want to allow 'medieval()'. # # We have to be careful of possible bypasses using comment syntax. Examples: # # system(...) # system (...) # system\t(...) # system /*comment*/ (...) # system /*multiline \n comment*/ (...) # system //comment \n (...) # system #comment \n (...) # # This rule is triggered by the following exploits as well, as they include the string 'exec(...)': # [ Apache Struts vulnerability CVE-2017-9791 - Exploit tested: https://www.exploit-db.com/exploits/42324 ] # [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45260 ] # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # # Regular expression generated from regex-assembly/933160.ra. # To update the regular expression run the following shell script # (consult https://coreruleset.org/docs/development/regex_assembly/ for details): # crs-toolchain regex update 933160 # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b\(?[\"']*(?:assert(?:_options)?|c(?:hr|reate_function)|e(?:val|x(?:ec|p))|file(?:group)?|glob|i(?:mage(?:gif|(?:jpe|pn)g|wbmp|xbm)|s_a)|md5|o(?:pendir|rd)|p(?:assthru|open|rev)|(?:read|tmp)file|un(?:pac|lin)k|s(?:tat|ubstr|ystem))(?:/(?:\*.*\*/|/.*)|#.*|[\s\x0b\"])*[\"']*\)?[\s\x0b]*\(.*\)" \ "id:933160,\ phase:2,\ block,\ capture,\ t:none,\ msg:'PHP Injection Attack: High-Risk PHP Function Call Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP Object Injection ] # # PHP Object Injection is an application level vulnerability that could allow # an attacker to perform different kinds of malicious attacks, such as # Code Injection, SQL Injection, Path Traversal and Application Denial of Service, # depending on the context. # # The vulnerability occurs when user-supplied input is not properly sanitized # before being passed to the unserialize() PHP function. Since PHP allows object # serialization, attackers could pass ad-hoc serialized strings to a vulnerable # unserialize() call, resulting in an arbitrary PHP object(s) injection into the # application scope. # # https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection # # In serialized form, PHP objects have the following format: # # O:8:"stdClass":1:{s:1:"a";i:2;} # O:3:"Foo":0:{} # # Also detected are PHP objects with a custom unserializer: # https://www.phpinternalsbook.com/php5/classes_objects/serialization.html # These have the following format: # # C:11:"ArrayObject":37:{x:i:0;a:1:{s:1:"a";s:1:"b";};m:a:0:{}} # C:3:"Foo":23:{s:15:"My private data";} # # HTTP headers are inspected, since PHP object injection vulnerabilities have been # found in applications parsing them: # https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-8562 (User-Agent header) # https://www.exploit-db.com/exploits/39033/ (X-Forwarded-For header) # http://karmainsecurity.com/KIS-2015-10 (Host header) # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|ARGS_NAMES|ARGS|XML:/* "@rx [oOcC]:\d+:\".+?\":\d+:{.*}" \ "id:933170,\ phase:2,\ block,\ capture,\ t:none,\ msg:'PHP Injection Attack: Serialized Object Injection',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP Functions: Variable Function Calls ] # # PHP 'variable functions' provide an alternate syntax for calling PHP functions. # http://php.net/manual/en/functions.variable-functions.php # # An attacker may use variable function syntax to evade detection of function # names during exploitation of a remote code execution vulnerability. # An example to use the 'file_get_contents' function while evading rule 933150: # # $fn = 'file_' . 'get_' . 'contents'; # echo $fn('wp-co' . 'nfig.php'); # # Some examples from obfuscated malware: # # $OOO0000O0(...) # @$b374k(...) # $_[@-_]($_[@!+_] ) # # A breakdown of the regular expression: # # \$+ # The variable's '$' char, or multiple '$' for 'variable variables': # http://php.net/manual/en/language.variables.variable.php # (?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\s*{.+}) # One of the following: # - A variable name; regexp from http://php.net/language.variables.basics # - A nonempty expression for variable variables: ${'fn'} or $ {'fn'} # (?:\s|\[.+\]|{.+}|/\*.*\*/|//.*|#.*)* # Optional whitespace, array access, or comments # \(.*\) # Parentheses optionally containing function parameters # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx \$+(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\s*{.+})(?:\s|\[.+\]|{.+}|/\*.*\*/|//.*|#.*)*\(.*\)" \ "id:933180,\ phase:2,\ block,\ capture,\ t:none,\ msg:'PHP Injection Attack: Variable Function Call Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # [ PHP Functions: Variable Function Prevent Bypass ] # # Referring to https://www.secjuice.com/php-rce-bypass-filters-sanitization-waf/ # Regex test on https://regex101.com/r/x1tfXG/1 # the rule 933180 could be bypassed by using the following payloads: # # - (system)('uname'); # - (sy.(st).em)('uname'); # - (string)"system"('uname'); # - define('x', 'sys' . 'tem');(x)/* comment */('uname'); # - $y = 'sys'.'tem';($y)('uname'); # - define('z', [['sys' .'tem']]);(z)[0][0]('uname'); # - (system)(ls); # - (/**/system)(ls/**/); # - (['system'])[0]('uname'); # - (++[++system++][++0++])++{/*dsasd*/0}++(++ls++); # # This rule blocks all payloads above and avoids to block values like: # # - [ACME] this is a test (just a test) # - Test (with two) rounded (brackets) # # Regular expression generated from regex-assembly/933210.ra. # To update the regular expression run the following shell script # (consult https://coreruleset.org/docs/development/regex_assembly/ for details): # crs-toolchain regex update 933210 # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?:\((?:.+\)(?:[\"'][\-0-9A-Z_a-z]+[\"'])?\(.+|[^\)]*string[^\)]*\)[\s\x0b\"'\-\.0-9A-\[\]_a-\{\}]+\([^\)]*)|(?:\[[0-9]+\]|\{[0-9]+\}|\$[^\(\),\./;\x5c]+|[\"'][\-0-9A-Z\x5c_a-z]+[\"'])\(.+)\);" \ "id:933210,\ phase:2,\ block,\ capture,\ t:none,t:urlDecodeUni,t:replaceComments,t:removeWhitespace,\ msg:'PHP Injection Attack: Variable Function Call Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:933013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.7.0-dev',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:933014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.7.0-dev',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" # # -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) # # # [ PHP Functions: Medium-Risk PHP Function Names ] # # In paranoia level 2, we add additional checks for most PHP functions. # # The size of the PHP function list is considerable. # Even after excluding the more obscure PHP extensions, 1300+ functions remain. # For performance and maintenance reasons, this rule does not use a regexp, # but uses a phrase file (@pmFromFile), and additionally looks for an '(' character # in the matched variable. # # This approach carries some risk for false positives. Therefore, the function list # has been curated to remove words closely matching natural language and terms often # used in other contexts. # # This rule is a stricter sibling of rule 933150. # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-function-names-933151.data" \ "id:933151,\ phase:2,\ block,\ capture,\ t:none,\ msg:'PHP Injection Attack: Medium-Risk PHP Function Name Found',\ logdata:'Matched Data: %{TX.1} found within %{TX.933151_MATCHED_VAR_NAME}: %{TX.933151_MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.933151_matched_var=%{MATCHED_VAR}',\ setvar:'tx.933151_matched_var_name=%{MATCHED_VAR_NAME}',\ chain" SecRule MATCHED_VARS "@rx \b([^\s]+)\s*[(]" \ "capture,\ chain" SecRule TX:1 "@pmFromFile php-function-names-933151.data" \ "setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:933015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.7.0-dev',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:933016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.7.0-dev',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" # # -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) # # # [ PHP Variables: Common Variable Indexes ] # # In paranoia level 3, we add additional checks for parameters to many PHP variables. # # # One of the more common variables used within attacks on PHP is $_SERVER. Because # of how many different ways PHP has for executing variables (variable variables, # etc) often just looking for $_SERVER will be less effective than looking for the # various indexes within $_SERVER. This rule checks for these indexes. # This rule is located in PL 3 because often developers will use these names as # parameter names or values and this will lead to false positives. # Because this list is not expected to change and it is limited in size we use a # regex in this case to look for these values whereas in its sibling rule we use # @pmFromFile for flexibility and performance. # # Regular expression generated from regex-assembly/933131.ra. # To update the regular expression run the following shell script # (consult https://coreruleset.org/docs/development/regex_assembly/ for details): # crs-toolchain regex update 933131 # # This rule is a stricter sibling of rule 933130. SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx AUTH_TYPE|HTTP_(?:ACCEPT(?:_(?:CHARSET|ENCODING|LANGUAGE))?|CONNECTION|(?:HOS|USER_AGEN)T|KEEP_ALIVE|(?:REFERE|X_FORWARDED_FO)R)|ORIG_PATH_INFO|PATH_(?:INFO|TRANSLATED)|QUERY_STRING|REQUEST_URI" \ "id:933131,\ phase:2,\ block,\ capture,\ t:none,t:normalisePath,t:urlDecodeUni,\ msg:'PHP Injection Attack: Variables Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # # [ PHP Functions: Low-Value PHP Function Calls ] # # In paranoia level 3, we add additional checks for the remaining PHP functions. # # Most of these function names are likely to cause false positives in natural text # or common parameter values, such as 'abs', 'copy', 'date', 'key', 'max', 'min'. # Therefore, these function names are not scanned in lower paranoia levels. # # To mitigate the risk of false positives somewhat, a regexp is used to look for # PHP function syntax. (See rule 933160 for a description.) # # This rule is a stricter sibling of rule 933160. # # This rule is also triggered by the following exploit(s): # [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45262 ] # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # # Regular expression generated from regex-assembly/933161.ra. # To update the regular expression run the following shell script # (consult https://coreruleset.org/docs/development/regex_assembly/ for details): # crs-toolchain regex update 933161 # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:a(?:bs|s(?:in|sert(?:_options)?))|basename|c(?:h(?:eckdate|r(?:oot)?)|o(?:(?:mpac|(?:nsta|u)n)t|py|sh?)|r(?:eate_function|ypt)|urrent)|d(?:ate|e(?:coct|fined?)|ir)|e(?:nd|val|x(?:ec|p(?:lode)?|tract))|f(?:ile(?:(?:[acm]tim|inod|siz|typ)e|group|owner|perms)?|l(?:o(?:ck|or)|ush))|glob|h(?:ash|eader)|i(?:date|m(?:age(?:gif|(?:jpe|pn)g|wbmp|xbm)|plode)|s_a)|key|l(?:ink|og)|m(?:a(?:il|x)|d5|in)|n(?:ame|ext)|o(?:pendir|rd)|p(?:a(?:ck|ss(?:thru)?)|i|o(?:pen|w)|rev)|r(?:an(?:d|ge)|e(?:(?:adfil|nam)e|set)|ound)|s(?:(?:erializ|huffl)e|in|leep|(?:or|ta)t|ubstr|y(?:mlink|s(?:log|tem)))|t(?:an|(?:im|mpfil)e|ouch|rim)|u(?:cfirst|n(?:lin|pac)k)|virtual)(?:[\s\x0b]|/\*.*\*/|(?:#|//).*)*\(.*\)" \ "id:933161,\ phase:2,\ block,\ capture,\ t:none,\ msg:'PHP Injection Attack: Low-Value PHP Function Call Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # # [ PHP Script Uploads: Superfluous extension ] # # Block file uploads with PHP related extensions (.php, .phps, .phtml, # .php5 etc) anywhere in the name, followed by a dot. # # Example: index.php.tmp # # Uploading of such files can lead to remote code execution if # Apache is configured with AddType and MultiViews, as Apache will # automatically do a filename match when the extension is unknown. # This configuration is fortunately not common in modern installs. # # Blocking these file names might lead to more false positives. # # Some AJAX uploaders use the nonstandard request headers X-Filename, # X_Filename, or X-File-Name to transmit the file name to the server; # scan these request headers as well as multipart/form-data file names. # # This rule is a stricter sibling of rule 933110. # SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.(?:php\d*|phtml)\..*$" \ "id:933111,\ phase:2,\ block,\ capture,\ t:none,t:lowercase,\ msg:'PHP Injection Attack: PHP Script File Upload Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # [ PHP Closing Tag Found ] # # http://www.php.net/manual/en/language.basic-syntax.phptags.php # # This check was extracted from 933100 (paranoia level 1), since the # checked sequence '?>' commonly causes false positives. # See issue #654 for discussion. # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pm ?>" \ "id:933190,\ phase:2,\ block,\ capture,\ t:none,t:urlDecodeUni,\ msg:'PHP Injection Attack: PHP Closing Tag Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # [ PHP Functions: Variable Function Prevent Bypass ] # # This rule is a stricter sibling of 933210. # Unlike 933210, this rule will also match "this is a 'dog' (not a cat)", because the semi-colon at the end of the string is optional. # This is useful for PHP evals where the semi-colon is already hardcoded: # <?php eval("($input);") ?> # # Any potential function calls not at the end of a string will require a semi-colon to form valid PHP, which is automatically covered by 933210. # # Regular expression generated from regex-assembly/933211.ra. # To update the regular expression run the following shell script # (consult https://coreruleset.org/docs/development/regex_assembly/ for details): # crs-toolchain regex update 933211 # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?:\((?:.+\)(?:[\"'][\-0-9A-Z_a-z]+[\"'])?\(.+|[^\)]*string[^\)]*\)[\s\x0b\"'\-\.0-9A-\[\]_a-\{\}]+\([^\)]*)|(?:\[[0-9]+\]|\{[0-9]+\}|\$[^\(\),\./;\x5c]+|[\"'][\-0-9A-Z\x5c_a-z]+[\"'])\(.+)\)(?:;|$)?" \ "id:933211,\ phase:2,\ block,\ capture,\ t:none,t:urlDecodeUni,t:replaceComments,t:removeWhitespace,\ msg:'PHP Injection Attack: Variable Function Call Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ ver:'OWASP_CRS/4.7.0-dev',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:933017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.7.0-dev',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:933018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.7.0-dev',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" # # -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) # # # -= Paranoia Levels Finished =- # SecMarker "END-REQUEST-933-APPLICATION-ATTACK-PHP"