Skip to content

Commit

Permalink
feat(re2): rewrites rule 942130 with re2 support
Browse files Browse the repository at this point in the history
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
  • Loading branch information
fzipi committed Mar 8, 2022
1 parent c134cea commit 37b138a
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 28 deletions.
19 changes: 12 additions & 7 deletions rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
Original file line number Diff line number Diff line change
Expand Up @@ -561,20 +561,22 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:not\s+between\s+(?:(?:(?:'[^']*')|(?:
# Boolean-based SQL injection or tautology attack. Boolean values (True or False) are used to carry out
# this type of SQL injection. The malicious SQL query forces the web application to return a different result de-
# pending on whether the query returns a TRUE or FALSE result.
#
# Regexp generated from util/regexp-assemble/data/942130.data using Regexp::Assemble.
#
# Regexp on the initial rule is the prefix commented on the 942130.data. When the prefix matches, we store
# the match to a new variable for comparing in the chained rule.
# The chained rule uses the assembled regexp in 942130.data to check for the right hand side of the logical query.
# To rebuild the regexp:
# cd util/regexp-assemble
# ./regexp-assemble.py data/942130-re2.data
##
SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?(?:<(?:=(?:[\s'\"`()]*?(?!\b\1\b)[\d\w]+|>[\s'\"`()]*?(?:\b\1\b))|>?[\s'\"`()]*?(?!\b\1\b)[\d\w]+)|(?:not\s+(?:regexp|like)|is\s+not|>=?|!=|\^)[\s'\"`()]*?(?!\b\1\b)[\d\w]+|(?:(?:sounds\s+)?like|r(?:egexp|like)|=)[\s'\"`()]*?(?:\b\1\b))" \
SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?" \
"id:942130,\
phase:2,\
block,\
capture,\
t:none,t:urlDecodeUni,t:replaceComments,\
msg:'SQL Injection Attack: SQL Tautology Detected',\
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
msg:'SQL Injection Attack: SQL Boolean-based attack Detected',\
logdata:'Matched Data: %{TX.lhs_942130} found within %{MATCHED_VAR_NAME}',\
tag:'application-multi',\
tag:'language-multi',\
tag:'platform-multi',\
Expand All @@ -586,8 +588,11 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?(?:
ver:'OWASP_CRS/3.4.0-dev',\
severity:'CRITICAL',\
multiMatch,\
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\
setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
setvar:'tx.lhs_942130=%{TX.1}',\
chain"
SecRule MATCHED_VAR "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?(?:<(?:=(?:[\s'\"`()]*?(?!\b\1\b)[\d\w]+|>[\s'\"`()]*?(?:\b\1\b))|>?[\s'\"`()]*?(?!\b\1\b)[\d\w]+)|(?:not\s+(?:regexp|like)|is\s+not|>=?|!=|\^)[\s'\"`()]*?(?!\b\1\b)[\d\w]+|(?:(?:sounds\s+)?like|r(?:egexp|like)|=)[\s'\"`()]*?(?:\b\1\b))" \
"setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\
setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'"


#
Expand Down
77 changes: 56 additions & 21 deletions util/regexp-assemble/data/942130.data
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
##! This is a data file used to generate a regular expression for a CRS rule.
##! The generation of the regular expression happens with the help of
##! This is a data file used to generate a regular expression for a CRS rule.
##! The generation of the regular expression happens with the help of
##! util/regexp-assemble/regexp-assemble.py.
##! The ID of the rule in question is part of the file name of this data file.
##! Read more about the format of this data file and the use of the assembly
##! The ID of the rule in question is part of the file name of this data file.
##! Read more about the format of this data file and the use of the assembly
##! script in util/regexp-assemble/README.md.
##!
##! Lines starting with `##!` are comments and will be skipped,
##! empty lines will be ignored completely.
##! In addition, the quote character `'` at the beginning of a line will
##! cause the line to be interpreted as literal by the cmdline preprocessor only.
##!
##!
##! Five special comments are at your disposal to influence the assembled expression:
##! - `##!+`: the flag comment
##! - `##!^`: the prefix comment
Expand All @@ -23,19 +23,54 @@

##!+ i

[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?=[\s'\"`()]*?(?:\b\1\b)
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?<=>[\s'\"`()]*?(?:\b\1\b)
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?like[\s'\"`()]*?(?:\b\1\b)
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?rlike[\s'\"`()]*?(?:\b\1\b)
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?sounds\s+like[\s'\"`()]*?(?:\b\1\b)
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?regexp[\s'\"`()]*?(?:\b\1\b)
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?!=[\s'\"`()]*?(?!\b\1\b)[\d\w]+
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?<=[\s'\"`()]*?(?!\b\1\b)[\d\w]+
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?>=[\s'\"`()]*?(?!\b\1\b)[\d\w]+
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?<>[\s'\"`()]*?(?!\b\1\b)[\d\w]+
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?<[\s'\"`()]*?(?!\b\1\b)[\d\w]+
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?>[\s'\"`()]*?(?!\b\1\b)[\d\w]+
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?\^[\s'\"`()]*?(?!\b\1\b)[\d\w]+
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?is\s+not[\s'\"`()]*?(?!\b\1\b)[\d\w]+
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?not\s+like[\s'\"`()]*?(?!\b\1\b)[\d\w]+
[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?not\s+regexp[\s'\"`()]*?(?!\b\1\b)[\d\w]+
##! General comments:
##!
##! The idea behind this expressions is to capture simple logic based (un)equalities that
##! are used to quickly test SQL Logic that always returns TRUE (hence the term "SQL Tautology").

##! Prefix: captures the initial part that will be matched on the right hand side of the logicl construct.
##! This goes into the first rule of the chain:
##! [\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?

##! These expressions try to match the logic using the operator,
##! so when the operator targets a TRUE operation, the initial match
##! should be present after the operator, logically meaning TRUE
##!
##! Examples:
##! '1' = '1'
##! 'f' like 'f'

=[\s'\"`()]*?(?:\b%{tx.lhs_942130}\b)
<=>[\s'\"`()]*?(?:\b%{tx.lhs_942130}\b)

##! Like queries allow you to use wilcards: '%'

like[\s'\"`()]*?(?:\b%?%{tx.lhs_942130}%?\b)
sounds\s+like[\s'\"`()]*?(?:\b%?%{tx.lhs_942130}%?\b)

##! String based regexp. These don't use % as wildcard.
rlike[\s'\"`()]*?(?:\b%{tx.lhs_942130}\b)
regexp[\s'\"`()]*?(?:\b%{tx.lhs_942130}\b)

##! These expressions try to match the logic using the negative operator,
##! so when the operator targets a false operation, the initial match
##! should *not* be present after the operator, effectively meaning TRUE
##!
##! Examples:
##! '1' <= '2'
##! 'a' not like 'b'

\!=[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)
<=[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)
>=[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)
<>[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)
<[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)
>[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)
\^[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)
is\s+not[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)
not\s+like[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)

##! String based regexp.

not\s+rlike[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)
not\s+regexp[\s'\"`()]*?(?!\b%{tx.lhs_942130}\b)

0 comments on commit 37b138a

Please sign in to comment.