CVE-2024-3400: PAN-OS Command Injection Vulnerability in GlobalProtect Gateway. Learn More

CVE-2024-3400: PAN-OS Command Injection Vulnerability in GlobalProtect Gateway. Learn More

Services
Capture
Managed Detection & Response

Eliminate active threats with 24/7 threat detection, investigation, and response.

twi-managed-portal-color
Co-Managed SOC (SIEM)

Maximize your SIEM investment, stop alert fatigue, and enhance your team with hybrid security operations support.

twi-briefcase-color-svg
Advisory & Diagnostics

Advance your cybersecurity program and get expert guidance where you need it most.

tw-laptop-data
Penetration Testing

Test your physical locations and IT infrastructure to shore up weaknesses before exploitation.

twi-database-color-svg
Database Security

Prevent unauthorized access and exceed compliance requirements.

twi-email-color-svg
Email Security

Stop email threats others miss and secure your organization against the #1 ransomware attack vector.

tw-officer
Digital Forensics & Incident Response

Prepare for the inevitable with 24/7 global breach response in-region and available on-site.

tw-network
Firewall & Technology Management

Mitigate risk of a cyberattack with 24/7 incident and health monitoring and the latest threat intelligence.

Solutions
BY TOPIC
Microsoft Exchange Server Attacks
Stay protected against emerging threats
Rapidly Secure New Environments
Security for rapid response situations
Securing the Cloud
Safely navigate and stay protected
Securing the IoT Landscape
Test, monitor and secure network objects
Why Trustwave
About Us
Awards and Accolades
Trustwave SpiderLabs Team
Trustwave Fusion Security Operations Platform
Trustwave Security Colony
Partners
Technology Alliance Partners
Key alliances who align and support our ecosystem of security offerings
Trustwave PartnerOne Program
Join forces with Trustwave to protect against the most advance cybersecurity threats
SpiderLabs Blog

ModSecurity Advanced Topic of the Week: HMAC Token Protection

8062_15cd28ae-5657-4741-8f2d-28aacffa1b48This blog post presents a powerful feature of ModSecurity v2.7 that has been highly under-utilized by most users: HMAC Token Protection. There was a previous blog post written that outlined some usage examples here, however we did not properly demonstrate the protection coverage gained by its usage. Specifically, by using the HMAC Token Protection capabilities of ModSecurity, you can reduce the attack surface of the following attacks/vulnerabilities:

  • Forceful Browsing of Website Content
  • Automated Botnet Attacks
  • Manipulation of Query String Parameters
  • Reflected Cross-Site Scripting
  • Cross-Site Request Forgery (CSRF) Protection
Excerpts of this blog post will discuss Recipe 1-2: Preventing Data Manipulation with Cryptographic Hash Tokens from my book "Web Application Defender's Cookbook: Battling Hackers and Protecting Users".

Recipe 1-2: Preventing Data Manipulation With Cryptographic Hash Tokens

This recipe will show you how to use ModSecurity to implement additional hash tokens to outbound html data in order to prevent data manipulation attacks. At the time of writing this book, the capabilities outlined in this recipe are available in ModSecurity version 2.7. Future versions may have different or extended functionality.

Ingredients

Background

Web developers cannot rely upon web browser security mechanisms to prevent data manipulation. With this being the case, how can we implement an external method of verifying that outbound data has not been manipulated when returned in a follow-up request? One technique that can be used is to parse the outbound html response body data, calculate digest hashes for content and then inject additional token data into select locations. The data that we are injecting are called request parameter validation tokens and are essentially cryptographic hashes of select html page elements. The hashes enable us to detect if the client attempts to tamper with the data.

Example Configuration

Here are some example ModSecurity directives and rules that implements basic hashing protections:

SecDisableBackendCompression On
SecContentInjection On
SecStreamOutBodyInspection On
SecHashEngine On
SecHashKey rand
SecHashParam "hmac"
SecHashMethodrx "HashHref" "\.(aspx?|php)"
SecHashMethodrx "HashFormAction" "\.(aspx?|php)"
SecRule REQUEST_URI "@validateHash \.(aspx?|php)" "phase:2,id:1000,t:none,block,msg:'Hash Validation Violation.',ctl:hashEnforcement=On,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:'tx.msg=%{rule.msg}',setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}"

