Skip to content

Commit

Permalink
Update util/regexp-assemble/data/942131.data
Browse files Browse the repository at this point in the history
Co-authored-by: Max Leske <th3s3ion@gmail.com>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
  • Loading branch information
fzipi and theseion committed Mar 22, 2022
1 parent 6c20ed0 commit 9afbf38
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 48 deletions.
36 changes: 20 additions & 16 deletions rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
Original file line number Diff line number Diff line change
Expand Up @@ -566,23 +566,22 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:not\s+between\s+(?:(?:(?:'[^']*')|(?:
# - 942130 targeting "true" tautologies (e.g. 1 = 1)
# - 942131 targeting "false" tautologies (e.g. 1 != 2)
#
# The regexp written at the initial rule on the chain is the original prefix from the 942130.data.
# When the prefix matches, we store the match to a new variable for comparing in the chained rule.
# We use captures to check for (in)equality in the regexp. So TX.1 will capture the left and side of the inequality,
# and TX.2 + TX.3 will capture the right hand side of the logical query.
#
# The chained rule then uses the assembled regexp from 942130.data to check for the right hand side of the logical query.
# To regenerate the regexp:
#
# To rebuild the regexp:
# cd util/regexp-assemble
# ./regexp-assemble.py data/942130.data
#
SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?" \
SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?(?:(?:r(?:egexp|like)|<=>|=)[\s'\"`()]*?\b([\d\w]+)\b|(?:sounds\s+)?like[\s'\"`()]*?%?\b([\d\w]+)\b%?)" \
"id:942130,\
phase:2,\
block,\
capture,\
t:none,t:urlDecodeUni,t:replaceComments,\
t:none,t:replaceComments,\
msg:'SQL Injection Attack: SQL Boolean-based attack Detected',\
logdata:'Matched Data: %{TX.lhs_942130} found within %{MATCHED_VAR_NAME}',\
logdata:'Matched Data: %{MATCHED_VARS} found within %{MATCHED_VAR_NAME}',\
tag:'application-multi',\
tag:'language-multi',\
tag:'platform-multi',\
Expand All @@ -592,25 +591,29 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?" \
tag:'PCI/6.5.2',\
tag:'paranoia-level/2',\
ver:'OWASP_CRS/3.4.0-dev',\
setvar:'tx.lhs_942130=/%{TX.1}/',\
severity:'CRITICAL',\
multiMatch,\
setvar:'tx.lhs_942130=%{TX.1}',\
chain"
SecRule MATCHED_VAR "@rx (?i)(?:(?:r(?:egexp|like)|<=>|=)[\s'\"`()]*?(?:\b%{tx.lhs_942130}\b)|(?:sounds\s+)?like[\s'\"`()]*?(?:\b%?%{tx.lhs_942130}%?\b))" \
"setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\
SecRule TX:lhs_942130 "@within /%{TX.2}/ /%{TX.3}/" \
"t:none,\
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\
setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'"

# Rule Targeting logical inequalities that return TRUE (e.g. 1 != 2)
#
# The regexp written at the initial rule on the chain is the original prefix from the 942130.data.
# When the prefix matches, we store the match to a new variable for comparing in the chained rule.
#
# The chained rule then uses the assembled regexp from 942130.data to check for the right hand side of the logical query.
# To rebuild the regexp:
# We use captures to check for (in)equality in the regexp. So TX.1 will capture the left and side of the inequality,
# and TX.2, TX.3 and TX.4 will capture the right hand side of the logical query.
#
# To regenerate the regexp:
#
# cd util/regexp-assemble
# ./regexp-assemble.py data/942131.data
#
SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?" \
SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?(?:not\s+(?:r(?:egexp|like)[\s'\"`()]*?\b([\d\w]+)\b|like[\s'\"`()]*?(?:d\b([\d\w]+)\b))|(?:is\s+not|![<=>]|<[=>]?|>=?|\^)[\s'\"`()]*?\b([\d\w]+)\b)" \
"id:942131,\
phase:2,\
block,\
Expand All @@ -629,10 +632,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.lhs_942131=%{TX.1}',\
setvar:'tx.lhs_942131=/%{TX.1}/',\
chain"
SecRule MATCHED_VAR "!@rx (?i)(?:not\s+(?:r(?:egexp|like)[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)|like[\s'\"`()]*?(?:d\b%{tx.lhs_942131}\b))|(?:is\s+not|![<=>]|<[=>]?|>=?|\^)[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b))" \
"setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\
SecRule TX:lhs_942131 "!@within /%{TX.2}/ /%{TX.3}/ /%{TX.4}/" \
"t:none,\
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\
setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'"

#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ tests:
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: POST
port: 80
uri: /post
data: "var=%221%22%20sSOUNDS%20LIKE%20%22SOUNDS%20LIKE%201&other_var=test"
version: HTTP/1.0
output:
Expand All @@ -32,7 +33,7 @@ tests:
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/?a=1=1"
uri: "/get?a=1=1"
version: HTTP/1.1
output:
log_contains: id "942130"
Expand All @@ -47,7 +48,7 @@ tests:
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/?a=11=1"
uri: "/get?a=11=1"
version: HTTP/1.1
output:
no_log_contains: id "942130"
Expand All @@ -62,7 +63,7 @@ tests:
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/?a=1=11"
uri: "/get?a=1=11"
version: HTTP/1.1
output:
no_log_contains: id "942130"
Expand All @@ -77,7 +78,7 @@ tests:
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/?a=11!=11"
uri: "/get?a=11!=11"
version: HTTP/1.1
output:
no_log_contains: id "942130"
Expand All @@ -92,7 +93,53 @@ tests:
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/?a=b,1=1"
uri: "/get?a=b,1=1"
version: HTTP/1.1
output:
log_contains: id "942130"
- test_title: 942130-7
desc: "SQL Injection Attack: SQL Tautology - like"
stages:
- stage:
input:
dest_addr: 127.0.0.1
headers:
Host: localhost
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: POST
uri: "/post"
data: "a=42%20like%20%2542"
version: HTTP/1.1
output:
log_contains: id "942130"
- test_title: 942130-8
desc: "SQL Injection Attack: SQL Tautology"
stages:
- stage:
input:
dest_addr: 127.0.0.1
headers:
Host: localhost
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/get?a=This%20is%20like%20no%20other"
version: HTTP/1.1
output:
no_log_contains: id "942130"
- test_title: 942130-9
desc: "SQL Injection Attack: SQL Tautology using MySQL NULL-safe operator <=>"
stages:
- stage:
input:
dest_addr: 127.0.0.1
headers:
Host: localhost
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/get?a=42<=>42"
version: HTTP/1.1
output:
log_contains: id "942130"
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ tests:
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/?a=11!=1"
uri: "/get?a=11!=1"
version: HTTP/1.1
output:
log_contains: id "942131"
Expand All @@ -31,7 +31,7 @@ tests:
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/?a=1!=11"
uri: "/get?a=1!=11"
version: HTTP/1.1
output:
log_contains: id "942131"
Expand All @@ -46,7 +46,7 @@ tests:
User-Agent: OWASP ModSecurity Core Rule Set
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
method: GET
uri: "/?a=11!=11"
uri: "/get?a=11!=11"
version: HTTP/1.1
output:
no_log_contains: id "942131"
21 changes: 12 additions & 9 deletions util/regexp-assemble/data/942130.data
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,19 @@
##! - cmdline [windows|unix] (file scope)
##! Please refer to util/regexp-assemble/README.md for a full explanation

##!+ i

##! 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").

##! We also want to capture the left and right side, and compare for equality.
##! That's why you see below that some of the patterns include grouping explicitly

##! 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'\"`()]*?

##!+ i
##!^ [\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
Expand All @@ -42,16 +44,17 @@
##! 'f' like 'f'

##! This one will also match the "equal" part of '<=' and '>='
=[\s'\"`()]*?(?:\b%{tx.lhs_942130}\b)
=[\s'\"`()]*?\b([\d\w]+)\b

<=>[\s'\"`()]*?(?:\b%{tx.lhs_942130}\b)
##! <=> NULL-safe equal to operator in MySQL
<=>[\s'\"`()]*?\b([\d\w]+)\b

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

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

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

34 changes: 19 additions & 15 deletions util/regexp-assemble/data/942131.data
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,38 @@

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

##!^ [\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?

##!+ i

##! 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
##! should *not* be present after the operator, effectively meaning TRUE.
##! NOTE: The expressions actually *do* try to match the left hand side of the
##! operation. We use the "inversion operator" (`!@rx`) to make the rule
##! execute when the expression *doesn't* match.
##!
##! Examples:
##! '1' <= '2'
##! 'a' not like 'b'
##!
##! SQL Comparison Operators: =, !=, <=, >=, <>, <, >, !>, !<, ^

\!=[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
<>[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
<[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
\!<[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
>[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
\!>[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
<=[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
>=[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
\^[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
\!=[\s'\"`()]*?\b([\d\w]+)\b
<>[\s'\"`()]*?\b([\d\w]+)\b
<[\s'\"`()]*?\b([\d\w]+)\b
\!<[\s'\"`()]*?\b([\d\w]+)\b
>[\s'\"`()]*?\b([\d\w]+)\b
\!>[\s'\"`()]*?\b([\d\w]+)\b
<=[\s'\"`()]*?\b([\d\w]+)\b
>=[\s'\"`()]*?\b([\d\w]+)\b
\^[\s'\"`()]*?\b([\d\w]+)\b

is\s+not[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
not\s+like[\s'\"`()]*?(?:d\b%{tx.lhs_942131}\b)
is\s+not[\s'\"`()]*?\b([\d\w]+)\b
not\s+like[\s'\"`()]*?(?:d\b([\d\w]+)\b)

##! String based regexp.

not\s+rlike[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
not\s+regexp[\s'\"`()]*?(?:\b%{tx.lhs_942131}\b)
not\s+rlike[\s'\"`()]*?\b([\d\w]+)\b
not\s+regexp[\s'\"`()]*?\b([\d\w]+)\b

0 comments on commit 9afbf38

Please sign in to comment.