Modsecurity SQL injection attack

Source: Internet
Author: User
Tags sql injection attack modsecurity

Modsecurity is an intrusion detection and blocking engine that is primarily used for Web applications so it can also be called a Web application firewall. It can be run as a module of the Apache Web server or as a separate application. The purpose of modsecurity is to enhance the security of Web applications and protect Web applications from known and unknown attacks. This paper mainly introduces the idea of a penetration testing competition for open source WAF.

1. Article background

Modsecurity SQL Injection Challenge (Modsecurity launched a penetration test competition for open source WAF)

Owasp-modsecurity-crs (owasp the authoritative rule written for modsecurity)


2. Bypass Thinking Analysis


Target Application system: Acunetix Acuart Site

Injection point:? artist=1 ';


Injection point is obvious, through the test can know that the injection point is a digital injection, all kinds of splicing can be done, but the ordinary injection method without exception will trigger the MoD interception rules.

Here, we use MySQL annotation +crlf to bypass the idea to inject

Mysql Comment Syntax

1) "#" for single-line comments

2) "–" for single-line comments, but note that using this style of notation must be guaranteed to follow a "space or control Char" after "Double Dash" (the control can be a space, Tab tab, line feed newline ...). (Be aware of URL encodings when you use them, such as URL encoding for newline characters%0d%0a). About this "Double dash annotation" in the official MySQL document there is still a little detail to note (the emphasis is on the new version of the MySQL parsing engine improvements to avoid "minus-based annotation injection")

3) "/* * * *" C-style annotation, which allows for cross-line annotations (that is, allow the addition of line breaks in the comment character, for example:/*..%0 d%0a. */)

Mysql> SELECT; # This comment continues to the end of line mysql> SELECT; --This comment continues to the end of line mysql> SELECT 1/* This is an in-line comment */+ 1; mysql> SELECT 1+/* This is a multiple-line comment */1;

Go back to our injection point and see, we use MySQL annotation +crlf to construct the payload (note URL encoding):

? artist=0+div+1+union%23foo*%2f*bar%0d%0aselect%23foo%0d%0a1%2c2%2ccurrent_user

Escape to its URL as follows (note the parsing of newline characters):

0 Div 1 Union#foo*/*bar



This SQL statement will be parsed once again to the MySQL parsing engine:

0 Div 1 Union Select 1,2,current_user

As you can see, there is a staggered combination of the nearest principles between the annotations, and MySQL's SQL parser is selected for neglect.

The rules of modsecurity CRS are as follows:

Noting this ": Replacecomments", we know that Modsecurity uses regular expressions to match the input SQL to detect the presence of select and union in sensitive locations, but Modsecurity has a feature (or merit), it will "normalize" the input, the original intent of the normalization is to defend "based on the encoding format, parsing order" bypass.

For example:

Mods can resist this form of bypass:


After the "normalization", the attacker's original purpose of violence in the MoD detection, this time again on the rules can be detected, it can be said, normalization is a good defense ideas.

But here it leads to another kind of "bypass."

The key to the problem is that modsecurity's understanding of annotations differs from that of MySQL's parsing engine.

(This seems to be back to the old question: the same business rules in different systems of understanding semantics can often lead to bypass)

: replacecomments

Unterminated comments'll also is replaced with a space (ASCII 0x20). However, a standalone termination of a comment (*/) would not be acted upon.

That is, the MoD ignores the forward semi-open comment and treats the back half-open comment as a single-line comment (if it does not find a closed comment that is semi-open)

The following records can be found in the MoD's intercept log:

Thus, in the MoD's view, the payload we have entered 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 methods:

1) Change the original remove annotation method to match the SQL comment

# #-=[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.%{}-web_attack/sql_injection-%{matched_var_name}=%{tx.0} "

But this approach is essentially back in the category of "blacklist Mode", which may again lead to other forms of bypass

2) Use multi-line matching (multimatch Action) + Normalization method (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.%{}-web_attack/sql_injection-%{matched_var_name}=%{tx.


Target Application system: Cenzic Crack Me Bank

Injection point: (POST)

Inject payload:

Bypass Analysis:

"Fragment injection (segmented SQL injection)" is used here, or "split and balance principle", as we often call it. For example:

For the simplest case, you can use the string join technique to construct a smaller part into a string. Different databases use different syntax to construct strings

Oracle: ' Selec ' | | ' T ' SQL Server: ' Selec ' + '; MySQL: ' Selec ' + ' t '

(This is called split and balance thought)

Also note that the plus and the spaces are URL-encoded before they are sent

The advantage of this technique is that the original complete payload can be divided into several segments, using Modsecurity's understanding of SQL semantics to circumvent the rules. Often used for "binary logic" blind inference.

Go back to our injection point and look at:

For mod, our attack payload is:


For the MySQL parsing engine, it automatically removes and transforms these connection controls into:

Huserid=22768&fromdate=a1%27+or&todate=<>amount And%27&sendbutton1=get Statement

Defense methods:

1) Here is a concept called "String termination/statement Ending injection testing". Attackers often use "terminators", such as single quotes, NULL, and so on when conducting SQL injection detection, to see if the current page has an injection point by observing whether the page is an error.

To protect against this injection, we can use the following CRS rules:

# #-=[String termination/statement Ending injection Testing]=-# # Identifies common initial SQLi probing requests wher E 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.%{}-web_attack/sql_injection-%{matched_var_name}=%{tx.0} "

2) Notice our attack payload in a MySQL logical operator: "<>". An attacker could use a logical operator for "blind inference". For example, we often have traditional blind means:

