Chapter 13

Passive Response Actions

Hence, when able to attack, we must seem unable; when using our forces, we must seem inactive.

—Sun Tzu in The Art of War

Passive response actions are any changes or actions made as a result of detection rules that the end user cannot directly perceive. These actions have no direct impact on the user or his or her web application session. These scenarios often are not severe enough to warrant any active or intrusive response actions. These responses may simply provide information to third-party systems or security personnel for further review.


Recipe 13-1: Tracking Anomaly Scores
This recipe shows you how to utilize anomaly scoring to track suspicious behavior across multiple requests.
Ingredients
  • ModSecurity
    • TX:ANOMALY_SCORE variable
    • IP:ANOMALY_SCORE variable
    • SESSION:ANOMALY_SCORE variable
    • @gt operator
    • @ge operator
    • @lt operator
    • setvar action
    • initcol action
    • setsid action
Per-Transaction Anomaly Scores
Many detection recipes in Part II showed examples of using transactional anomaly scores. This is done by using the ModSecurity setvar action to increment the anomaly_score variable in the transient TX collection. Here is an example taken from the modsecurity_crs_41_sql_injection.conf file:
#
# -=[ SQL Tautologies ]=-
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|
REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* 
"(?i:([s'"'´''()]*)([dw]++)([s'"'´''()]*)(?:(?:=|<=>|r?lik
e|soundss+like|regexp)([s'"'´''()]*)2|(?:!=|<=|>=|<>|<|>|^|is
s+not|nots+like|nots+regexp)([s'"'´''()]*)(?!2)([dw]+)))"
        "phase:2,rev:'2',ver:'OWASP_CRS/2.2.6',maturity:'9',accuracy
:'8',capture,multiMatch,t:none,t:urlDecodeUni,t:replaceComments,
ctl:auditLogParts=+E,block,msg:'SQL Injection Attack',id:'950901',
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}:
 %{MATCHED_VAR}',severity:'2',
tag:'OWASP_CRS/WEB_ATTACK/SQL_INJECTION',
tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',
tag:'OWASP_AppSensor/CIE1',
tag:'PCI/6.5.2',setvar:'tx.msg=%{rule.msg}',
setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score},
setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},
setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/SQL_INJECTION-
%{matched_var_name}=%{tx.0}"
This setvar action increases the transactional anomaly score by the amount specified in the macro variable. Let’s look at a quick SQL Injection attack request:
http://localhost/products.php?prod_id=84'%20or%20'9'!=%228%22;--
This request would trigger the following in the ModSecurity debug log file:
Target value: "prod_id"
Operator completed in 69 usec.
T (0) urlDecodeUni: "prod_id"
T (0) replaceComments: "prod_id"
Transformation completed in 1 usec.Executing operator "rx" with 
param
 "(?i:([\s'"'xc2xb4xe2x80x99xe2x80x98\(\)]*)?([\d\w]+)
([\s'"'xc2xb4xe2x80x99xe2x80x98\(\)]*)?(?:=|<=>|r?like|
sounds\s+like|regexp)([\s'"'xc2xb4xe2x80x99xe2x80x98\(\
)]*)?\2|([\s'"'xc2xb4xe2x80x99xe2x80x98\(\)]*)?([\d\w
]+)([\s'"'xc2xb4xe2x80x99xe2x80x98\(\)]*)?(?:!=|<=|>=|<>
|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'"'xc2xb4xe2x
80x99xe2x80x98\(\)]*)?(?!\6)([\d\w]+))" against 
ARGS:prod_id.
Target value: "84' or '9'!="8";--"
Added regex subexpression to TX.0:  '9'!="8
Added regex subexpression to TX.1:
Added regex subexpression to TX.2:
Added regex subexpression to TX.3:
Added regex subexpression to TX.4:
Added regex subexpression to TX.5:  '
Added regex subexpression to TX.6: 9
Added regex subexpression to TX.7: '
Added regex subexpression to TX.8: "
Added regex subexpression to TX.9: 8
Operator completed in 136 usec.
Ctl: Set auditLogParts to ABIJDEFHE.
Setting variable: tx.msg=%{rule.msg}
Resolved macro %{rule.msg} to: SQL Injection Attack
Set variable "tx.msg" to "SQL Injection Attack".
Setting variable: tx.sql_injection_score=
+%{tx.critical_anomaly_score}
Original collection variable: tx.sql_injection_score = "3"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: sql_injection_score=3+5
Set variable "tx.sql_injection_score" to "8".
Setting variable: tx.anomaly_score=+%{tx.critical_anomaly_score}
Original collection variable: tx.anomaly_score = "5"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: anomaly_score=5+5
Set variable "tx.anomaly_score" to "10".
As you can see from the bold lines, after this rule has processed, the transactional anomaly score increases from 5 to 10 points. This variable can then be checked at certain intervals in the transaction to determine if it has exceeded a threshold. The following rules inspect the anomaly scores at the end of the inbound request phase to determine if any disruptive actions should be initiated:
SecRule TX:ANOMALY_SCORE "@ge 10" "id:'999901',phase:2,drop,log,
msg:'Transaction Dropped due to high anomaly score.',
logdata:'%{tx.anomaly_score}'"
 
