AppSecDC_2010-ModSecurityCRS_Ryan_Barnett

OWASP ModSecurity Core Rule
Set (CRS) Project
Ryan Barnett
OWASP CRS Project Leader
Senior Security Researcher
Ryan Barnett Background
•Trustwave
•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 Quick Overview
• The Core Rule Set (CRS) Overview
• Basic Detection Categories
• Latest CRS Improvements
• CRS Demonstration Page
• Future Directions
ModSecurity Quick Overview
What is ModSecurity?
 It is an open source web application firewall (WAF)
module for Apache web servers
www.modsecurity.org
Separate Rule and Audit Engines
Allows full request/response HTTP logging capability
Deep understanding of HTTP and HTML
Robust Parsing (form encoding, multipart, XML)
Event-based Rules Language
Anti-Evasion Features (normalization functions)
Advanced Capabilities
Transactional and Persistent Collections
Content Injection
Lua API
ModSecurity’s Rules Language Syntax
Tells ModSecurity how
to process data (such
@rx, @pm or @gt).
SecRule TARGETS OPERATOR [ACTIONS]
Tells ModSecurity where
to look (such as ARGS,
ARGS_NAMES or
COOKIES).
Tells ModSecurity what to
do if a rule matches (such
as deny, exec or setvar).
ModSecurity’s Apache Request Cycle Hooks
OWASP ModSecurity Core Rule
Set (CRS) Overview
Project Info
http://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project
What is the Core Rule Set (CRS)?
A generic, plug-n-play set of WAF rules
Choose your mode of operation
Standard vs. Anomaly Scoring
Detection Categories:
Protocol Validation
Malicious Client Identification
Generic Attack Signatures
Known Vulnerabilities Signatures
Trojan/Backdoor Access
Outbound Data Leakage
Anti-Virus and DoS utility scripts
Initial Configuration
Once unpacked, edit the main config file
modsecurity_crs_10_config.conf
Customize the following items
Mode of Detection – Standard vs. Anomaly Scoring
Anomaly Scoring Severity Levels
Enable/Disable Blocking
Blocking Threshold Levels
Paranoid Mode – aggressive inspection
HTTP Policy Settings
Choose where to log events (Apache error_log and/or
ModSecurity’s audit log)
Traditional Detection Mode
Self Contained Rules Concept
IDS/IPS mode with “self-contained” rules
Like HTTP itself – the rules are stateless
No intelligence is shared between rules
If a rule triggers, it will execute a disruptive/logging action
Easier for the new user to understand
Not optimal from a rules management perspective
(handling false positives/exceptions)
Not optimal from a security perspective
Not every site has the same risk tolerance
Lower severity alerts are largely ignored
Anomaly Scoring Detection Mode
Collaborative Rules Concept
Advanced inspection/detection mode
Delayed blocking
Rules set transactional variables (tx) to store temporary
meta-data about the rule match
Rules also increase anomaly scores for both the attack
category and global score
The anomaly score enforcement rules decide whether
or not to deny transactions at the end of the inbound
request phase
modsecurity_crs_49_inbound_blocking.conf
Anomaly Scoring - Debug Log View
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+5
Set 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+5
Set 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=1
Set 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: 1
Operator completed in 19 usec.Ctl: Set auditLogParts to ABIFHZE.Setting variable: tx.msg=%{rule.msg}
Inspecting Anomaly Scores
# 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}" chain
SecRule TX:ANOMALY_SCORE_BLOCKING "@streq on"
Conditional Rules (Weak Sigs)
SQL Injection Example
Aggregate indicators to determine an attack
Strong indicators
Keywords such as: xp_cmdshell, varchar,
Sequences such as: union …. select, select … top … 1
Amount: script, cookie and document appear in the
same input field
Weak indicators – meta-characters
--, ;, ', …
CRS only applies weak signatures in the event a
stronger signature has previously triggered
Conditional Rule Example
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)|group\b
\W*\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
Event Logging
Standard vs. Correlated Events
Standard mode
Rules log event data to both the Apache error_log and the
ModSecurity Audit log
Correlated mode
Basic rules are considered reference events and do not
directly log to the Apache error_log
Correlation rules in the logging phase analyze
inbound/outbound events and generate special events
modsecurity_crs_60_correlation.conf
Inbound/Outbound Correlation
Couple the inbound with the outbound for increased
intelligence
Was there an inbound attack?
Was there an HTTP Status Code Error (4xx/5xx level)?
Was there an application information leak?
Correlation facilitates better incident response
App error without inbound attack -> Contact Ops
Inbound attack + outbound error -> Contact Security
Event Severity Ratings
 Correlated Events
 0: Emergency - is generated from correlation (inbound attack +
outbound leakage)
 1: Alert - is generated from correlation (inbound attack + outbound
application level error)
 Non-Correlated Events
 2: Critical - highest severity level possible without correlation. It is
