OWASP ModSecurity Core Rule Set (CRS) Project
Ryan BarnettOWASP CRS Project LeaderSenior Security Researcher
Ryan Barnett - BackgroundTrustwave•SpiderLabs Research Team
•Web application firewall research/development
•ModSecurity Community Manager•Interface with the community on
public mail-list
•Steer the internal development of ModSecurity
Author•“Preventing Web Attacks with Apache”
Community Projects• Open Web Application Security Project (OWASP)
• Project Leader, ModSecurity Core Rule Set
• Project Contributor, OWASP Top 10
• Project Contributor, AppSensor
• Web Application Security Consortium (WASC)
• Project Leader, Web Hacking Incident Database
• Project Leader, Distributed Web Honeypots
• Project Contributor, Web Application Firewall Evaluation Criteria
• Project Contributor, Threat Classification
• The SANS Institute
• Courseware Developer/Instructor
• Project Contributor, CWE/SANS Top 25 Worst Programming Errors
Session Outline• ModSecurity
• Core Rule Set (CRS)
•
• CRS
• CRS Demonstration Page
•
ModSecurity
open source web application firewall (WAF) module Apache web servers
www.modsecurity.org Rule Audit Engines
HTTP HTTP HTML
Parsing (form encoding, multipart, XML) Rules
)
Transactional and Persistent CollectionsContent Injection
ModSecurity’s Rules
SecRule TARGETS OPERATOR [ACTIONS]
ModSecurity
ARGS, ARGS_NAMES or
COOKIES).
ModSecurity
@rx, @pm or @gt).
ModSecurity 0 ,
deny
exec or setvar).
ModSecurity’s Apache
OWASP ModSecurity (Core Rule
Set - CRS)
Core Rule Set (CRS)?
, plug-n-play WAF-
vs.
:
Trojan/Backdoor
DoS
modsecurity_crs_10_config.conf
– vs.
(Enable/Disable)
Paranoid – HTTP
, (Apache error_log /
« » IDS/IPS “ ”
HTTP –
, disruptive/logging
)
(tx)
,
, , ,
. modsecurity_crs_49_inbound_blocking.conf
Target value: "" OR 1=1#"AdResolved macro %{rule.msg} to: SQL Injection AttackSet variable "tx.msg" to "SQL Injection Attack".
Setting variable: tx.sql_injection_score=+%{tx.critical_anomaly_score}Recorded original collection variable: tx.sql_injection_score = "0"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: sql_injection_score=0+5Set variable "tx.sql_injection_score" to "5".Setting variable: tx.anomaly_score=+%{tx.critical_anomaly_score}Original collection variable: tx.anomaly_score = "3"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: anomaly_score=3+5Set variable "tx.anomaly_score" to "8".Setting variable: tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}Resolved macro %{rule.id} to: 950901
Resolved macro %{matched_var_name} to: ARGS:prod_id
Resolved macro %{tx.0} to: 1=1Set variable "tx.950901-WEB_ATTACK/SQL_INJECTION-ARGS:prod_id" to "1=1".
Warning. Pattern match "\b(\d+) ?(?:=|<>|<=>|<|>|!=) ?\1\b|[\'"\`\´\’\‘](\d+)[\'"\`\´\’\‘] ?(?:=|<>|<=>|<|>|!=) ?[\'"\`\´\’\‘]\2\b|[\'"\`\´\‘](\w+)[\'"\`\´\’\‘] ?(?:=|<>|<=>|<|>|!=) ?[\'"\`\´\’\‘]\3\b|([\'"\;\`\´\’\‘]*)?\s+(and|or)\s+([\s\'"\` ..." at ARGS:prod_id. [file "/usr/local/apache/conf/modsec_current/base_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "425"] [id "950901"] [rev "2.0.9"] [msg "SQL Injection Attack"] [data "1=1"] [severity "CRITICAL"]
ded regex subexpression to TX.0: 1=1Added regex subexpression to TX.1: 1Operator completed in 19 usec.Ctl: Set auditLogParts to ABIFHZE.Setting variable: tx.msg=%{rule.msg}
# Alert and Block based on Anomaly Scores
SecRule TX:ANOMALY_SCORE "@gt 0" \"chain,phase:2,t:none,nolog,auditlog,deny,msg:'Inbound Anomaly
Score Exceeded (Total Score: %{TX.ANOMALY_SCORE}, SQLi=%{TX.SQL_INJECTION_SCORE}, XSS=%{TX.XSS_SCORE}): tx.msg}',setvar:tx.inbound_tx_msg=%{tx.msg},setvar:tx.inbound_anom
aly_score=%{tx.anomaly_score}"SecRule TX:ANOMALY_SCORE "@ge
tx.inbound_anomaly_score_level}" chainSecRule TX:ANOMALY_SCORE_BLOCKING "@streq on"
(Weak Sigs) SQL Injection
, : xp_cmdshell, varchar, , : union …. select, select
top … 1Amount: script, cookie document
--, ;, ', …
CRS
SecMarker BEGIN_SQL_INJECTION_WEAK
SecRule &TX:/SQL_INJECTION/ "@eq 0" "phase:2,t:none,nolog,pass,skipAfter:END_SQL_INJECTION_WEAK"
SecRule TX:/SQL_INJECTION/ \b(?:rel(?:(?:nam|typ)e|kind)|a(?:ttn(?:ame|um)|scii)|c(?:o(?:nver|un)t|ha?r
)|s(?:hutdown|elect)|to_(?:numbe|cha)r|u(?:pdate|nion)|d(?:elete|rop)|groupW*\bby|having|insert|length|where)\b" \
"phase:2,chain,capture,t:none,ctl:auditLogParts=+E,block,nolog,auditlog,msg:'SQL Injection Attack',id:'950001',tag:'WEB_ATTACK/SQL_INJECTION',logdata:'%{TX.0}',severity:'2'"
SecRule MATCHED_VAR "(?:[\\\(\)\%#]|--)" \"t:none,setvar:'tx.msg=%{rule.msg}',setvar:tx.sqli_score=+1,setvar:tx.a
nomaly_score=+20,setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{matched_var}"
SecMarker END_SQL_INJECTION_WEAK
vs.
Apache error_log, ModSecurity Audit log
Apache error_log
/
modsecurity_crs_60_correlation.conf
/
? HTTP Status Code Error (4xx/5xx )?
?
-> Contact Ops + -> Contact Security
0: Emergency ( )
1: Alert + )
2: Critical – , ,
. level files)3: Error –
(50 level files)4: Warning
(35 level files)5: Notice 6: Info – engine (55 marketing file)
Message: Pattern match "\;\W*?\bdrop\b" at TX:pm_sqli_data_REQUEST_URI. [file "/opt/wasc-honeypot/etc/rules/base_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "262"] [id "959001"] [msg "SQL Injection Attack"] [data "; drop"] [severity "CRITICAL"] [tag "WEB_ATTACK/SQL_INJECTION"]
Message: Operator GE matched 0 at TX:anomaly_score. [file "/opt/wasc-honeypot/etc/rules/base_rules/modsecurity_crs_49_enforcement.conf"] [line "30"] [msg "Anomaly Score Exceeded (score 55): SQL Injection Attack Detected"]Message: Pattern match "\bsupplied argument is not a valid MySQL\b" at RESPONSE_BODY. [file "/opt/wasc-honeypot/etc/rules/base_rules/modsecurity_crs_50_outbound.conf"] [line "259"] [id "971156"] [msg "SQL Information Leakage"] [severity "ERROR"] [tag "LEAKAGE/ERRORS"]Message: Warning. Operator GE matched 1 at TX. [file "/opt/wasc-honeypot/etc/rules/base_rules/modsecurity_crs_60_correlation.conf"] [line "24"] [msg "Correlated Successful Attack Identified: Inbound Attack (SQL Injection Attack Detected) + Outbound Data Leakage (SQL Information Leakage)
(Transactional Anomaly Score: 85)"] [severity "EMERGENCY"]
, , Request Smuggling,
URL GET/HEAD
ASCII ,
)
modsecurity_crs_20_protocol_violations.conf
, Host, Accept, User-Agent IP- (
)modsecurity_crs_21_protocol_anomalies.conf
, # , modsecurity_crs_23_request_limits.conf
, ,
– WebDAV, « » , CONNECT, TRACE
DEBUG – backup , , ini-
Content-Types ( )
, -
&
: User-Agent header, URL, Headers IP-
, (rate)
(WAFW00f)
modsecurity_crs_35_bad_robots.conf
, , OWASP top 10
SQL injection blind SQL injectionCross site scripting (XSS)OS command injection
modsecurity_crs_40_generic_attacks.confmodsecurity_crs_41_sql_injection_attacks.confmodsecurity_crs_41_xss_attacks.conf
SpiderLabs ET Snort
CRShttp://www.emergingthreats.net/
emerging-web_server.rulesemerging-web_specific_apps.rules
,
CRS
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"ET WEB_SPECIFIC_APPS 20/20 Auto Gallery SQL Injection Attempt -- vehiclelistings.asp vehicleID SELECT"; flow:established,to_server; uricontent:"/vehiclelistings.asp?"; nocase; uricontent:"vehicleID="; nocase; uricontent:"SELECT"; nocase; pcre:"/.+SELECT.+FROM/Ui"; classtype:web-application-attack; reference:cve,CVE-2006-6092; reference:url,www.securityfocus.com/bid/21154; reference:url,doc.emergingthreats.net/2007504; reference:url,www.emergingthreats.net/cgi-bin/cvsweb.cgi/sigs/WEB_SPECIFIC_APPS/WEB_2020_Auto_gallery; sid:2007504; rev:5;)
–
URI + Parameter
PCRE –
# (sid 2007508) ET WEB_SPECIFIC 20/20 Auto Gallery SQL Injection Attempt -- vehiclelistings.asp vehicleID
SecRule REQUEST_URI_RAW "(?i:\/vehiclelistings\.asp)" "chain,phase:2,block,t:none,t:urlDecodeUni,t:htmlEntityDecode,t:normalisePathWin,capture,ctl:auditLogParts=+E,nolog,auditlog,logdata:'%{TX.0}',id:sid2007508,rev:3,msg:'ET WEB_SPECIFIC 20/20 Auto Gallery SQL Injection Attempt -- vehiclelistings.asp vehicleID ',tag:‘web-application-attack',tag:'url,www.emergingthreats.net/cgi-bin/cvsweb.cgi/sigs/WEB_SQL_INJECTION/WEB_2020_Auto_gallery'"
SecRule &TX:'/SQL_INJECTION.*ARGS:vehicleID/' "@gt 0" "setvar:'tx.msg=ET WEB_SPECIFIC 20/20 Auto Gallery SQL Injection Attempt -- vehiclelistings.asp vehicleID',setvar:tx.sqli_score=+1,setvar:tx.anomaly_score=+20,setvar:tx.%{rule.id}-SQL_INJECTION/SQL_INJECTION-%{matched_var_name}=%{matched_var}"
URI
TX SQL Injection
,
,
, , WORD docs)
util/modsec-clamscan.pl
http- c backdoor
(x_key )Generic file management output (gid, uid, drwx, c:\)modsecurity_crs_45_trojans.conf
:
HTTP Error SQL
,
)
modsecurity_crs_50_outbound.conf
CRS:v2.0.9
Lua of PHPIDS Converter.php
PHPIDS-
CRS
Lua PHPIDS
http://phpids.net/~70
XSSSQL InjectionRFI
Trustwave SpiderLabs PHPIDS Lua
ModSecurity’s APIhttps://svn.php-ids.org/svn/trunk/lib/IDS/Converter.phphttps://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xmlThanks to Mario Heiderich
Lua PHPIDS
--[[ Make sure the value to normalize and monitor doesn't contain Regex DoS
--[[ Check for comments and erases them if available ]]
--[[ Strip newlines ]]
--[[ Checks for common charcode pattern and decodes them ]]
--[[ Eliminate JS regex modifiers ]]
--[[ Converts from hex/dec entities ]]
--[[ Normalize Quotes ]]
--[[ Converts SQLHEX to plain text ]]
--[[ Converts basic SQL keywords and obfuscations ]]
--[[ Detects nullbytes and controls chars via ord() ]]
--[[ This method matches and translates base64 strings and fragments ]]
--[[ Strip XML patterns ]]
--[[ This method converts JS unicode code points to regular characters ]]
--[[ Converts relevant UTF-7 tags to UTF-8 ]]
--[[ Converts basic concatenations ]]
--[[ This method collects and decodes proprietary encoding types ]]
PHPIDS
<filter> <id>1</id> <rule><![CDATA[(?:"[^"]*[^-
]?>)|(?:[^\w\s]\s*\/>)|(?:>")]]></rule> <description>finds html breaking injections
including whitespace attacks</description> <tags>
<tag>xss</tag> <tag>csrf</tag>
</tags> <impact>4</impact>
</filter>
PHPIDS
SecRule TX:'/^(QUERY_|REQUEST_|ARGS:).*_normalized/' "(?:\<\w*:?\s(?:[^\>]*)t(?!rong))|(?:\<scri)|(<\w+:\w+)" "phase:2,capture,t:none,pass,skip:1,nolog,auditlog,msg:'Detects obfuscated script tags and XML wrapped HTML',id:'9000033',tag:'WEB_ATTACK/XSS',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.id}-%{rule.msg}',setvar:tx.anomaly_score=+4,setvar:'tx.%{tx.msg}-WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}'"
SecRule TX:PARANOID_MODE "@eq 1" "chain,phase:2,t:none,logdata:'%{TX.0}',severity:'2',pass,nolog,auditlog,msg:'Detects obfuscated script tags and XML wrapped HTML',id:'9000033',tag:'WEB_ATTACK/XSS'"
SecRule ARGS|REQUEST_BODY|REQUEST_URI_RAW "(?:\<\w*:?\s(?:[^\>]*)t(?!rong))|(?:\<scri)|(<\w+:\w+)" "capture,multiMatch,t:none,t:urlDecodeUni,t:cssDecode,t:jsDecode,t:htmlEntityDecode,t:replaceComments,t:compressWhiteSpace,t:lowercase,setvar:'tx.msg=%{rule.id}-%{rule.msg}',setvar:tx.anomaly_score=+4,setvar:'tx.%{tx.msg}-WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}'"
Centrifuge
Negative security approach to combating XSS and SQL Injection is doomed to fail…
Unlimited ways to write functionally equivalent codeObfuscation methods, however often have certain characteristics
PHPIDS has an interesting approach to identify attack payloads through heuristics called Centrifuge
Analysis of the use of special characters
Ratio between the count of the word characters, spaces, punctuation and the non word characters
If <3.49 = malicious
Normalization and stripping of any word character and spaces including line breaks, tabs and carriage returns
Regex check in default_filters.xml catches results
PHPIDS Lua
/beta
Optional_rules/modsecurity_crs_40_experimental.conf
,
, , , ,
.
,
(alerts), 4
CRS
CRS
CRS
PHPIDShttp://demo.php-ids.org/
,
CRS CRS , PHPIDS
CRS, PHPIDS
JIRA ticketing
https://www.modsecurity.org/tracker/browse/CORERULES
>6700
CRS
Demonstration page Demo
CRS
share WAF
SMTP SPAM- mime-headersoptional_rules/modsecurity_crs_49_header_tagging.conf
AppSensor – RP2 )
GET /path/to/foo.php?test=1%27%20or%20%272%27=%272%27;-- HTTP/1.1Host: www.example.com User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.5) Gecko/20091109 Ubuntu/9.10 (karmic) Firefox/3.5.5Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-us,en;q=0.5Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
WAF-Events: TX: / 999935-Detects common comment types-WEB_ATTACK/INJECTION-ARGS:test, TX:999923-Detects JavaScript location/document property access and window access obfuscationWEB_ATTACK/INJECTION-REQUEST_URI_RAW, TX:950001-WEB_ATTACK/SQL_INJECTION-ARGS:test
WAF-Score: Total=48; sqli=2; xss=Connection: Keep-Alive
XSS with Content InjectionJavascript Sandboxing with Active Content Signatureshttp://blog.modsecurity.org/2010/09/advanced-topic-of-theweek-xss-defense-via-content-injection.htmlhttp://www.modsecurity.org/demo/demo-deny-noescape.html
OWASP AppSensorWe currently have some mappings for existing eventsWill be using Lua to implement other aggregate/behavioral/trend detection Points
Call for Community Help
We have made great strides with CRS v2.0 but there is still much work to be doneTest out the CRS demo page and report any issues found either to the mail-list or to JIRANeed Rule Documentation helpPlease sign up on our project mail-list if you want to help
https://lists.owasp.org/mailman/listinfo/owasp-modsecurity-corerule-set