SecRule TX:ANOMALY_SCORE "@lt 10" "chain,id:'999902',phase:2,deny,
log,msg:'Transaction Denied due to anomaly score.',
logdata:'%{tx.anomaly_score}'"
   SecRule TX:ANOMALY_SCORE "@ge 5"
 
SecRule TX:ANOMALY_SCORE "@lt 5" "chain,id:'999903',phase:2,pass,
log,msg:'Transaction Logged due to anomaly score.',
logdata:'%{tx.anomaly_score}'"
   SecRule TX:ANOMALY_SCORE "@ge 1"
These rules apply different disruptive actions depending on the anomaly score value. If the value is less than 5, the transaction is simply logged. If the value is between 5 and 9 points, the transaction is denied. Finally, if the anomaly score value is 10 or more, the TCP connection is dropped. You should review the various disruptive response actions presented in Chapters 14 and 15 and apply those that suit your needs.
Although anomaly scoring is a valuable tactic, it is limited by the fact that it applies to only a single transaction. The next section describes options for tracking anomaly scores across multiple transactions to give you a wider view of malicious activities.
Per-IP Anomaly Scores
ModSecurity can be configured to create persistent storage for each client. The following example uses the initcol action to create this storage for each IP address and User-Agent combination:
# -- [[ Global and IP Collections ]] ----------------------------
#
# Create IP collections for rules to use
# There are some CRS rules that assume that these two collections
# have already been initiated.
#
SecRule REQUEST_HEADERS:User-Agent "^(.*)$" 
"id:'900014', 
phase:1, 
t:none,t:sha1,t:hexEncode, 
setvar:tx.ua_hash=%{matched_var}, 
nolog, 
pass"
 
SecRule &TX:REAL_IP "@eq 0" 
"id:'900017', 
phase:1, 
t:none, 
initcol:global=global, 
initcol:ip=%{remote_addr}_%{tx.ua_hash}, 
nolog, 
pass"
With the persistent storage now available, we can save and track anomaly scores across multiple requests. We just need to modify rules to add the following bold setvar action to add the same anomaly score value to the persistent storage:
#
# -=[ SQL Tautologies ]=-
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|
REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* 
"(?i:([s'"'´''()]*)([dw]++)([s'"'´''()]*)(?:(?:=|<=>|r?lik
e|soundss+like|regexp)([s'"'´''()]*)2|(?:!=|<=|>=|<>|<|>|^|is
s+not|nots+like|nots+regexp)([s'"'´''()]*)(?!2)([dw]+)))"
        "phase:2,rev:'2',ver:'OWASP_CRS/2.2.6',maturity:'9',