The first directive called SecDiableBackendCompression is only needed in a reverse proxy setup and is used if the web application is compressing response data in the gzip format. This is needed so that we can parse the response html data and modify it. ModSecurity's default configuration is to only make copies of transactional data in memory and inspect them while buffering the real connection. The next two directives are used together, however, to be able to modify and fully replace the original buffered response body with the new one. The next four SecHash directives configure the basic settings. In this configuration, ModSecurity will use a random encryption key as the hash salt value and will also use the REMOTE_ADDR of the client as an additional item in the hash calculation. It will then hash HTML HREF and Form Action components that match the defined regular expression. In this example, we are only applying these protections to web pages with .php, .asp and .aspx file extensions. The final SecRule is used for validation and enforcement of the hash tokens.

A Practical Example Walk-Through

For our example web application, we will be using the public demo web application Acuart. When a client requests the main webpage through ModSecurity with the Hash token protections, this is what the debug log shows when processing the returned HTML data to the client:

Starting phase RESPONSE_HEADERS.
This phase consists of 8 rule(s).
Content Injection: Nothing to inject.
Output filter: Bucket type TRANSIENT contains 1251 bytes.
Output filter: Receiving output (f 10a803d38, r 10a8020a0).
Output filter: Bucket type TRANSIENT contains 2845 bytes.
Output filter: Receiving output (f 10a803d38, r 10a8020a0).
Output filter: Bucket type EOS contains 0 bytes.
Output filter: Completed receiving response body (buffered full - 4096 bytes).
init_response_body_html_parser: assuming ISO-8859-1.
init_response_body_html_parser: Successfully html parser generated.
Signing data [privacy.php]
Signing data [AJAX/index.php]
Signing data [guestbook.php]
Signing data [userinfo.php]
Signing data [login.php]
Signing data [cart.php]
Signing data [artists.php]
Signing data [categories.php]
Signing data [AJAX/index.php]
Signing data [guestbook.php]
Signing data [cart.php]
Signing data [disclaimer.php]
Signing data [artists.php]
Signing data [categories.php]
Signing data [index.php]
Signing data [search.php?test=query]
hash_response_body_links: Processed [0] iframe src, [0] hashed.
hash_response_body_links: Processed [0] frame src, [0] hashed.
hash_response_body_links: Processed [1] form actions, [1] hashed.
hash_response_body_links: Processed [23] links, [15] hashed.
inject_hashed_response_body: Detected encoding type [ISO-8859-1].
inject_hashed_response_body: Using content-type [ISO-8859-1].
inject_hashed_response_body: Copying XML tree from CONV to stream buffer [4733] bytes.
inject_hashed_response_body: Setting new content value 4733
inject_hashed_response_body: Stream buffer [4733]. Done
Hash completed in 3215 usec.

As you can see from this logging output, ModSecurity dynamically inserted hmac hashes for 15 HREF links and 1 Form action in the web page. Here is how this appears to the user when they mouse over links in the web page:

10731_96e2df86-f7aa-4d0e-9275-7df231ef0c7f

Notice the link now has a new "hmac" parameter value appended to the end. When the client makes subsequent requests, ModSecurity will ensure the following:

  1. HMAC Token Exists - the request includes an hmac parameter token value. If the hmac token is missing, an attacker be attempting to bypass the protections by stripping out the token altogether.
  2. HMAC Token Mismatch - That the hmac value submitted in the requests matches the re-calculated server-side value within ModSecurity when it analyzes the live HTTP request data.

If either of these scenarios happen, then ModSecurity will generate alerts. Let's look at the real-world attack scenarios listed at the beginning of the blog post to see how this works.

Forceful Browsing Attacks

11123_a9e71a17-bf07-4707-b02f-1972bfe65cdb

In the Acuart demo website, there is a Forceful Browsing attack/vulnerability with the "showimage.php" resource. Under normal circumstances, this is how the resources is accessed:

8770_39243a9c-97e8-4c39-8d39-add7ad6e55b8

The resource has one parameter called "file" and it is supposed to be used to access image files. The attacker, however, is able to change the data in the "file" parameter to access other files such as the Database Connection config file:

10113_7af7badc-4e12-46c5-8d08-4b6ddce763ac

If an attacker attempts to send that specific request, ModSecurity will generate the following event:

Rule 10094a408: SecRule "REQUEST_URI" "@validateHash \\.(aspx?|php)" "phase:2,log,tag:%{request_headers.host},id:1000,t:none,block,msg:'Hash Validation Violation.',ctl:hashEnforcement=On,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.msg=%{rule.msg},setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}"
Transformation completed in 1 usec.
Executing operator "validateHash" with param "\\.(aspx?|php)" against REQUEST_URI.
Target value: "/showimage.php?file=./database_connect.php"
Request URI without hash parameter [/showimage.php?file=./database_connect.php]
Operator completed in 83 usec.
Ctl: Set HashEnforcement to On.
Setting variable: tx.anomaly_score=+%{tx.critical_anomaly_score}
Recorded original collection variable: tx.anomaly_score = "0"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: anomaly_score=0+5
Set variable "tx.anomaly_score" to "5".
Setting variable: tx.msg=%{rule.msg}
Resolved macro %{rule.msg} to: Hash Validation Violation.
Set variable "tx.msg" to "Hash Validation Violation.".
Setting variable: tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}
Resolved macro %{rule.id} to: 1000
Resolved macro %{matched_var_name} to: REQUEST_URI
Resolved macro %{matched_var} to: /showimage.php?file=./database_connect.php
Set variable "tx.1000-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-REQUEST_URI" to "/showimage.php?file=./database_connect.php".
Resolved macro %{request_headers.host} to: testphp.vulnweb.com
Warning. Request URI matched "\\.(aspx?|php)" at REQUEST_URI. No Hash parameter [file "/usr/local/apache/conf/crs/base_rules/REQUEST-00.conf"] [line "10"] [id "1000"] [msg "Hash Validation Violation."] [tag "testphp.vulnweb.com"]

The attacker attempted to to simply remove the hmac token parameter altogether and this is a violation. In the event that the attacker includes an hmac token, it would generate the following event data:

Rule 10094a438: SecRule "REQUEST_URI" "@validateHash \\.(aspx?|php)" "phase:2,log,tag:%{request_headers.host},id:1000,t:none,block,msg:'Hash Validation Violation.',ctl:hashEnforcement=On,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.msg=%{rule.msg},setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}"
Transformation completed in 0 usec.
Executing operator "validateHash" with param "\\.(aspx?|php)" against REQUEST_URI.
Target value: "/showimage.php?file=./database_connect.php&hmac=c7857949531753f07f692db8cb446d6233ed5a5d"
Validating URI /showimage.php?file=./database_connect.php size 42
Signing data [showimage.php?file=./database_connect.php]
Operator completed in 160 usec.
Ctl: Set HashEnforcement to On.
Setting variable: tx.anomaly_score=+%{tx.critical_anomaly_score}
Recorded original collection variable: tx.anomaly_score = "0"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: anomaly_score=0+5
Set variable "tx.anomaly_score" to "5".
Setting variable: tx.msg=%{rule.msg}
Resolved macro %{rule.msg} to: Hash Validation Violation.
Set variable "tx.msg" to "Hash Validation Violation.".
Setting variable: tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}
Resolved macro %{rule.id} to: 1000
Resolved macro %{matched_var_name} to: REQUEST_URI
Resolved macro %{matched_var} to: /showimage.php?file=./database_connect.php&hmac=c7857949531753f07f692db8cb446d6233ed5a5d
Set variable "tx.1000-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-REQUEST_URI" to "/showimage.php?file=./database_connect.php&hmac=c7857949531753f07f692db8cb446d6233ed5a5d".
Resolved macro %{request_headers.host} to: testphp.vulnweb.com
Warning. Request URI matched "\\.(aspx?|php)" at REQUEST_URI. Hash parameter hash value = [c7857949531753f07f692db8cb446d6233ed5a5d] Requested URI hash value = [6c1ee35d09112aba381a4aae49eed9620585f2b2] [file "/usr/local/apache/conf/crs/base_rules/REQUEST-00.conf"] [line "10"] [id "1000"] [msg "Hash Validation Violation."] [tag "testphp.vulnweb.com"]

This event shows that ModSecurity identified a mismatch between the hmac token hash submitted vs. the one that it calculates based on the actual request data.

Forceful Browsing Using Automation

If an attacker tries to use tools to automate the enumeration of resources on the site, this activity can also be blocked. For example, if an attacker tries to use a tool such as the OWASP Zed Attack Proxy's (ZAP)"Forced Browse" Plugin, these requests will be denied as the tool is not following URL links that the web application provided to the end user and are thus missing hmac tokens. Here is an example screenshot of ZAP's Forced Browse session where the requests were blocked by ModSecurity's Hash Token engine:

7654_0229c83f-bd6d-4bc9-86bc-abef5af87711

Automated Botnet Attacks