normally generated by the web attack rules (40 level files)
 3: Error - is generated from outbound leakage rules (50 level files)
 4: Warning - is generated by malicious client rules (35 level files)
 5: Notice - is generated by the Protocol policy and anomaly files
 6: Info - is generated by the search engine clients (55 marketing file)
Correlated Event Messages
Message: Pattern match "\;\W*?\bdrop\b" at TX:pm_sqli_data_REQUEST_URI.
[file "/opt/waschoneypot/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/waschoneypot/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/waschoneypot/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/waschoneypot/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"]
Detection Mechanisms: Protocol Violations
Protocol vulnerabilities such as Response Splitting,
Request Smuggling, Premature URL ending
Content length only for non GET/HEAD methods
Non ASCII characters or encoding in headers
Valid use of headers (for example, content length is numerical)
Proxy Access
modsecurity_crs_20_protocol_violations.conf
Attack requests are different due to automation
Missing headers such as Host, Accept, User-Agent
Host is an IP address (common worm propagation method)
modsecurity_crs_21_protocol_anomalies.conf
Detection Mechanisms: Protocol Policies
Policy is usually application specific
Some restrictions can usually be applied generically
White lists can be build for specific environments
Limitations on Sizes
Request size, Upload size
# of parameters, length of parameter
modsecurity_crs_23_request_limits.conf
Items that can be allowed or restricted
Methods - Allow or restrict WebDAV, block abused methods
such as CONNECT, TRACE or DEBUG
File extensions – backup files, database files, ini files
Content-Types (and to some extent other headers)
Modsecurity_crs_30_http_policy.conf
Detection Mechanisms: Malicious Clients
Not aimed against targeted attacks, but against general
malicious internet activity
Offloads a lot of cyberspace junk & noise
Effective against comment spam
Reduce event count
Detection of Malicious Robots
Unique request attributes: User-Agent header, URL, Headers
Black list of IP addresses
Rate based detection
Detection of security scanners
Blocking can confuse security testing software (WAFW00f)
 modsecurity_crs_35_bad_robots.conf
Detection Mechanisms: App Layer Attacks
Detect application level attacks such as those described
in the OWASP top 10
SQL injection and blind SQL injection
Cross site scripting (XSS)
OS command injection and remote command access
Remote file inclusion
 modsecurity_crs_40_generic_attacks.conf
 modsecurity_crs_41_sql_injection_attacks.conf
 modsecurity_crs_41_xss_attacks.conf
Known Vulnerability Signatures
 SpiderLabs received authorization from ET to convert
their Snort rules and include them in the CRS
 http://www.emergingthreats.net/
 Converted the following rule files
 emerging-web_server.rules
 emerging-web_specific_apps.rules
 Identifying attacks against known vulnerabilities does
have value
 Raised threat level
 If done correctly, lessens false positives
 CRS combines the what of our generic attack payload
detection with the where of ET known vuln data
Example Emerging Threats Rule
Attack vectorany -> $HTTP_SERVERS
alert tcp $EXTERNAL_NET
location –
$HTTP_PORTS (msg:"ET
WEB_SPECIFIC_APPS 20/20 Auto
URI + Parameter
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:webapplication-attack; reference:cve,CVE-2006-6092;
reference:url,www.securityfocus.com/bid/21154;
reference:url,doc.emergingthreats.net/2007504;
PCRE –
reference:url,www.emergingthreats.net/cgiWeak signature
bin/cvsweb.cgi/sigs/WEB_SPECIFIC_APPS/WEB_2020_Auto_g
allery; sid:2007504; rev:5;)
Converted Emerging Threats Rule
Verify the URI of
the request
# (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:norma
lisePathWin,capture,ctl:auditLogParts=+E,nolog,auditlog,logdata:'%{TX
.0}',id:sid2007508,rev:3,msg:'ET WEB_SPECIFIC 20/20 Auto Gallery SQL
Verify the attack vector
Injection Attempt -- vehiclelistings.asp
vehicleID ',tag:‘weblocation from saved TX SQL
application-attack',tag:'url,www.emergingthreats.net/cgiInjection data exists
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.%{rul
e.id}-SQL_INJECTION/SQL_INJECTION-%{matched_var_name}=%{matched_var}"
Detection Mechanisms: Trojans/Backdoors
Major problem in hosting environments
Uploading is allowed
Some sites may be secure while others not
Upload detection
Check uploading of files containing viruses (i.e. WORD docs)
util/modsec-clamscan.pl
Check uploading of http backdoor page
Access detection
Known signatures (x_key header)
Generic file management output (gid, uid, drwx, c:\)
 modsecurity_crs_45_trojans.conf
