Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re2 support 942130 #2425

Merged
merged 4 commits into from
Apr 4, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 63 additions & 11 deletions rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
Expand Up @@ -558,21 +558,30 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:not\s+between\s+(?:(?:(?:'[^']*')|(?:
#
# -=[ SQL Tautologies ]=-
#
# Regexp generated from util/regexp-assemble/data/942130.data using Regexp::Assemble.
# To rebuild the regexp:
# cd util/regexp-assemble
# ./regexp-assemble.py 942130
# 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.
#
# The original 942130 was split in two rules:
# - 942130 targets tautologies using equalities (e.g. 1 = 1)
# - 942131 targets tautologies using inequalities (e.g. 1 != 2)
#
# We use captures to check for (in)equality in the regexp. So TX.1 will capture the left hand side (LHS) of the inequality,
# and TX.2 will capture the right hand side (RHS) of the logical query.
#
# Not supported by re2 (backreferences, lookaheads).
# To regenerate the regexp:
fzipi marked this conversation as resolved.
Show resolved Hide resolved
#
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))" \
# cd util/regexp-assemble
# ./regexp-assemble.py data/942130.data
fzipi marked this conversation as resolved.
Show resolved Hide resolved
#
SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?(?:(?:sounds\s+)?like|r(?:egexp|like)|<=>|=)[\s'\"`()]*?\b([\d\w]+)\b" \
"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.0} found within %{TX.942130_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
tag:'application-multi',\
tag:'language-multi',\
tag:'platform-multi',\
Expand All @@ -583,10 +592,53 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?(?:
tag:'paranoia-level/2',\
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.942130_lhs=%{TX.1}',\
setvar:'tx.942130_matched_var_name=%{matched_var_name}',\
chain"
SecRule TX:942130_lhs "@streq %{TX.2}" \
"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 chain starter rule uses the original prefix from the 942130.data in the regular expression.
fzipi marked this conversation as resolved.
Show resolved Hide resolved
# When the prefix matches, we store the match in a new variable for comparision in the chained rule.
fzipi marked this conversation as resolved.
Show resolved Hide resolved
#
# We use captures to check for (in)equality in the regexp. So TX.1 will capture the left hand side (LHS) of the inequality,
# and TX.2 will capture the right hand side (RHS) of the logical query.
#
fzipi marked this conversation as resolved.
Show resolved Hide resolved
# To regenerate the regexp:
#
# cd util/regexp-assemble
# ./regexp-assemble.py data/942131.data
fzipi marked this conversation as resolved.
Show resolved Hide resolved
#
SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?(?:not\s+(?:r(?:egexp|like)|like)|is\s+not|![<=>]|<[=>]?|>=?|\^)[\s'\"`()]*?\b([\d\w]+)\b" \
"id:942131,\
phase:2,\
block,\
capture,\
t:none,t:urlDecodeUni,t:replaceComments,\
msg:'SQL Injection Attack: SQL Boolean-based attack detected',\
fzipi marked this conversation as resolved.
Show resolved Hide resolved
logdata:'Matched Data: %{TX.0} found within %{TX.942131_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
tag:'application-multi',\
tag:'language-multi',\
tag:'platform-multi',\
tag:'attack-sqli',\
tag:'OWASP_CRS',\
tag:'capec/1000/152/248/66',\
tag:'PCI/6.5.2',\
tag:'paranoia-level/2',\
ver:'OWASP_CRS/3.4.0-dev',\
severity:'CRITICAL',\
multiMatch,\
setvar:'tx.942131_lhs=%{TX.1}',\
setvar:'tx.942131_matched_var_name=%{matched_var_name}',\
chain"
SecRule TX:942131_lhs "!@streq %{TX.2}" \
"t:none,\
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\
setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'"

#
# -=[ SQL Function Names ]=-
Expand Down
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,10 +78,10 @@ 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!=11"
version: HTTP/1.1
output:
log_contains: id "942130"
no_log_contains: id "942130"
- test_title: 942130-6
desc: "SQL Injection Attack: SQL Tautology"
stages:
Expand All @@ -92,11 +93,27 @@ 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=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%2042"
version: HTTP/1.1
output:
log_contains: id "942130"
- test_title: 942130-8
desc: "SQL Injection Attack: SQL Tautology"
stages:
- stage:
Expand All @@ -107,12 +124,12 @@ 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=This%20is%20like%20no%20other"
version: HTTP/1.1
output:
no_log_contains: id "942130"
- test_title: 942130-8
desc: "SQL Injection Attack: SQL Tautology"
- test_title: 942130-9
desc: "SQL Injection Attack: SQL Tautology using MySQL NULL-safe operator <=>"
fzipi marked this conversation as resolved.
Show resolved Hide resolved
stages:
- stage:
input:
Expand All @@ -122,7 +139,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=b,1=1"
uri: "/get?a=42<=>42"
version: HTTP/1.1
output:
log_contains: id "942130"
114 changes: 114 additions & 0 deletions tests/regression/tests/REQUEST-942-APPLICATION-ATTACK-SQLI/942131.yaml
@@ -0,0 +1,114 @@
---
meta:
author: "Felipe Zipitria"
description: SQL Tautology
enabled: true
name: 942131.yaml
tests:
- test_title: 942131-1
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=11!=1"
version: HTTP/1.1
output:
log_contains: id "942131"
- test_title: 942131-2
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=1!=11"
version: HTTP/1.1
output:
log_contains: id "942131"
- test_title: 942131-3
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=11!=11"
version: HTTP/1.1
output:
no_log_contains: id "942131"
- test_title: 942131-4
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=1%20is%20not%202"
version: HTTP/1.1
output:
log_contains: id "942131"
- test_title: 942131-5
desc: "SQL Injection Attack: SQL Tautology negative"
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=1%20is%20not%201"
version: HTTP/1.1
output:
no_log_contains: id "942131"
- test_title: 942131-6
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: POST
uri: "/post"
data: "a='1' not regexp '2'"
version: HTTP/1.1
output:
log_contains: id "942131"
- test_title: 942131-7
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: POST
uri: "/post"
data: "a='1' not regexp '1'"
version: HTTP/1.1
output:
no_log_contains: id "942131"
61 changes: 40 additions & 21 deletions util/regexp-assemble/data/942130.data
@@ -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,38 @@

##!+ i
fzipi marked this conversation as resolved.
Show resolved Hide resolved

[\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").

##! 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 logical construct.

##!^ [\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?
theseion marked this conversation as resolved.
Show resolved Hide resolved

##! 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'

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

##! <=> NULL-safe equal to operator in MySQL
fzipi marked this conversation as resolved.
Show resolved Hide resolved
<=>[\s'\"`()]*?\b([\d\w]+)\b

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

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([\d\w]+)\b
regexp[\s'\"`()]*?\b([\d\w]+)\b