Contents
Introduction to WAF
WAF logs (Web Application Firewall logs) are crucial for maintaining online security. By gaining insights from these logs, organizations can strengthen their cyber defenses and protect against potential threats.
WAF Logs provide detailed information on incoming web requests, allowing users to track and analyze traffic patterns. This data can be instrumental in identifying malicious activities and unauthorized access attempts.
The WAF security submodule inside the IPDS module (Intrusion prevention and detection system) is preloaded by default with the Rules of the OWASP project, to be more specific with the rules of the CRS v4 (OWASP project CRS v4 Rules), those rules are preloaded in the IPDS system and can be used by default protecting against a big number of known Web attacks any API service or WEB application, from SKUDONET we encourage you to use those rulesets particularly for any accessible services on the Internet.
The current article is trying to describe the complete information that the Web Application Firewall submodule saves in logs if some rule is triggered, in that way, the sysadmin will be able to understand the attack and be protected and acquire information in case some troubleshooting is required.
Benefits and Drawbacks of WAF Logs
- Benefits:
- Enhanced security measures
- Real-time threat detection
- Customizable logging options
- Drawbacks:
- Potential log delivery delays
- Complex log analysis process
- Resource-intensive log storage
Log Configuration and Fields
When it comes to analyzing WAF logs data, understanding the log configuration and fields is crucial. Each log entry includes specific details such as IP addresses, request details, and applied rules. By properly configuring the logs, you can ensure comprehensive data collection for effective analysis.
Log Analysis Tools
Utilizing the right log analysis tools is essential for deriving insights from WAF logs data. Tools like Splunk and ELK Stack Insights offer advanced capabilities for processing and visualizing log information. These tools allow for in-depth analysis, anomaly detection, and real-time monitoring for enhanced security.
A real WAF logs example
When it comes to leveraging WAF Logs with SKUDONET ADC, understanding the capabilities and benefits of this integration is crucial. Let’s delve into the details.
The SKUDONET ADC Appliance has been configured to load balance a simple HTTPS load balanced service against 2 backends:
- The farm name configured has been called WAF
- and the IPDS module
Both has been configured using the following rulesets:
Take into consideration that all the rules have been applied to the farm, but please use only the rules based on what protection you want to be covered, understanding always what you are doing, in other case please open a support request and contact SKUDONET Engineers for further help in the WAF configuration.
If you want to know more about what kind of protection offers each ruleset, please refer to this article about WAF rules.
The Farm has been configured with the following data:
Taking all this configuration into consideration any request reaching the VIP 172.16.100.100 with protocol HTTPS in port 443 will be secured with the bunch of security rules shown in the previous screenshot.
Now the IP 172.16.2.21 is going to run the following request:
curl https://172.16.100.100/index.php?hi=/../../bye -H "Host: www.skudonet.com" -v -k
* Trying 172.16.100.100:443...
* Connected to 172.16.100.100 (172.16.100.100) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
* subject: C=ES; ST=Spain; L=Spain; O=Zevenet SL; OU=Telecommunications; CN=*; emailAddress=info@zevenet.com
* start date: Nov 15 15:35:51 2017 GMT
* expire date: Nov 13 15:35:51 2027 GMT
* issuer: C=ES; ST=Spain; L=Spain; O=Zevenet SL; OU=Telecommunications; CN=*; emailAddress=info@zevenet.com
* SSL certificate verify result: self-signed certificate (18), continuing anyway.
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET /index.php?hi=/../../bye HTTP/1.1
> Host: www.skudonet.com
> User-Agent: curl/7.84.0
> Accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 403 Request forbidden
< Content-Type: text/html
< Content-Length: 17
< Expires: now
< Pragma: no-cache
< Cache-control: no-cache,no-store
<
* Closing connection 0
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS alert, close notify (256):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS alert, close notify (256):
replied forbidden
This request has been rejected by the WAF submodule sending the following information to the WAF logs /var/log/syslog:
Apr 8 10:21:26 skdwaf pound: waf, [WAF,service be, backend 172.16.100.253:80,] (7f0fae969700) [client 192.168.2.21] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Rx' with parameter `(?i)(?:[/\x5c]|%(?:2(?:f|5(?:2f|5c|c(?:1%259c|0%25af))|%46)|5c|c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|(?:bg%q|(?:e|f(?:8%8)?0%8)0%80%a)f|u(?:221[56]|EFC8|F025|002f)|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|1 (394 characters omitted)' against variable `ARGS:hi' (Value: `/../../bye' ) [file "/usr/local/zevenet/config/ipds/waf/sets/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "17"] [id "930100"] [rev ""] [msg "Path Traversal Attack (/../) or (/.../)"] [data "client:192.168.2.21"] [severity "2"] [ver "OWASP_CRS/4.2.0-dev"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-lfi"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/255/153/126"] [hostname "172.16.100.100"] [uri "/index.php"] [unique_id "171256448613.288302"] [ref "o14,4v4,24o0,4v18,10"]
Apr 8 10:21:26 skdwaf pound: waf, service be, backend 172.16.100.253:80, (7f0fae969700) WAF denied a request from 192.168.2.21
But what does the Web Application Firewall submodule show here?
Let’s explain field by field the useful and rich information we have here:
Apr 8 10:21:26
Day and date of the triggered action
skdwaf
Hostname where the triggered action has been executed
pound
Binary used by SKUDONET ADC Appliance for HTTP(S) profile implementation. You can read more about our proxy in our public GITHUB repository.
waf
Farm name where the rule has been triggered.
[WAF,service be, backend 172.16.100.253:80,]
Group of information related to the WAF submodule inside the IPDS system. in order of appearance:
WAF
IPDS submodule where the rule has been triggered.
service be
Service name that should manage the HTTP request executed by the client.
backend 172.16.100.253:80
A backend that should manage the request in case the triggered rule doesn’t stop the request.
(7f0fae969700)
Space of memory, used for development purposes.
[client 192.168.2.21]
Source IP that triggered the WAF rule.
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Rx' with parameter `(?i)(?:[/\x5c]|%(?:2(?:f|5(?:2f|5c|c(?:1%259c|0%25af))|%46)|5c|c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|(?:bg%q|(?:e|f(?:8%8)?0%8)0%80%a)f|u(?:221[56]|EFC8|F025|002f)|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|1 (394 characters omitted)' against variable `ARGS:hi' (Value: `/../../bye' )
The reason why the particular rule has been triggered by the ModSecurity library used by WAF; the possible attacker introduced not allowed string “/../../bye” in the ARGS variable.
[file "/usr/local/zevenet/config/ipds/waf/sets/REQUEST-930-APPLICATION-ATTACK-LFI.conf"]
File where the triggered rule is configured.
[line "17"]
The line number where the triggered rule is present inside the previous file.
[id "930100"]
Unique ID of the rule, each rule is identified by a unique id and a load balancing farm can’t be configured using rules with repeated id.
[rev ""]
An empty field can be filled inside the particular rule, this rule doesn’t include any content for the revision field. If the rule suffers different modifications by the OWASP project this value will change.
[msg "Path Traversal Attack (/../) or (/.../)"]
Information related to the description of the possible attack is protected.
[data "client:192.168.2.21"]
Source IP that sent the request and triggered the rule.
[severity "2"]
The severity of the rule is a kind of punctuation, OWASP assigns a severity for each rule, those values are added in each triggered rule, and finally, the total severity result is evaluated. If the final severity reaches a limit then the request is blocked.
[ver "OWASP_CRS/4.2.0-dev"]
OWASP information, here is saved the rule version. In case the version is changed by the OWASP project this value will be increased.
[maturity "0"]
Descriptive field, used by OWASP. value not in use in this OWASP Ruleset.
[accuracy "0"]
Descriptive field, used by OWASP. value not in use in this OWASP Ruleset.
[tag "application-multi"]
Descriptive information, the rule is typified using this field, this information can be used in future searches to group by kind of attacks.
[tag "language-multi"]
Descriptive information, the rule is typified using this field, this information can be used in future searches to group by kind of attacks.
[tag "platform-multi"]
Descriptive information, the rule is typified using this field, this information can be used in future searches to group by kind of attacks.
[tag "attack-lfi"]
Descriptive information, the rule is typified using this field, this information can be used in future searches to group by kind of attacks.
[tag "paranoia-level/1"]
The paranoia level assigned to this rule, the OWASP rulesets can be configured with different levels of paranoia, if you want to read more about this particular field, please refer to this article.
[tag "OWASP_CRS"]
Source where the rule has been obtained from.
[tag "capec/1000/255/153/126"]
typified attack by CAPEC (Common Attack Pattern Enumeration and Classification).
[hostname "172.16.100.100"]
Destination IP where the connection has been done, this field will match with the Virtual IP for the farm.
[uri "/index.php"]
URI requested by the client.
[unique_id "171256448613.288302"]
Unique ID for the HTTP request/response transaction. If a client triggers more than one rule, all the triggered rules will be identified with the same unique_id.
[ref "o14,4v4,24o0,4v18,10"]
Internal information for modsecurity.
Let see the rule triggered by the client and analyzed in the logs, for that we have to refer to the indicated file in logs /usr/local/zevenet/config/ipds/waf/sets/REQUEST-930-APPLICATION-ATTACK-LFI.conf, line 17:
SecRule REQUEST_URI_RAW|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|FILES|XML:/* "@rx (?i)(?:[/\x5c]|%(?:2(?:f|5(?:2f|5c|c(?:1%259c|0%25af))|%46)|5c|c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|(?:bg%q|(?:e|f(?:8%8)?0%8)0%80%a)f|u(?:221[56]|EFC8|F025|002f)|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|1u)|0x(?:2f|5c))(?:\.(?:%0[01]|\?)?|\?\.?|%(?:2(?:(?:5(?:2|c0%25a))?e|%45)|c0(?:\.|%[256aef]e)|u(?:(?:ff0|002)e|2024)|%32(?:%(?:%6|4)5|E)|(?:e|f(?:(?:8|c%80)%8)?0%8)0%80%ae)|0x2e){2,3}(?:[/\x5c]|%(?:2(?:f|5(?:2f|5c|c(?:1%259c|0%25af))|%46)|5c|c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|(?:bg%q|(?:e|f(?:8%8)?0%8)0%80%a)f|u(?:221[56]|EFC8|F025|002f)|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|1u)|0x(?:2f|5c))" \ "id:930100,\ phase:2,\ block,\ capture,\ t:none,\ msg:'Path Traversal Attack (/../) or (/.../)',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-lfi',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/255/153/126',\ ver:'OWASP_CRS/4.2.0-dev',\ severity:'CRITICAL',\ setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}'"
Additionally, to the information obtained from WAF logs, we can see that this rule is executed in phase 2 when all the request headers are received and the default action is blocking, if the rule is triggered the action is to block the request.