and (ASCII (SUBSTRING ((select username from admin))) >97

(This is to convert the characters to ASCII values and then use the binary lookup method to guess)

UPDATE table SET views = ' 1 ' WHERE id = -2441 OR (ORD ((Selectifnull (FirstName as CHAR), 0x20) from Nowamagic. ' TB2 ' ORDER by ID LIMIT, 2,1)) >112) #

(The same idea, change a function)

To protect against this 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.%{}-web_attack/ sql_injection-%{matched_var_name}=%{tx.0} "


Target Application System: IBM Site

Injection point: (POST)

Inject payload:

The HPP (HTTP Parameter pollution) injection technology is used here, and there are a lot of relevant information about HPP:


Returning to our injected payload, we noticed that after this field appeared 3 times, and the latter 2 occurrences were actually created as a comma to bypass. It is important to note that the HPP attacks are very much related to the specific application environment and behave differently on different systems:


Defense methods:

We can use the following CRS rules to protect against HPP attacks:

#-=[Rules Logic}=-# The ruleset below is not looking for attacks directly, but rather is a crude normalization # FUNCT ion that mimics ASP. Regards to joining, the payloads of parameters with the # same name. These rules would create a new tx:hpp_data variable that would hold the this DATA. # If You have the enabled Paranoid_mode, then this variable data would also be searched against # attack filters. # #-=[References]=-# # 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} ' "


Target Application system: Cenzic Crack Me Bank

Injection point: (POST)

Inject payload:

Thinking Analysis:

This uses the "unterminated Comments" + "MySQL Annotation code execution (MySQL Comment Extensions for conditional Code execution)" Technology to bypass

Half-open annotation we said before, using MoD's replacecomments to bypass sensitive keywords. and "MySQL Comment 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 includes-MySQL extensions, but was still portable, by using comments of the following F Orm:

(MySQL allows C-style annotations and allows writing to the MySQL extension, i.e. inserting executable SQL code)

/*! Mysql-specific Code * *

MySQL's Paerser engine automatically parses the SQL code in this format, while other databases (such as MSSQL, Oracle automatically ignores these annotations), that is, MySQL-specific features:

Select 1 union/*! Select */version ();

Select 1 union/*!32302 Select */version ();

Defense methods:

As with 0x1, the use of multiline matching (Multimatch Action) + Normalization method (replacecomments)


Target Application System: IBM Site

Injection point: (COOKIE)

Inject payload:

Injection Analysis:

The injection point is nothing special, and the key here is to use a cookie injection

Defense methods:

On this cookie injection, I would like to extend several ideas:

In the selection of the injection point, any field in HTTP, any location is "likely" to generate SQL injection, it can only be said to be possible, because whether the injection can be generated, and the specific application system environment, that is, the application system will use which fields to carry the data for execution

The role of "gpcs":

There is a configuration in php.ini: Variables_order = "GPCs" (Specific order and character related to your configuration)

If the "register_globals" option is turned on in php.ini, PHP extracts the global Data's subkeys in the order of "$GET", "$POST", "$COOKIE", and "SERVER". Registers to the local variable's symbol table, that is, the global variable localization. This order is important, which is often the key to many local variable coverage exploits

3. Any location in HTTP can generate SQL injection, see the following example:

Create New Admin Exploit for php168 v4.0sp

In this example, the injection point occurs in the "X-forwarded-for" field, which is used by the application system to record the login user's IP, proxy IP business functions, but because there is no strict filtering, resulting in the injection of the occurrence


Target Application system: Acunetix Acuart Site

Injection point:? artist=1 '

Inject payload:

? artist=%40%40new%20union% 23sqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsql%0aselect %201,2,database%23sqlmap%0a%28%29

Payload Analysis:

Here's a combination of "MySQL note (MySQL Comment)" + "newline bypass (New line trick)" to bypass the MoD (essentially bypassing the regular expression used by MoD)

In MoD's view, our payload are as follows:

[Email protected] @new union# Sqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsql

Select 1,2,database#sqlmap


However, when this SQL code enters the MySQL parsing engine, MySQL sees this form:

[Email protected] @new Union select 1,2,database ()

Defense methods:

We know that SQL (Structure Query Language) is a flexible imperative language, the combination of elements can be a lot of different, the use of regular Regex method to match is often not accurate guidance, in order to solve this problem, we have two ways

1) Use higher-order SQL parsing methods, such as AST:

2) Improved regular, 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 Cha Racters 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.%{}-web_attack/restricted_sqli_chars-%{matched _var_name}=%{tx.0} "


Target Application system: Acunetix Acuart Site

Injection point:? artist=1 '


Inject payload:



Payload Analysis:

Here is a combination of "MySQL error echo" + "tab-delimited bypass" to bypass the MoD, where the key point is not to use traditional spaces for "Split and Balance".

Here is the blacklist idea, the "Split and Balance" defense if the blacklist easy to create bypass:

Https:// intermediary_character_30801873723976314

If the blacklist must be used, strict code auditing and testing are required to ensure the integrity of the blacklist.

For example, the delimiters allowed in MySQL are:







Defense methods:

Use the full "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.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. Summary

Blacklist filtering is not enough-do not rely on the blacklist mechanism

You should use a variety of methods for defense-in-depth

Use security model for input validation, including normalization, data type, data format, data length

WAF as a defensive means, from a certain program only increases the attacker's attack cost, and does not fundamentally solve the injection, to solve the injection of vulnerability, to protect sensitive data, must be multi-pronged, from the application system, WAF, database Firewall from the perspective of thinking

Original address:

Modsecurity SQL injection attack

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.