ModSecurity is an engine for intrusion detection and prevention. It is mainly used for Web applications and can also be called Web application firewall. it can be run as a module or a separate application of the Apache Web server. ModSecurity aims to enhance the security of Web applications and protect Web applications from known and unknown attacks. This article mainly introduces the idea of an open source WAF penetration testing competition.1. BackgroundModSecurity SQL Injection Challenge (A penetration test Competition initiated by ModSecurity against open source WAF) http://www.modsecurity.org/demo/challenge.htmlowasp-modsecurity-crs (OWASP's authoritative rule for ModSecurity) https://github.com/SpiderLabs/owasp-modsecurity-crs2. Analysis of bypassing ideas0 × 1: Target Application System: Acunetix Acuart Site injection point: http://www.modsecurity.org/testphp.vulnweb.com/artists.php? Artist = 1'; analysis: the injection point is obvious. Through testing, we can know that the injection point is a digital injection, and all kinds of splicing can be performed, however, common injection methods will trigger Mod interception rules without exception. Mysql Comment Syntax 1) "#" for single row Comment 2) "-" for single row Comment, note that the annotator of this style must keep up with a "space" or a Control Char behind the "dual horizontal line" (the Control character can be a space, Tab, or line feed ...) "(Pay attention to URL encoding when using it. For example, the line feed URL is encoded as % 0D % 0A ). This "Double Dash annotator" is worth noting in the Mysql official documentation. (The key point is that the new Mysql parsing engine is improved to avoid "annotation injection caused by subtraction") 3) "/**/" C-style annotator. This annotation allows cross-line comments (that is, line breaks can be added to the annotator, for example :/*.. % 0D % 0A .. */)
mysql> SELECT 1+1; # This comment continues to the end of linemysql> SELECT 1+1; -- This comment continues to the end of linemysql> SELECT 1/* this is an in-line comment */ + 1;mysql> SELECT 1+/*this is amultiple-line comment*/1;
Let's take a look at our injection point. We use mysql annotation + CRLF to construct payload (pay attention to URL encoding ): http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=0+div+1+union%23foo * % 2F * bar % 0D % 0 Aselect % 23foo % 0D % 0A1% 2C2% 2Ccurrent_user escape the URL as follows (note the line break parsing ): 0 div 1 union # foo */* barselect # foo1, 2, current_user after the SQL statement reaches the Mysql parsing engine, it will be parsed as: 0 div 1 union select 1, 2, current_user: As you can see, the nearby principle is staggered between comments, and the SQL Parser of Mysql is ignored. The ModSecurity CRS rules are as follows: Note this: ": replaceComments". We know that ModSecurity uses a regular expression to check the matching of Input SQL statements, the appearance of Select and Union in sensitive locations is intercepted, but ModSecurity has a feature (or an advantage) that will "normalize" the input ", the purpose of normalization is to defend against the bypass of "encoding format and resolution sequence. For example, Mod can defend against this type of bypass: After SEL/**/ECT is "normalized", the attacker's original purpose is violent under Mod detection, at this time, the rules can be detected again. It can be said that standardization is a good defense idea. However, the key to another "Bypass" problem is that ModSecurity's understanding of annotations is different from that of Mysql's parsing engine (this seems to return to the old problem: different definitions of the same business rule in different systems may cause bypassing.): replaceCommentsUnterminated comments will also be replaced with a space (ASCII 0x20 ). however, a standalone termination of a comment (*/) will not be acted. that is to say, Mod ignores the comments to the front half and regards the comments to the back half as a single line comment (if it does not find the closed comments to the back half) in the Mod interception log, we can see the following records: In the Mod's view, the Payload we input becomes: "0 div 1 union # foo *", but in Mysql's view, our SQL statement is actually: 0 div 1 union select 1, 2, current_user
Defense method:1) change the original method for removing comments to match the SQL comments.
## -=[ Detect SQL Comment Sequences ]=-#SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \"(\/\*\!?|\*\/|\-\-[\s\r\n\v\f]|(?:--[^-]*-)|([^\-&])#.*[\s\r\n\v\f]|;?\\x00)" \"phase:2,rev:'2.2.2',id:'981231',t:none,t:urlDecodeUni,block,msg:'SQL Comment Sequence Detected.',capture,logdata:'%{tx.0}',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.sql_injection_score=+1,setvar:'tx.msg=%{rule.msg}',setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"
However, this method is essentially back to the category of the "blacklist mode", which may cause another form of bypass 2) using MultiMatch Action + ReplaceComments)
SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "(?i:\buser_tables\b)" \"phase:2,rev:'2.2.2',capture,multiMatch,t:none,t:urlDecodeUni,t:replaceComments,ctl:auditLogParts=+E,block,msg:'Blind SQL Injection Attack',id:'959918',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.
0 × 2:Target Application System: Cenzic Crack Me Bank injection point: http://www.modsecurity.org/Kelev/php/accttransaction.php (POST) injection Payload: bypass analysis: here the "fragment injection (segment SQL injection )", or we often say "Split And Balance Principles ". For example, in the simplest case, you can use the string connection technology to construct a small part into a string. Different databases use different syntaxes to construct strings.
oracle: 'selec'||'t'sqlserver: 'selec'+'';mysql: 'selec'+'t'
(This is the so-called split and balance idea) It should be noted that, the advantage of using the plus sign and space to encode the URL before sending this technology is that you can divide the original complete Payload into several sections and bypass the rules using ModSecurity's incomplete understanding of SQL semantics. It is often used for blind injection inference of binary logic. Back to our injection point: For Mod, the Payload attack is: hUserId = 22768 & FromDate = a1 % 27 + or & ToDate = % 3C % 3 Eamount + and % 27 & sendbutton1 = Get + Statement for Mysql's parsing engine, it automatically removes and converts these connection controllers to: hUserId = 22768 & FromDate = a1 % 27 + or & ToDate = <> amount and % 27 & sendbutton1 = Get Statement
Defense method:1) Here is a concept called "String Termination/Statement Ending Injection Testing ". During SQL Injection detection, attackers often use Terminator, such as single quotes and NULL, and check whether the page reports an error to determine whether the current page has an injection point. To defend against such injection, we can use the following CRS rules:
## -=[ String Termination/Statement Ending Injection Testing ]=-## Identifies common initial SQLi probing requests where attackers insert/append# quote characters to the existing normal payload to see how the app/db responds.#SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \"(?i:(\!\=|\&\&|\|\||>>|<<|>=|<=|<>|<=>|xor|rlike|regexp|isnull)|(?:not\s+between\s+0\s+and)|(?:is\s+null)|(like\s+null)|(?:(?:^|\W)in[+\s]*\([\s\d\"]+[^()]*\))|(?:xor|<>|rlike(?:\s+binary)?)|(?:regexp\s+binary))" \"phase:2,rev:'2.2.2',capture,t:none,t:urlDecodeUni,block,msg:'SQL Injection Attack: SQL Operator Detected',id:'981212',logdata:'%{TX.0}',severity:'2',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.notice_anomaly_score},setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"
2) We noticed a Mysql logical operator in Payload: "<> ". Attackers can use logical operators to perform "Blind injection inference ". For example, our common blind injection method is: and (ascii (substring (select username from admin),)> 97 (this is to convert characters one by one into ASCII values and then use the Binary Search Method to guess) UPDATE table SET views = '1' WHERE id =-2441 OR (ORD (MID (SELECTIFNULL (CAST (FirstName as char), 0x20) FROM nowamagic. 'tb2' order by id LIMIT 112),)>) # (similarly, with a function) to defend against such injection, we can use the following CRS rules
## -=[ SQL Operators ]=-#SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \"(?i:(\!\=|\&\&|\|\||>>|<<|>=|<=|<>|<=>|xor|rlike|regexp|isnull)|(?:not\s+between\s+0\s+and)|(?:is\s+null)|(like\s+null)|(?:(?:^|\W)in[+\s]*\([\s\d\"]+[^()]*\))|(?:xor|<>|rlike(?:\s+binary)?)|(?:regexp\s+binary))" \"phase:2,rev:'2.2.2',capture,t:none,t:urlDecodeUni,block,msg:'SQL Injection Attack: SQL Operator Detected',id:'981212',logdata:'%{TX.0}',severity:'2',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.notice_anomaly_score},setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"
0 × 3:Target Application System: IBM demo.testfire.net site injection point: http://www.modsecurity.org/bank/login.aspx (POST) injection Payload:
HPP (HTTP Parameter Pollution) injection technology is used here, there are a lot of information about HPP: http://www.bkjia.com/Article/201109/103092.html
Http://www.bkjia.com/Article/201210/160959.htmlhttp://www.bkjia.com/Article/200906/38773.htmlhttp://www.bkjia.com/Article/200906/39657.htmlhttps://www.owasp.org/images/ B /ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf back to our injection Payload up, we noticed that after this field appeared three times, the last two appear is actually produced the role of a comma, in order to bypass. It should be noted that HPP attacks are closely related to the specific application system environment, and are not consistent in different systems:
# -=[ Rules Logic }=-# The ruleset below is not looking for attacks directly, but rather is a crude normalization# function that mimics ASP.NET with regards to joining the payloads of parameters with the# same name. These rules will create a new TX:HPP_DATA variable that will hold this data.# If you have enabled PARANOID_MODE, then this variable data will also be searched against# attack filters.## -=[ References ]=-# http://tacticalwebappsec.blogspot.com/2009/05/http-parameter-pollution.html# SecRule ARGS "^" "chain,phase:2,t:none,nolog,pass,capture,id:'900032',rev:'2.2.9',setvar:tx.%{matched_var_name}=+1" SecRule TX:/^ARGS:/ "@gt 1" "chain,t:none" SecRule MATCHED_VARS_NAMES "TX:(ARGS:.*)" "chain,capture,t:none,setvar:tx.hpp_names=%{tx.1}" SecRule ARGS ".*" "chain,t:none,capture,setvar:tx.arg_counter=+1,setvar:'tx.hppnamedata_%{tx.arg_counter}=%{matched_var_name}=%{tx.0}'" SecRule TX:/HPPNAMEDATA_/ "@contains %{tx.hpp_names}" "chain,setvar:tx.hpp_counter=+1,setvar:tx.hpp_counter_%{tx.hpp_counter}=%{matched_var}" SecRule TX:/HPP_COUNTER_/ "ARGS:(.*)?=(.*)" "capture,setvar:'tx.hpp_data=%{tx.hpp_data},%{tx.2}'"
0 × 4:Target Application System: Cenzic Crack Me Bank injection point: http://www.modsecurity.org/Kelev/php/accttransaction.php (POST) injection Payload: Train of Thought Analysis: here using the "Unterminated Comments) "+" Mysql comments code execution (MySQL Comment Extensions for conditional code execution) "technology to bypass half-open annotators we have said before, attackers can use Mod replaceComments to bypass sensitive keywords. Mysql annotator code execution is a running mechanism of Mysql. The official Mysql documentation is as follows: MySQL Server supports some variants of C-style comments. these enable you to write code that has des MySQL extensions, but is still portable, by using comments of the following form :( Mysql allows C-style annotators and allows Mysql extensions to be written in it, insert executable SQL code )/*! MySQL-specific code */Mysql's Paerser engine will automatically parse the SQL code in this format, and other databases (such as MSSQL and ORACLE will automatically ignore these annotations), that is, this is a unique feature of Mysql: select 1 union /*! Select */version (); select 1 union /*! 32302 select */version ();
Defense method:Like 0 × 1, use MultiMatch Action + normalization (ReplaceComments)
0 × 5:Target Application System: IBM demo.testfire.net site injection point: http://www.modsecurity.org/bank/login.aspx (COOKIE) injection Payload: Injection Analysis: injection points are nothing special, the key here with the COOKIE injection defense method: with regard to COOKIE injection, I want to extend some ideas: in the selection of injection points, any field in HTTP "may" generate SQL injection, which can only be said here, whether or not injection is generated depends on the environment of the application system, that is, the fields used by the application system to import data for "GPCS": in php. there is a configuration in ini: variables_order = "GPCS" (the specific order and characters are related to your configuration) if you are in php. if the "register_globals" option is enabled in ini, PHP will follow the "$ GET", "$ POST", "$ COOKIE", "SERVER" To extract the Chinese sub-keys of the global data and register them in the symbol table of the local variable, that is, the global variable localization. This order is very important, which is often the key to exploiting many local variables. any location in HTTP may produce SQL injection, see the following example: http://sebug.net/vuldb/ssvid-8427Create New Admin Exploit FOR php168 v4.0SP in this example, the injection point occurs in the "X-FORWARDED-FOR" field, this was originally the business function used by the application system to record the IP addresses and proxy IP addresses of login users. However, because there is no strict filtering, injection occurs.
0 × 6:Target Application System: Acunetix Acuart Site injection: http://www.modsecurity.org/testphp.vulnweb.com/listproducts.php? Artist = 1' inject Payload: http://www.modsecurity.org/testphp.vulnweb.com/artists.php? Artist = % 40% 40new % 20 union % 23 limit % 0 Aselect % ,,2, database % 23 sqlmap % 0A % 28% 29Payload analysis: Mysql Comment) "+" New Line trick "Combination Method to bypass Mod (essentially bypassing the regular expression used by Mod). In the opinion of Mod, our Payload: http://www.modsecurity.org/testphp.vulnweb.com/artists.php? Artist = @ new union # merge, database # sqlmap (). However, when this SQL code enters the Mysql parsing engine, Mysql will see this form: artist = @ new union select 1, 2, database () defense method: We know that SQL is a flexible imperative Language, there can be many combinations of elements. Regular REGEX is often used for matching and cannot provide precise guidance. To solve this problem, we have two ideas: 1) higher-Order SQL parsing method, such as AST: http://www.cnblogs.com/LittleHann/p/3495602.html2) to improve regular expressions, using sensitive keyword Matching Method
SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \"([\~\!\@\#\$\%\^\&\*\(\)\-\+\=\{\}\[\]\|\:\;\"\'\′\’\‘\`\<\>].*){4,}" \"phase:2,t:none,t:urlDecodeUni,block,id:'981173',rev:'2.2.1',msg:'Restricted SQL Character Anomaly Detection Alert - Total # of special characters exceeded',capture,logdata:'%{tx.1}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.sql_injection_score=+1,setvar:'tx.msg=%{rule.msg}',setvar:tx.%{rule.id}-WEB_ATTACK/RESTRICTED_SQLI_CHARS-%{matched_var_name}=%{tx.0}"
0 × 7:Target Application System: Acunetix Acuart Site injection: http://www.modsecurity.org/testphp.vulnweb.com/listproducts.php? Artist=1'1.png injection Payload: 1.png1.png Payload analysis: here we use a combination of "Mysql error echo" + "Tab key separation bypass" to bypass Mod, the key point here is that the traditional space is not used for "Split And Balance ". Here is to mention the black list of ideas, the "Split And Balance" defense if the use of black list is easy to generate bypass: https://docs.google.com/document/d/1rO_LCBKJY0puvRhPhAfTD2iNVPfR4e9KiKDpDE2enMI/edit? Pli = 1 # allowed_intermediary_character_30801873724256314 if blacklist is required, strict code audit and testing are required to ensure the integrity of the blacklist. For example, the separator allowed in Mysql is 090A0B0C0DA0. Defense method: use the complete "quasi-space separator" blacklist CRS
SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \"(?i:(?:,.*[)\da-f(\"|'|`|′|’|‘)](\"|'|`|′|’|‘)(?:(\"|'|`|′|’|‘).*(\"|'|`|′|’|‘)|\Z|[^(\"|'|`|′|’|‘)]+))|(?:\Wselect.+\W*from)|((?:select|create|rename|truncate|load|alter|delete|update|insert|desc)\s*\(\s*space\s*\())" \"phase:2,capture,multiMatch,t:none,t:urlDecodeUni,t:replaceComments,block,msg:'Detects MySQL comment-/space-obfuscated injections and backtick termination',id:'981257',tag:'WEB_ATTACK/SQLI',tag:'WEB_ATTACK/ID',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.id}-%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:'tx.%{tx.msg}-WEB_ATTACK/SQLI-%{matched_var_name}=%{tx.0}',setvar:'tx.%{tx.msg}-WEB_ATTACK/ID-%{matched_var_name}=%{tx.0}'
3. SummaryBlacklist filtering is not enough-do not rely on the Blacklist mechanism. Multiple methods should be used for in-depth defense.