accuracy:'8',capture,multiMatch,t:none,t:urlDecodeUni,
t:replaceComments,ctl:auditLogParts=+E,block,
msg:'SQL Injection Attack',id:'950901',logdata:'Matched Data: 
%{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',
severity:'2',tag:'OWASP_CRS/WEB_ATTACK/SQL_INJECTION',
tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',
tag:'OWASP_AppSensor/CIE1',
tag:'PCI/6.5.2',setvar:'tx.msg=%{rule.msg}',
setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score},
setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},
setvar:ip.anomaly_score=+%{tx.critical_anomaly_score},
setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-
%{matched_var_name}=%{tx.0}"
If we now send in the same SQL Injection attack shown previously, we see that the anomaly score data is now also added to the persistent IP collection:
Setting variable: tx.anomaly_score=+%{tx.critical_anomaly_score}
Original collection variable: tx.anomaly_score = "7"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: anomaly_score=7+5
Set variable "tx.anomaly_score" to "12".
Setting variable: ip.anomaly_score=+%{tx.critical_anomaly_score}
Recorded original collection variable: ip.anomaly_score = "0"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: anomaly_score=0+5
Set variable "ip.anomaly_score" to "5".
At the end of the transaction, the anomaly score is saved within the persistent storage:
collection_store: Retrieving collection (name "ip", filename 
"/tmp/ip")
Re-retrieving collection prior to store: ip
collection_retrieve_ex: Retrieving collection (name "ip", filename 
"/tmp/ip")
Wrote variable: name "__expire_KEY", value "1345998247".
Wrote variable: name "KEY", value 
"192.168.1.104_1a6b014a54ce89a2b9534e7e08553b086b617748".
Wrote variable: name "TIMEOUT", value "3600".
Wrote variable: name "__key", value 
"192.168.1.104_1a6b014a54ce89a2b9534e7e08553b086b617748".
Wrote variable: name "__name", value "ip".
Wrote variable: name "CREATE_TIME", value "1345994647".
Wrote variable: name "UPDATE_COUNTER", value "1".
Wrote variable: name "anomaly_score", value "5".
Wrote variable: name "dos_counter", value "1".
Wrote variable: name "LAST_UPDATE_TIME", value "1345994647".
Persisted collection (name "ip", key 
"192.168.1.104_1a6b014a54ce89a2b9534e7e08553b086b617748").
With this new data available for tracking purposes, you can check for overall anomaly score values with rules such as this:
SecRule IP:ANOMALY_SCORE "@gt 50" "id:'999904',phase:2,
redirect:http://www.example.com/temp_lockout.php
,log,msg:'Transaction Logged due to anomaly score.',
logdata:'%{tx.anomaly_score}'"
This rule checks to see if the anomaly score is over 50 points and then redirects the user to an informational page describing why he or she is denied access.
Per-Session Anomaly Scores
Using the IP collection for tracking purposes is good, but several people might be using the same source IP address. To be more unique for each user, you could use the same approach but add anomaly score tracking to the application SessionID using setsid instead of initcol. You would first need to ensure that you have properly set up SessionID tracking, as outlined in Chapter 8. Then you can update your rule like this to increment an anomaly score in the session collection:
#
# -=[ SQL Tautologies ]=-
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|
REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* 
"(?i:([s'"'´''()]*)([dw]++)([s'"'´''()]*)(?:(?:=|<=>|r?lik
e|soundss+like|regexp)([s'"'´''()]*)2|(?:!=|<=|>=|<>|<|>|^|is
s+not|nots+like|nots+regexp)([s'"'´''()]*)(?!2)([dw]+)))"
        "phase:2,rev:'2',ver:'OWASP_CRS/2.2.6',maturity:'9',
accuracy:'8',capture,multiMatch,t:none,t:urlDecodeUni,
t:replaceComments,ctl:auditLogParts=+E,block,msg:'SQL Injection 
Attack',id:'950901',logdata:'Matched Data: %{TX.0} found within 
%{MATCHED_VAR_NAME}: %{MATCHED_VAR}',severity:'2',
tag:'OWASP_CRS/WEB_ATTACK/SQL_INJECTION',
tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',
tag:'OWASP_AppSensor/CIE1',
tag:'PCI/6.5.2',setvar:'tx.msg=%{rule.msg}',
setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score},
setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},
setvar:session.anomaly_score=+%{tx.critical_anomaly_score},
setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-
%{matched_var_name}=%{tx.0}"


Recipe 13-2: Trap and Trace Audit Logging
This recipe shows you how to dynamically adjust logging details for malicious clients as a result of security violations.
Ingredients
  • ModSecurity
    • IP:TRAP-N-TRACE variable
    • @streq operator
    • setvar action
    • expirevar action
    • ctl:auditEngine action
Trap and Trace Audit Logging
Recipes 1-6 and 1-7 discussed audit logging. Full audit logging is ideal, but many organizations opt to log only security-relevant transactions by configuring ModSecurity’s SecAuditEngine to RelevantOnly. This configuration reduces the amount of audit log data collected, but it is less than ideal from an incident response perspective. This recipe outlines a middle-ground logging configuration you can use to dynamically increase audit logging for suspicious clients.
Rather than setting a static global configuration for the amount of data we will audit-log for all clients, we can use conditional logging. For example, the RelevantOnly audit logging configuration is “alert-centric” and generates an audit log entry only if the client triggers one of our negative security rules. This is not ideal from a security perspective, because we do not have a full view of the client’s activities within the web application. What we can do instead is use a “trap and trace” configuration that uses the initial security alert as a trigger to place the client on a “watch list.” Doing so initiates full audit logging for this client, regardless of whether it triggers any more alerts.
As an example, let’s take a look at one of the geographic location rules taken from Recipe 4-1:
SecRule GEO:COUNTRY_CODE "@pm CN UA ID YU LT EG RO BG TR RU"
"id:'999018',phase:1,t:none,log,pass,msg:'High Risk Fraud Location',
setvar:tx.fraud_score=+10"
In this example, we have checked the client’s geographic location. If the client is coming from what we consider a high-risk location, we increase the fraud score for the current transaction. The client’s geographic location alone may not warrant denying access to the application, but this data could still be used as a key initiator for increasing the audit logging for this client. To accomplish this task, we can modify the action listing for the rule as follows:
SecRule GEO:COUNTRY_CODE "@pm CN UA ID YU LT EG RO BG TR RU"
"id:'999018',phase:1,t:none,log,pass,msg:'High Risk Fraud Location',
setvar:tx.fraud_score=+10,
setvar:ip.trap-n-trace=on,expirevar:ip.trap-n-trace=3600"
By adding these two new actions to the rule, we have set a new variable within the IP persistent storage for this client called trap-n-trace that will expire in one hour. We then can add the following rule that conditionally enables audit logging for the current transaction if this variable is set for the client.
SecRule IP:TRAP-N-TRACE "@streq on"
"id:'999900',phase:1,t:none,log,pass,msg:'Suspicious Client: 
Enabling Audit Logging',ctl:auditEngine=On"
This rule uses the ctl:auditEngine action to dynamically toggle the SecAuditEngine setting to On, which would generate a full audit log entry. This type of approach may be used with essentially any of the recipes in this book.


