Shellshock mitigation with BIG-IP iRules
Yesterday, NIST released information on a new network exploitable vulnerability in the GNU Bash shell as demonstrated by vectors involving parts of OpenSSH sshd, the mod_cgi, and mod_cgid modules in the Apache HTTP Server, scripts executed by DHCP clients, and other situations where setting the environment around a bash process occurs. Vulnerability CVE-2014-6271, or Shellshock as everyone is calling it, allows remote attackers to execute arbitrary code on the target systems. Redhat has a great overview in their security blog posting on the topic.
What makes this vulnerability serious is the fact that server-side CGI applications running under the Apache Web Server with mod_cgi or mod_cgid are susceptible.
F5's Jeff Costlow is maintaining an article on the Shellshock vulnerability so make sure you check back to that article for F5's official stance.
The first step to mitigation is to setup a plan to patch the bash shell on all of your systems. In the interum, if you believe that any of your backend servers are vulnerable (if they are Unix-based then they likely are) and you are fronting them with a BIG-IP, below is an iRule solution you can apply to your Virtual Servers that will protect your servers against attacks.
Block-Shellshocked
The Block-Shellshock iRule searches for the pattern "*() {*" in the URI and in the HTTP headers. It is rare that this pattern of characters will occur in a URI or HTTP Header so we believe the number of false-positives will be minimal. If the pattern is found, an audit entry will be written to the system log with the client ip as well as the URI, and optionally the HTTP header, that the attack was detected. I chose to issue a reject on the connection. If you want to be more polite to the hackers, you can substitute the "reject" with a 403 - Forbidden.
"*() \{*"when HTTP_REQUEST { set pattern
; if { [string match $pattern [HTTP::uri]] } { log local0. "Detected CVE-2014-6271 attack from '[IP::client_addr]' in URI '[HTTP::uri]'"; reject; } else { foreach header_name [HTTP::header names] { foreach header_value [HTTP::header values $header_name] { if { [string match $pattern $header_value] } { log local0. "Detected CVE-2014-6271 attack from '[IP::client_addr]' in HTTP Header $header_name = '$header_value'; URI = '[HTTP::uri]'"; reject; break; } } } } }
Block-Shellshock-full
The first iRule gives a more detailed audit if the attack is detected. In the case where that is not a concern and you are more concerned with performance, the HTTP::request method can be used to perform a single search across all of the request header information. This does not cover the POST body, but at this point there is no indication that the exploit is exposed within the body portion of a POST request. This irule reports the client IP along with the requested URI that is the source of the attack.
"*() \{*"when HTTP_REQUEST { if { [string match
[HTTP::request]] } { log local0. "Detected CVE-2014-6271 attack from '[IP::client_addr]'; URI = '[HTTP::uri]'"; reject; } }
We will be monitoring this vulnerability over the coming weeks and update the iRule solution if a more optimal one becomes available. Please leave a comment if you have any suggestions. And, make sure you monitor Jeff's article for updates.
Special Considerations
Please be aware that this iRule will reject any connections containing the string "() {" in the URI or header. While we are confident that this is not a valid pattern for standard headers, there could be situations where custom application values contain this string pattern and this iRule would cause issues to those applications. We suggest running the longer iRule and actively monitoring the system log for false positives. If you find a case where your custom application is being blocked, you can customize the first iRule to exclude the header your application relies on.
- Beinhard_8950Nimbostratusjust one notice, When talking about IDS/IPS and similar we know that "workarounds" usually happens from the attacking "side". So when Irules does not do any decoding I guess that strings like this will pass the irule and still be vulnerible: %28%20) %7b%20
- brad_11480Nimbostratusas Gary noted, the pattern *(*)*\{* would end up with many false positives. User agents, as stated, would be enclosed in parenthesis and then anything following it that uses a left curly brace would trigger. Example: User-Agent: Mozilla/5.0 (Linux; Android 4.4.2; SM-G900T Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.117 Mobile Safari/537.36 Accept-Encoding: gzip,deflate Accept-Language: en-US,en;q=0.8 Cookie: _gat=1; MM_GUID=1ffa80b5-007f-8d02-fbe5-1c15bd314e65; MM_UUID=EEFC18F2-A109-434E-A7C6-5E4F0F400A3D; MM_DP={"bmi":"","gclid":"CIuggZOkicECFSyCMgoddiMAuw"}; ..
- @CodeZone - When you say your users could no longer connect to the internet, did you mean you applied this to a virtual server for outbound traffic? It should be applied to a virtual that is fronting a set of application servers. @Beinhard - We tested decoding and I have an iRule ready to go if we find a way to execute this exploit when passing through encoded values. But, in all our testing, the encoded values are passed back directly to the server and then into Bash where it didn't seem to decode them. Header decoding is something that needs to be handled with the application itself as webservers typically don't change their contents. Have you been able to execute on this exploit by passing in encoded parameters in HTTP Headers? As for the URI, we have only been able to replicate the attack through HTTP::headers but we included the check there for good measure but we haven't been able to replicate with the URI. @brad - that's why I updated the iRule to be a bit more restrictive on the match. After looking at the bash sources, it looks for the literal string so I changed the iRule to do the same.
- On yesterday's guru panel, a user asked a question on how to most easily apply this iRule to 1000+ Virtual Servers. I wrote a little iControl perl script this morning that will apply attempt to apply an iRule (stored in a local file) to all the virtuals on your system. Make sure you test this out before using it but hope it helps those with very large configurations. https://clouddocs.f5.com/api/icontrol-soap/PerlVirtualShow.html
- ITOPSNetwTeam_6NimbostratusDo these iRules also protect against CVE-2014-6277, CVE-2014-6278, CVE-2014-7186 and CVE-2014-7187 ?
- sally_calvert_8Nimbostratusis there a way to make this a blanket irule? If I have 30 VIPS I would need to add the rule to each of those, right?
- rgrojas_76899NimbostratusCan we have a modified iRule that will send an email alert aside from writing message to the log?
- Beinhard_8950Nimbostratus@Joe, i missed that you answered me, sorry for late feedback. I´m also thinking of hex ascii characters, so for example using \x28..... would not match the irule. I´m also thinking about XSS and infect the clients to the "website" and similar attackvectors. I think we will see quite a lot of new attackvectors in the nearest future. So decoding I think needs to be used. Br. Beinhard
- Ashish_Ram_Tak1NimbostratusHow should I check if my BIG IP CLI is affected by Shellshock, is there any way to check.
- Nathan_Bultman_Historic F5 AccountAshish, you can check the list of vulnerable versions and currently available hotfixes for those versions in Solution 15629 on AskF5: http://support.f5.com/kb/en-us/solutions/public/15000/600/sol15629.html