ModSecurity Advanced Topic of the Week: Automated Virtual Patching Script

Automated Virtual Patching Example Script

image from

The SpiderLabs Research Team has added an example script to the OWASP ModSecurity Core Rule Set (CRS) Project archive that will help users to quickly implement virtual patches for vulnerabilities identified by an open source web vulnerability scanning tool. The example script ( is located in the /util directory of the CRS archive in SVN and will auto-convert XML data from the Arachni web application scanning framework written by Tasos Zapotek Laskos into custom ModSecurity rules.

Why Arachni (vs. some other scanner)? Well, besides the fact that it is an extremely good tool, SpiderLabs felt a certain kinship with the project due to it being an Arachnid sibling ;) While this example script can only currently process Arachni XML report data, the script could be adapted to process other DAST tools by updating the XML::Smart variables to handle different schemas.

The script will parse the XML data from Arachni and will auto-create ModSecurity rules for the following attack/vulnerability categories:

  • SQL Injection
  • Cross-site Scripting
  • Remote File Inclusion
  • Local File Inclusion
  • HTTP Response Splitting

Here is an example of the XML output from arachni for an SQL Injection vulnerability found in the Acunetix Acuart Demo site.

    <issue><name>SQL Injection</name>
<tags><tag name="sql" /><tag name="injection" /><tag name="regexp" /><tag name="database" /><tag name="error" /></tags>
<variable>artist</variable><description>SQL code can be injected into the web application.</description>

The XML data highlighted can be parsed by the scripts to create a ModSecurity rule based on the injection point (URL + Parameter name) and vulnerability category.

Virtual Patching Challenges

The true value of levaraging vulnerability scanner data is confirmation of a known attack vector location or injection point for a specific attack category (such as SQL Injection). Now that you know where a vulnerability exists, the question is how do you want to protect against it? Ideally, you should use a positive security model which will only allow the data types and lengths that you want. If that is not possible, then you can use a negative security approach and deny things that you consider bad. In the case of using DAST data, it becomes tricky if you want to use attack payloads used during the test. The reason is that oftentimes the payloads used during testing are inference-based and geared towards identify a vulnerability vs. actual malicious payloads used by attackers. Vulnerability scanning is used to identify if a vulnerability exists, not to identify all of the possible exploitation variations.

So how can we identify attacks attempting to exploit these vulnerable resources?

The ModSecurity Core Rule Set uses the concept of "generic attack payload detection" where it has many different methods of identifying malicious payloads where ever they may exist. It does not, however, know if this is a known vulnerable injection point. The result is that there is a higher degree of false positives. When we uuse both the CRS generic detection along with the known attack injection point intelligence from the vulnerability scanner XML output, the user can have an increased confidence in blocking. Running the Virtual Patching Scripts To run the scripts, simply specify which XML file to use as input:

$ ./arachni2modsec.plFlag:  -f:  path to arachni xml report fileUsage: ./ -f ./arachni_report.xml$ ./ -f arachni_testphp-vulnweb.xml==================================================================================================Vulnerability[0] -  Type: Cross-Site Scripting (XSS)Found a Cross-Site Scripting (XSS) vulnerability.Validating URL: is well-formedContinuing Rule GenerationCurrent vulnerable Param(s): searchForCross-Site Scripting (XSS) (uricontent and param) rule successfully generated and saved in ./modsecurity_crs_48_virtual_patches.conf.==================================================================================================Vulnerability[1] -  Type: SQL InjectionFound a SQL Injection vulnerability.Validating URL: is well-formedContinuing Rule GenerationCurrent vulnerable Param(s): catSQL Injection (uricontent and param) rule successfully generated and saved in ./modsecurity_crs_48_virtual_patches.conf.==================================================================================================--CUT--==================================================================================================Vulnerability[19] -  Type: The TRACE HTTP method is enabled.Vulnerability Type:  is not supported in this version.==================================================================================================--CUT--************ END OF SCRIPT RESULTS *****************Number of Vulnerabilities Processed: 49Number of ModSecurity rules generated:   9Number of Unsupported vulns skipped:     40Number of bad URLs (rules not gen):      0****************************************************----------------------------------------------------To activate the virtual patching file (./modsecurity_crs_48_virtual_patches.conf),copy it into the CRS "base_rules" directory and then createa symlink to it in the "activated_rules" directory.-----------------------------------------------------

As you can see, there were both Cross-site Scripting and SQL Injection vulns found within the Arachni report. For vulnerability categories that the script doesn't handle, you will also get a notification as shown for the "The TRACE HTTP method is enabled" alert.

Let's now take a look at an example ModSecurity rule created based on the vuln data:

## Arachni Virtual Patch Details:# ID: 11# Type: SQL Injection# Vulnerable URL: listproducts.php# Vulnerable Parameter: cat#SecRule REQUEST_FILENAME "listproducts.php" "chain,phase:2,t:none,block,msg:'Virtual Patch for SQL Injection',id:'11',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',logdata:'%{matched_var_name}',severity:'2'"        SecRule &TX:'/SQL_INJECTION.*ARGS:cat/' "@gt 0" "setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score}"

As you can see, the first SecRule is checking the request line data to make sure that it matches the vulnerable resource. We then run a 2nd chained rule that, instead of looking separately for the existence of the parameter name and a regex match, it simply inspects previously matched TX variable meta-data. In this case, if a previous CRS rules had already identified an SQL Injection attack payload in the "ARGS:cat" parameter location, then the rule matches.

Continued Maintenance

Organizations can use this process each time that they run their vulnerability scans so that they can swap in the most up-to-date virtual patches.

Trustwave reserves the right to review all comments in the discussion below. Please note that for security and other reasons, we may not approve comments containing links.