Recipe 13-3: Issuing E-mail Alerts
This recipe shows you how to send e-mails to security personnel as a result of security violations.
Ingredients
  • ModSecurity AuditConsole1
  • ModSecurity
    • REQUEST_HEADERS variable
    • REQUEST_BODY variable
    • @eq operator
    • exec action
    • setenv action
Sending E-mail Alerts Using the exec Action
ModSecurity’s exec action executes a local binary or script independent of any disruptive actions within the rule. One of the more helpful use cases for the exec action is to send an e-mail to security personnel when certain predefined criteria are met. For instance, consider a scenario in which an attacker attempts SQL Injection to bypass a login page, as shown in Figure 13-1.

Figure 13-1: Authentication bypass SQL Injection attack

c13f001.tif
If this particular injection attack is not formatted correctly and causes errors in the back-end SQL database, it may respond with error messages similar to those shown in Figure 13-2.

Figure 13-2: Microsoft SQL error messages in response

c13f002.tif
Even though this particular attack failed, it may be only a matter of time before it succeeds. In these situations it is wise to notify security personnel. The following correlation rule runs when a transaction is complete. It checks for any web attack rules that may have triggered against the inbound request content. It then checks for any information leakage rules that may have triggered on outbound content. If this is found, the rule exports the relevant security data into the Apache environment using the setenv action and then executes the alert_email.pl script.
# Correlated Successful Attack
#
SecRule &TX:'/LEAKAGE\/ERRORS/' "@ge 1" 
    "chain,phase:5,id:'981201',t:none,log,pass,
skipAfter:END_CORRELATION,severity:'0',msg:'Correlated Successful 
Attack Identified: (Total Score: %{tx.anomaly_score},
 SQLi=%{TX.SQL_INJECTION_SCORE}, XSS=%{TX.XSS_SCORE}) Inbound Attack
 (%{tx.inbound_tx_msg} – Inbound Anomaly Score: 
%{TX.INBOUND_ANOMALY_SCORE}) + Outbound Data Leakage 
(%{tx.msg} - Outbound Anomaly Score: %{TX.OUTBOUND_ANOMALY_SCORE})'"
        SecRule &TX:'/WEB_ATTACK/' "@ge 1" "t:none,chain"
                SecRule REQUEST_LINE|REQUEST_HEADERS|REQUEST_BODY|
TX:/^d/".*" "chain,setenv:%{matched_var_name}=%{matched_var}"
                     SecAction "setenv:msg=%{rule.msg},
exec:/usr/local/apache/conf/alert_email.pl"
The alert_email.pl script dumps all environment variables into an e-mail and sends them to the specified recipient. Here are the contents:
#!/usr/bin/perl
use String::ShellQuote qw(shell_quote);
 
