April/2022 – CVE-2022-22965: Spring4Shell Remote Code Execution Mitigation

Recently, a Remote Code Execution vulnerability was discovered in the Java Spring Core library. This vulnerability allows attackers to execute arbitrary code on affected systems.

You can find more information on that vulnerability in the announcement on the Spring Blog.

While HAProxy Enterprise, HAProxy ALOHA, and other products within the HAProxy Technologies portfolio are not impacted by this (they do not use the Spring Core library at all), you can use our products to mitigate the attack.

These mitigation techniques we describe are subject to change as attackers develop new attack vectors, new false positives are discovered, or better ways to handle the issue are found. When the rules change, this blog post will be updated with a changelog added to the bottom. While these rules have been tested against the original attack vectors, they have a high risk of false positives in many environments. We recommend testing these rules in your environment (such as replacing the http-request deny rules with an http-request capture rule to log violations rather than deny them outright).

To block the attack, add the following ACLs, which are an adaptation of the ModSecurity solution described later, to a frontend or listen section within your load balancer configuration:

frontend fe_main
...
option http-buffer-request
http-request deny if { query -i -m sub class.module.classLoader.resources.context.parent.pipeline springframework.context.support.FileSystemXmlApplicationContext }
http-request deny if { req.hdrs -i -m sub class.module.classLoader.resources.context.parent.pipeline springframework.context.support.FileSystemXmlApplicationContext }
http-request deny if { req.body -i -m sub class.module.classLoader.resources.context.parent.pipeline springframework.context.support.FileSystemXmlApplicationContext }

Alternatively, enable the ModSecurity web application firewall (WAF) module:

Find the following line in the file /etc/hapee-2.4/modsec.rules.d/lb-modsecurity.conf in HAProxy Enterprise:

Include /etc/hapee-2.4/modsec.rules.d/crs-setup.conf

Or find the following line in the file /app/security/etc/sec-offloader/modsecurity.load in HAProxy ALOHA :

include modsecurity/crs-setup.conf

Then add the following rule directly after:

SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
"@rx (?:class[.]module[.]classLoader[.]resources[.]context[.]parent[.]pipeline|springframework[.]context[.]support[.]FileSystemXmlApplicationContext)" \
"id:944260,\
phase:2,\
deny,\
t:urlDecodeUni,\
msg:'Remote Command Execution: Malicious class-loading payload',\
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
tag:'application-multi',\
tag:'language-java',\
tag:'platform-multi',\
tag:'attack-rce',\
tag:'OWASP_CRS',\
tag:'capec/1000/152/248',\
tag:'PCI/6.5.2',\
tag:'paranoia-level/2',\
ver:'OWASP_CRS/3.4.0-dev',\
severity:'CRITICAL',\
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'"

This rule can be found on the ModSecurity Core Rule Set project page. If this is the first time you are enabling the ModSecurity WAF, we recommend running it in detection-only mode at first to log malicious requests but not immediately block them.

With HAProxy Enterprise, you can also block the attack by enabling the Advanced WAF:

Then update your ruleset files by updating to the latest hapee-2.5r1-lb-wafadvanced package (or using the corresponding package for your version of HAProxy Enterprise). Follow the documentation for how to set thresholds for blocking threats.

If this is the first time you are enabling the Advanced WAF, we recommend running it in learning mode at first, to log malicious requests but not immediately block them.

To test that the mitigations you have configured are working correctly, try the following curl command on your HAProxy Enterprise server:

curl -v -d "class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=" http://localhost

If the blocking rules are working correctly, that request will be denied.

Changelog

  • 11 April 2022: Changed ModSecurity rule to use “urlDecodeUni” instead of “urlDecode”

Subscribe to our blog. Get the latest release updates, tutorials, and deep-dives from HAProxy experts.