In a previous blog post, I outlined the typical Botnet recuitement lifecycle:

11375_b5bf4080-a948-4d05-9868-b0ce0f0aee1e

In Step2 2, the Botnet client conducts Search Engine queries to try and identify websites that might be vulnerable to specific, widespread vulnerabilities. Based on those results, the Botnet client will then send pre-crafted attack payloads to the target website. Here is an example of some attack code functions found within a typical perl-based IRC Botnet client that send PHP code injection payloads:

12127_dae7f4d3-66d9-4473-ac18-2e45f6f17f32

The highlighted sections of code show that the Botnet client is sending these attack payloads directly to the URL returned from the Search Enginer results for a target site. If a Botnet client blindly sends attacks at URLs they will blocked by the ModSecurity Hash Token protections due to missing hmac tokens.

Query String Injection Attacks

11128_aa149a8e-ffee-402e-b74b-26321556a86d

SQLi in Query String Parameter

The Acuart "artists.php" resource has an SQL Injection vulnerability. The following screenshot shows an SQLi attack in the "artists" parameter that successfully enumerates the DB user:

12600_f09778cf-4662-41bc-9989-e4c7ad9f6ef7

This is how the normal HREF link to this page looks in the HTML:

10750_97822fc4-2c1b-42d1-8194-0023b99a210d

As you can see, the HREF link already includes the parameter "artists=1" data. When the user clicks on the link, it sends that parameter to the web app. In this case, that parameter is used, insecurely, within a back-end SQL query. With the ModSecurity HMAC token protection in place, however, that same HTML now looks like this:

8678_34a1c387-df1a-4c35-9068-2794f77d2f76

If an attacker tries to tamper with the artists data and send this same SQLi request through ModSecurity with the hmac token protections, it will be blocked. This event will be generated if they do not supply an hmac token:

[Thu Jan 23 17:07:04.692542 2014] [:error] [pid 38405:tid 4453466112] [client 127.0.0.1] ModSecurity: Access denied with code 403 (phase 2). Request URI matched "\\\\.(aspx?|php)" at REQUEST_URI. No Hash parameter[file "/usr/local/apache/conf/crs/base_rules/REQUEST-00.conf"] [line "10"] [id "1000"] [msg "Hash Validation Violation."] [tag "testphp.vulnweb.com"] [hostname "testphp.vulnweb.com"] [uri "http://testphp.vulnweb.com/artists.php?artist=0+div+1+union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A1%2C2%2Ccurrent_user"] [unique_id "UuGSh8CoAWcAAJYF7zQAAADT"]

This is an event if they have an hmac but try and inject the SQLi payload into the "artists" parameter value:

[Thu Jan 23 17:14:53.335440 2014] [:error] [pid 38405:tid 4447563776] [client 127.0.0.1] ModSecurity: Access denied with code 403 (phase 2). Request URI matched "\\\\.(aspx?|php)" at REQUEST_URI. Hash parameter hash value = [a5e6d5e6653b8cefa4681ed86fd6f4ef71701d45] Requested URI hash value = [663886560b52de38ca40323c27c2ebd6545474cf] [file "/usr/local/apache/conf/crs/base_rules/REQUEST-00.conf"] [line "10"] [id "1000"] [msg "Hash Validation Violation."] [tag "testphp.vulnweb.com"] [hostname "testphp.vulnweb.com"] [uri "http://testphp.vulnweb.com/artists.php?artist=+div+0+union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A1%2C2%2Ccurrent_user&hmac=a5e6d5e6653b8cefa4681ed86fd6f4ef71701d45"] [unique_id "UuGUXMCoAWcAAJYF7zgAAADI"]

It is important to note that this defense is aimed at reducing the attack surface of pre-populated query_string parameter data and won't protect against all injection point vectors (such as those sent in POST payload parameter fields).

Cross-Site Scripting (XSS)

9859_6f554d4d-bbe7-4369-b420-02035249e2c4

The Acuart demo app has a number of XSS flaws including one in the "searchFor" parameter of the "search.php" page:

8289_20af48b6-2584-470e-85fb-6bb4f26984d5

When an attacker (or victim) sends a request such as this to the search page, the data is refected back within the response executes the JS code:

9736_694cbf32-18d8-49a2-b0c6-7789c50485eb

Since this XSS vector occurs over a POST request, an attacker could create the following HTML code on a different site/page to auto-submit this data:

9174_4d4af09a-5e9f-4630-801d-58b02637b05e