my $DATE = '/bin/date';
chomp($DATE);
my $HOSTNAME = '/bin/hostname';
chomp($HOSTNAME);
my $TO = '[email protected]';
my $FROM = '"ModSecurity Alert" <www@'.$HOSTNAME.'>';
my $SUBJECT = "[ModSecurity Alert] Attack From: 
" .esc_subj($ENV{msg})." for "" .esc_subj($ENV{REQUEST_LINE}).""";
 
  open(MAIL, "|-", "/usr/sbin/sendmail", "-t", "-oi");
    print MAIL "To: $TO
";
    print MAIL "From: $FROM
";
    print MAIL "Subject: $SUBJECT
";
    print MAIL "
";
  print MAIL "______________________________________________________

";
  foreach $var (sort(keys(%ENV))) {
    $val = $ENV{$var};
    $val =~ s|
|\n|g;
    $val =~ s|"|\"|g;
    print MAIL "${var}="${val}"
";
}
 
  print MAIL "______________________________________________________
_
";
  close(MAIL);
  print "0";
 

sub esc_subj {
    my @bytes = split //, "@_";
    my $n = 0;
    my $str = "";
 
    for my $b (@bytes) {
        $b =~ s/(	)/\t/sg;
        $b =~ s/(x0d)/\r/sg;
        $b =~ s/(x0a)/\n/sg;
        $b =~ s/([^[:print:]])/sprintf("\x%02x", ord($1))/sge;
        $str .= $b;
        if (length($str) >= 50) {
            last;
        }
    }
 
    return $str;
}
If the SQL Injection attack shown in Figure 13-1 were encountered, security personnel would receive the following e-mail:
Date: Sun, 26 Aug 2012 16:11:27 -0500
To: <[email protected]>
From: ModSecurity Alert <[email protected]>
Subject: [ModSecurity Alert] Attack From: 72.192.214.223
"Correlated Successful Attack Identified"
 
________________________________________________________
CONTENT_LENGTH="73"
CONTENT_TYPE="application/x-www-form-urlencoded"
--CUT--
REMOTE_ADDR="72.192.214.223"
REMOTE_PORT="63125"
REQUEST_BODY="login=%27+or+%271%27%3E%275%27%23&password=fafasfds&
graphicOption=minimum"
REQUEST_HEADERS_Accept="text/html,application/xhtml+xml,application/
xml;q=0.9,*/*;q=0.8"
REQUEST_HEADERS_Accept_Encoding="gzip, deflate"
REQUEST_HEADERS_Accept_Language="en-us,en;q=0.5"
REQUEST_HEADERS_Connection="keep-alive"
REQUEST_HEADERS_Content_Length="73"
REQUEST_HEADERS_Content_Type="application/x-www-form-urlencoded"
REQUEST_HEADERS_Cookie="amSessionId=173728214042; 
ASPSESSIONIDCSRABQQD=LIHAMMOALHCOJIEFMGAIDOHG; sessionid="
REQUEST_HEADERS_DNT="1"
REQUEST_HEADERS_Host="www.modsecurity.org"
REQUEST_HEADERS_Referer="http://www.modsecurity.org/
zero.webappsecurity.com/banklogin.asp?serviceName=FreebankCaastAcces
s&templateName=prod_sel.forte&source=Freebank&AD_REFERRING_URL=
http://www.Freebank.com"
REQUEST_HEADERS_User_Agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 
10.6; rv:14.0) Gecko/20100101 Firefox/14.0.1"
REQUEST_LINE="POST /zero.webappsecurity.com/login1.asp HTTP/1.1"
REQUEST_METHOD="POST"
REQUEST_URI="/zero.webappsecurity.com/login1.asp"
--CUT--
TX_950901_WEB_ATTACK_SQL_INJECTION_ARGS_login="' or '1'>'5'#"
TX_959071_WEB_ATTACK_SQL_INJECTION_ARGS_login="' or '1'>'5'#"
TX_970901_AVAILABILITY_APP_NOT_AVAIL_RESPONSE_STATUS="500"
TX_971072_LEAKAGE_ERRORS_RESPONSE_BODY="Microsoft Access Driver"
TX_971116_LEAKAGE_ERRORS_RESPONSE_BODY="error '800"
TX_971197_LEAKAGE_ERRORS_RESPONSE_BODY="[Microsoft][ODBC"
msg="Correlated Successful Attack Identified: (Total Score: 
%{tx.anomaly_score}, SQLi=%{TX.SQL_INJECTION_SCORE}, 
XSS=%{TX.XSS_SCORE}) Inbound Attack (%{tx.inbound_tx_msg} – 
Inbound Anomaly Score: %{TX.INBOUND_ANOMALY_SCORE}) + Outbound
 Data Leakage (%{tx.msg} - Outbound Anomaly Score: 
%{TX.OUTBOUND_ANOMALY_SCORE})"
_________________________________________________________
The data in this e-mail provides all the critical information you need to get an idea of what has transpired. By reviewing the e-mail, a security analyst can quickly see what inbound alerts were triggered (SQL Injection) and what resulting outbound events were triggered (information leakage). At this point, it would be wise to look closely at this client’s activities and potentially activate more intrusive response or logging actions.
Sending E-mail Alerts Using the AuditConsole
As we discussed in Recipe 1-11, you can use the open source AuditConsole application to help manage web application security events and audit logs. One of AuditConsole’s useful features is that it allows the security analyst to specify rules or conditions under which other actions should be taken. These actions include the ability to send e-mail notifications. This is similar in theory to the previous example using ModSecurity’s exec action, but in this implementation the logic is moved to AuditConsole.
To start, you must configure the Mail Settings, as shown in Figure 13-3.

Figure 13-3: AuditConsole’s e-mail settings

c13f003.tif
After you have specified your e-mail configurations, you can go to the Rules page and click the New Rule button. You see the pop-up configuration window shown in Figure 13-4.

Figure 13-4: AuditConsole’s Create Rule interface

c13f004.tif
For our purposes, you want to add a condition that triggers when an event is received that has an EMERGENCY Severity level. To do this, you click the + Condition button and add the appropriate conditions, as shown in Figure 13-5.

Figure 13-5: AuditConsole’s Rule Condition interface

c13f005.tif
The next step is to click the + Action button so that you can define what to do if the conditions are met. In Figure 13-6, the specified action is to send an e-mail to my e-mail address.

Figure 13-6: AuditConsole’s Rule Action interface

c13f006.tif
After you click the OK button, you see a screen similar to Figure 13-7, which shows the completed new rule.

Figure 13-7: AuditConsole’s completed rule definition

c13f007.tif
Again, you must click OK, and then your new rule is active. With this rule in place, if a transaction is identified that results in an EMERGENCY Severity level, an e-mail similar to the following is received:
AuditConsole Event-Notification
===============================
The following 1 events have triggered this notification:
____________________________________________________
TX_ID : HrgqxsCo8AoAAC4mJ8cAAAAI
Received at: 2012-08-27 09:20:51.355 UTC
From Sensor: Test
Method : POST
URI : /zero.webappsecurity.com/login1.asp
Client : IP 72.192.214.223 Port 59562
Server-Response: 500
____________________________________________________
 
The following messages have been fired by the rules:
 
Message: Warning. Pattern match "(^["''xc2xb4xe2x80x99xe2x80
x98;]+|["''xc2xb4xe2x80x99xe2x80x98;]+$)" at ARGS:login.
 [rev "2.2.2"] | Rule-ID: 981211 Rule-Severity: 2 | Rule-Message: 
SQL Injection Attack: Common Injection Testing Detected | |
 
Message: Warning. Pattern match "(?i:\bor\b ?(?:\d{1,10}|['"]
[^=]{1,10}['"]) ?[=<>]+|(?i:'\s+x?or\s+.{1,20}[+\-!<>=])|\b(
?i:x?or)\b\s+(\d{1,10}|'[^=]{1,10}')|\b(?i:x?or)\b\s+(\d{1,1
0}|'[^=]{1,10}')\s*[=<>])" at ARGS:login. [rev "2.2.2"] | Rule-ID: 
959071 Rule-Severity: 2 | Rule-Message: SQL Injection Attack | |
 
Message: Warning. Pattern match "([\~\!\@\#\$\%\^\&\*\(\)
\-\+\=\{\}\[\]\|\:\;"'\xc2xb4\xe2x80x99\xe2x8
0x98'\<\>].*){6,}" at ARGS:login. [rev "2.2.1"] | Rule-ID: 9811
73 Rule-Severity: 15 | Rule-Message: Restricted SQL Character Anomal
y Detection Alert - Total # of special characters exceeded | |
 
Message: Warning. Pattern match "(?i:(?:\d("|'|'|xc2xb4|xe2x80
x99|xe2x80x98)\s+("|'|'|xc2xb4|xe2x80x99|xe2x80x98)\s
+\d)|(?:^admin\s*("|'|'|xc2xb4|xe2x80x99|xe2x80x98)|(\/
*)+("|'|'|xc2xb4|xe2x80x99|xe2x80x98)+\s?(?:--|#|\/\*|{
)?)|(?:("|'| ..." at ARGS:login. | Rule-ID: 981244 Rule-Severity: 2
 | Rule-Message: Detects basic SQL authentication bypass attempts 1/
3 | |Message: Warning. Pattern match "(?i:(?:\)\s*when\s*\d+\s*
then)|(?:("|'|'|xc2xb4|xe2x80x99|xe2x80x98)\s*(?:#|--|{))|
(?:\/\*!\s?\d+)|(?:ch(?:a)?r\s*\(\s*\d)|(?:(?:(n?and|x?x?or|
div|like|between|and|not)\s+|\|\||\&\&)\s*\w+\())" at
 ARGS:login. | Rule-ID: 981240 Rule-Severity: 2 | Rule-Message: 
Detects MySQL comments, conditions and ch(a)r injections
 
--CUT--
 
Message: Warning. Operator GE matched 1 at TX. Rule-Severity: 0 |
 Rule-Message: Correlated Successful Attack Identified: Inbound 
Attack (981243-Detects classic SQL injection probings 2/2) + 
Outbound Data Leakage (IIS Information Leakage) - (Transactional 
Anomaly Score: 59)
____________________________________________________


Recipe 13-4: Data Sharing with Request Header Tagging
This recipe shows you how to share security event information with other security systems by adding request header data.
Ingredients
  • OWASP ModSecurity Core Rule Set (CRS)
    • modsecurity_crs_49_header_tagging.conf
  • Apache
    • mod_headers header
  • ModSecurity
    • TX:ANOMALY_SCORE variable
    • REQUEST_BODY variable
    • @eq operator
    • setvar action
    • setenv action
A common security architecture is to deploy a web application firewall within a demilitarized zone (DMZ) network segment to act as a reverse proxy for protected web applications. With this setup, the WAF can inspect requests and decide whether to allow the transaction to continue and proxy it onto the downstream web application it is protecting. This setup works well for obvious attack traffic, but there may be some situations in which the WAF identifies some lower-level security issues. However, they are not at a level that would cause the traffic to be blocked. In these situations, intelligence is lost when the WAF sends the request to the destination web application. Wouldn’t it be great if your WAF could share its data with the application it is protecting? This concept is called request header tagging.
This concept is similar in theory to antispam SMTP applications that add additional MIME headers to e-mails, providing the spam detection analysis information. If your e-mail server uses this type of spam filtering, you may be able to view the source of your e-mail message and see headers such as this:
X-Spam-Flag: YES
X-Spam-Level: ******************
X-Spam-ASN: AS24560 122.161.32.0/20
X-Spam-Status: Yes, score=18.4 required=4.0 tests=BAYES_99,
EMPTY_MESSAGE,FH_FROMEML_NOTLD,FORGED_OUTLOOK_TAGS,FROM_NO_USER,
FSL_HELO_NON_FQDN_1,HELO_NO_DOMAIN,RCVD_IN_BRBL_LASTEXT,
RCVD_IN_PBL,RCVD_IN_RP_RNBL,RCVD_IN_SORBS_DUL,RCVD_IN_XBL,RDNS_NONE
 shortcircuit=no autolearn=no
        version=3.3.1
X-Spam-Relay-Country: IN
X-Spam-Report:
        *  3.5 BAYES_99 BODY: Bayes spam probability is 99 to 100%
        *      [score: 1.0000]
        *  1.5 FSL_HELO_NON_FQDN_1 FSL_HELO_NON_FQDN_1
        *  1.1 FH_FROMEML_NOTLD E-mail address doesn't have TLD 
        *      (.com, etc.)
        *  0.8 FROM_NO_USER From: has no local-part before @ sign
        *  1.4 RCVD_IN_BRBL_LASTEXT RBL: RCVD_IN_BRBL_LASTEXT
        *      [122.161.46.234 listed in bb.barracudacentral.org]
        *  1.3 RCVD_IN_RP_RNBL RBL: Relay in RNBL,
        *      https://senderscore.org/blacklistlookup/
        *      [122.161.46.234 listed in bl.score.senderscore.com]
        *  3.3 RCVD_IN_PBL RBL: Received via a relay in Spamhaus PBL
        *      [122.161.46.234 listed in zen.spamhaus.org]
        *  0.4 RCVD_IN_XBL RBL: Received via a relay in Spamhaus XBL
        *  0.0 RCVD_IN_SORBS_DUL RBL: SORBS: sent directly from 
        *      dynamic IP address [122.161.46.234 listed in 
        *      dnsbl.sorbs.net]
        *  0.1 FORGED_OUTLOOK_TAGS Outlook can't send HTML in this 
        *      format
        *  2.3 EMPTY_MESSAGE Message appears to have no textual 
        *      parts and no Subject: text
        *  1.2 RDNS_NONE Delivered to internal network by a host 
        *      with no rDNS
        *  1.5 HELO_NO_DOMAIN Relay reports its domain incorrectly
This data exposes the various spam validation results to the user by inserting them into the MIME header of the e-mail message. We can mimic this concept at the HTTP layer by adding additional request headers that provide insight into any security events that may have triggered during processing. The advantage of this approach is that it allows a WAF to be in detection-only mode while still providing attack data to the destination application server. The receiving application server may then inspect the WAF request headers or pass on the information to other web fraud detection inspection and then make a final determination whether to process the transaction. This concept is valuable in distributed web environments and hosting architectures where a determination to block may be appropriate only at the destination application server.
The OWASP ModSecurity Core Rule Set includes a file called modsecurity_crs_49_header_tagging.conf with the following rules:
SecRule TX:ANOMALY_SCORE "@eq 0" "phase:2,id:'981173',t:none,nolog,
pass,skipAfter:END_HEADER_TAGGING"
 
SecRule TX:/^d/ "." "phase:2,id:'981174',t:none,nolog,pass,
setvar:tx.counter=+1,
setenv:matched_rule-%{tx.counter}=%{matched_var_name},
setenv:anomaly_score=%{tx.anomaly_score},
setenv:sql_injection_score=%{tx.sql_injection_score},
setenv:xss_score=%{tx.xss_score}"
 
RequestHeader append X-WAF-Events "%{matched_rule-1}e"
 env=matched_rule-1
RequestHeader append X-WAF-Events "%{matched_rule-2}e"
 env=matched_rule-2
RequestHeader append X-WAF-Events "%{matched_rule-3}e"
 env=matched_rule-3
RequestHeader append X-WAF-Events "%{matched_rule-4}e"
 env=matched_rule-4
RequestHeader append X-WAF-Events "%{matched_rule-5}e"
 env=matched_rule-5
RequestHeader append X-WAF-Events "%{matched_rule-6}e"
 env=matched_rule-6
RequestHeader append X-WAF-Events "%{matched_rule-7}e"
 env=matched_rule-7
RequestHeader append X-WAF-Events "%{matched_rule-8}e"
 env=matched_rule-8
RequestHeader append X-WAF-Events "%{matched_rule-9}e"
 env=matched_rule-9
RequestHeader append X-WAF-Events "%{matched_rule-10}e"
 env=matched_rule-10
RequestHeader append X-WAF-Events "%{matched_rule-11}e"
 env=matched_rule-11
RequestHeader append X-WAF-Events "%{matched_rule-12}e"
 env=matched_rule-12
RequestHeader append X-WAF-Events "%{matched_rule-13}e"
 env=matched_rule-13
RequestHeader append X-WAF-Events "%{matched_rule-14}e"
 env=matched_rule-14
RequestHeader append X-WAF-Events "%{matched_rule-15}e"
 env=matched_rule-15
RequestHeader append X-WAF-Events "%{matched_rule-16}e"
 env=matched_rule-16
RequestHeader append X-WAF-Events "%{matched_rule-17}e"
 env=matched_rule-17
RequestHeader append X-WAF-Events "%{matched_rule-18}e"
 env=matched_rule-18
RequestHeader append X-WAF-Events "%{matched_rule-19}e"
 env=matched_rule-19
RequestHeader append X-WAF-Events "%{matched_rule-20}e"
 env=matched_rule-20
RequestHeader set X-WAF-Score "Total=%{anomaly_score}e; 
 sqli=%{sql_injection_score}e; xss=%{xss_score}e" env=anomaly_score
These rules check the transactional anomaly score level and then export all the relevant matched rule data to the Apache environment, where it can be used by the mod_headers module. The result of these rules is that two new request headers are added to the request as it is sent to the destination application server:
  • X-WAF-Events is a comma-separated listing of all rule match metadata.
  • X-WAF-Score lists the overall anomaly score and the subscores for SQL Injection and cross-site scripting.
Let’s look at a SQL Injection attack and see how it looks after the rules update the request and add the new header data:
POST /zero.webappsecurity.com/login1.asp HTTP/1.1
Host: www.modsecurity.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:14.0)
Gecko/20100101 Firefox/14.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;
q=0.8
Accept-Language: en-us,en;q=0.5
DNT: 1
Referer: http://www.modsecurity.org/zero.webappsecurity.com/
banklogin.asp?serviceName=FreebankCaastAccess&templateName=
prod_sel.forte&source=Freebank&AD_REFERRING_URL=
http://www.Freebank.com
Cookie: amSessionId=173728214042; ASPSESSIONIDCSRABQQD=
LIHAMMOALHCOJIEFMGAIDOHG; sessionid=
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
X-WAF-Events: TX:981318-WEB_ATTACK/SQL_INJECTION-ARGS:login,
TX:950901-WEB_ATTACK/SQL_INJECTION-ARGS:login,
TX:959071-WEB_ATTACK/SQL_INJECTION-ARGS:login,
TX:981173-WEB_ATTACK/RESTRICTED_SQLI_CHARS-ARGS:login,
TX:981244-Detects basic SQL authentication bypass attempts
1/3-WEB_ATTACK/SQLI-ARGS:login,
TX:981240-Detects MySQL comments, conditions and ch(a)r
injections-WEB_ATTACK/SQLI-ARGS:login,
TX:981242-Detects classic SQL injection probings
1/2-WEB_ATTACK/SQLI-ARGS:login,
TX:981243-Detects classic SQL injection probings
2/2-WEB_ATTACK/SQLI-ARGS:login
X-WAF-Score: Total=38; sqli=20; xss=
Connection: Keep-Alive
Content-Length: 72
 
login=%27+or+%271%27%3E%275%27%23&password=fddf433&
graphicOption=minimum
As you can see, this request had an anomaly score of 38 and a SQL Injection attack score of 20. The X-WAF-Events header lists a number of the rules that triggered. When this intelligence is shared with downstream systems, they may be able to make a more accurate decision about how to handle the transaction.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.29.219