Detection Mechanisms: Information
Leakage
Monitoring outbound application data
HTTP Error Response Status Codes
SQL Information Leakage
Stack Dumps
Source Code Leakage
Last line of defense if all else fails
Provide feedback to application developers
Important for customer experience
Makes life for the hacker harder (if blocking is used)
modsecurity_crs_50_outbound.conf
Latest CRS Improvements:
v2.0.9
Latest Improvements
Lua port of PHPIDS Converter.php code
Advanced normalization functions
More accurate use of PHPIDS Filters
Centrifuge Generic Attack Payload Detection
Experimental Rules
Generic attack payload detection
CRS Demonstration Page
Request Header Tagging
Lua port of PHPIDS
 http://phpids.net/
 ~70 regular expression rules to detect common attack
payloads
 XSS
 SQL Injection
 RFI
 Filters are heavily tested by the community and updated
frequently
 Trustwave SpiderLabs worked with PHPIDS lead to port
code to Lua for use in ModSecurity’s API
 https://svn.php-ids.org/svn/trunk/lib/IDS/Converter.php
 https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xml
 Thanks to Mario Heiderich
Lua port of PHPIDS
 Example normalization functions
 --[[ 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 Example Filter
<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>
Converted PHPIDS Example Filters
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,aud
itlog,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 Code
 Negative security approach to combating XSS and SQL
Injection is doomed to fail…
 Unlimited ways to write functionally equivalent code
 Obfuscation 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 Port Demo
Experimental Generic Detection Rules
 Two new experimental/beta generic detection rules
 Optional_rules/modsecurity_crs_40_experimental.conf
 Restricted Character Anomaly Usage
 Analyzes the number and type of meta-characters present in a
payload
 Testing thus far shows that the detection is good except for freeform text fields.
 Need to adjust the anomaly scoring for you own site
 Repetitive use of non-Word characters
 Currently alerts if there are 4 or more special characters found in a
row
Live CRS Demonstration Page
Live CRS Demonstration Page
http://www.modsecurity.org/demo/
CRS Demonstration Page
 Request will go through CRS page first and then we proxy
the request to the PHPIDS page
 http://demo.php-ids.org/
 We then inspect the inbound with the outbound and
provide results
 CRS detected an attack
 CRS did not find anything malicious but PHPIDS did
 Neither CRS nor PHPIDS found anything malicious
 A link is provided to report false negatives to our JIRA
ticketing system
 https://www.modsecurity.org/tracker/browse/CORERULES
 We have received >6700 attacks thus far
CRS Demonstration Page
Demonstration page Demo
Request Header Tagging
CRS Demonstration Page
 When in a distributed architecture, you can share WAF
data with downstream hosts
 Similar to SMTP SPAM data added to mime-headers
 optional_rules/modsecurity_crs_49_header_tagging.c
onf
 Maps to AppSensor Detection Point – RP2 (Suspicious
External User Behavior)
Example Header Tagging
GET /path/to/foo.php?test=1%27%20or%20%272%27=%272%27;-- HTTP/1.1
Host: 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.5
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
X-WAF-Events: TX: / 999935-Detects common comment typesWEB_ATTACK/INJECTION-ARGS:test, TX:999923-Detects JavaScript
location/document property access and window access obfuscationWEB_ATTACK/INJECTION-REQUEST_URI_RAW, TX:950001WEB_ATTACK/SQL_INJECTION-ARGS:test
X-WAF-Score: Total=48; sqli=2; xss=
Connection: Keep-Alive
Future Directions
Future Directions
Preventing XSS with Content Injection
Javascript Sandboxing with Active Content Signatures
http://blog.modsecurity.org/2010/09/advanced-topic-of-theweek-xss-defense-via-content-injection.html
http://www.modsecurity.org/demo/demo-denynoescape.html
Implementing OWASP AppSensor Detection Points
We currently have some mappings for existing events
Will 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 done
 Test out the CRS demo page and report any issues found
either to the mail-list or to JIRA
 Need Rule Documentation help
 Please sign up on our project mail-list if you want to help
 https://lists.owasp.org/mailman/listinfo/owasp-modsecurity-corerule-set
Questions?
• Email – [email protected]
• Twitter - @ryancbarnett / @modsecurity