How can the ModSecurity HMAC Token mechanism protect against this attack vector?

Notice the HTML Form "action" data highlighted in red? This is the location where the form will POST data to. This is important. One of the key requirements of this attack is that the target URL must be idempotent. This means that the attacker must know what URL location to use ahead of time to send the XSS payload to. This is where the Hash Token defense comes into play.

Non-Idempotent (Unique) URLs

When the SecHashMethodrx "HashFormAction" "\.(aspx?|php)" directive is used, the search Form action data is updated to include the hmac token:

10522_8db97a42-f2d2-43a2-bf65-cba44a899c2b

In order to defeat these types of Reflected XSS attacks, we can modify our SecHashKey directive settings to include additional data such as the client's IP Address or the current applicaton SessionID data: SecHashKey rand SessionID.

SecDisableBackendCompression On
SecContentInjection On
SecStreamOutBodyInspection On
SecHashEngine On
SecHashKey rand SessionID
SecHashParam "hmac"
SecHashMethodrx "HashHref" "\.(aspx?|php)"
SecHashMethodrx "HashFormAction" "\.(aspx?|php)"
SecRule REQUEST_URI "@validateHash \.(aspx?|php)" "phase:2,id:1000,t:none,block,msg:'Hash Validation Violation.',ctl:hashEnforcement=On,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:'tx.msg=%{rule.msg}',setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}"

With this updated configurtion - every hmac is unique for each user/session. Here is how the updated debug log processing looks:

Starting phase RESPONSE_HEADERS.
This phase consists of 8 rule(s).
Content Injection: Nothing to inject.
Output filter: Bucket type TRANSIENT contains 1251 bytes.
Output filter: Receiving output (f 10a803d38, r 10a8020a0).
Output filter: Bucket type TRANSIENT contains 2845 bytes.
Output filter: Receiving output (f 10a803d38, r 10a8020a0).
Output filter: Bucket type EOS contains 0 bytes.
Output filter: Completed receiving response body (buffered full - 4096 bytes).
init_response_body_html_parser: assuming ISO-8859-1.
init_response_body_html_parser: Successfully html parser generated.
Signing data [privacy.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [AJAX/index.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [guestbook.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [userinfo.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [login.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [cart.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [artists.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [categories.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [AJAX/index.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [guestbook.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [cart.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [disclaimer.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [artists.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [categories.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [index.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [search.php?test=query]
Using session id [wecm5b45fsznvm552hzoz3bl]
hash_response_body_links: Processed [0] iframe src, [0] hashed.
hash_response_body_links: Processed [0] frame src, [0] hashed.
hash_response_body_links: Processed [1] form actions, [1] hashed.
hash_response_body_links: Processed [23] links, [15] hashed.
inject_hashed_response_body: Detected encoding type [ISO-8859-1].
inject_hashed_response_body: Using content-type [ISO-8859-1].
inject_hashed_response_body: Copying XML tree from CONV to stream buffer [4733] bytes.
inject_hashed_response_body: Setting new content value 4733
inject_hashed_response_body: Stream buffer [4733]. Done
Hash completed in 3215 usec.

In essence, what this means is that an attacker can no longer copy/paste attack code including an hmac token and force another user to use it. This means that this defense can also help to prevent Cross-Site Request Forgery (CSRF) attacks as the hmac tokens function similarly to anti-CSRF tokens.

Conclusion

Hopefully this blog post has demonstrated the power provided by the HMAC Token protections in ModSecurity WAF. By deploying these configurations, you can significantly reduce your attack surface for a number of issues. If you have any feedback or questions, please contact the ModSecurity Project Team.

Latest SpiderLabs Blogs

The Secret Cipher: Modern Data Loss Prevention Solutions

This is Part 7 in my ongoing project to cover 30 cybersecurity topics in 30 weekly blog posts. The full series can be found here. Far too many organizations place Data Loss Prevention (DLP) and Data...

Read More

CVE-2024-3400: PAN-OS Command Injection Vulnerability in GlobalProtect Gateway

Overview A command injection vulnerability has been discovered in the GlobalProtect feature within Palo Alto Networks PAN-OS software for specific versions that have distinct feature configurations...

Read More

CNAPP, CSPM, CIEM, CWPP – Oh My!

We all know the cybersecurity industry loves its acronyms, but just because this fact is widely known doesn’t mean everyone knows the story behind the alphabet soup groups of letters, we must deal...

Read More