Forum Discussion

Craig_C_'s avatar
Craig_C_
Icon for Nimbostratus rankNimbostratus
Sep 24, 2014

Has anyone written an iRule to filter CVE-2014-6271?

CVE-2014-6271 was made public today, potentially wreaking havoc on apache/bash. Has anyone written an iRule to filter this vulnerability from HTTP GET requests?

 

19 Replies

  • I simply can't replicate John Alams test, it's basically working if I check for a base64-only string (DAGSUGER), but when I start checking for { etc it just won't trigger on anything. I've sniffed the request itself and it looks like this: GET /?text=DAGSUGER() { :;}; ls -al HTTP/1.1

     

    No amount of adjusting the "contains" check has made it trigger once I start escaping characters in the iRule editor...

     

  • False positives could be an issue with the POST body so I'd try to not use the [HTTP::request] if you are concerned with that.

    The pattern I've found that matches on all the cases I've seen is

    "*(*)*\{*"

    This is simple to do match against using the string match function.

    
    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;
            }
          }
        }
      }
    }
    

    One could greatly simplify this if you aren't concerned with false positives by just using the HTTP::request value

    
    when HTTP_REQUEST {
      if { [string match "*(*)*\{*" [HTTP::request]] } {
        log local0. "Detected CVE-2014-6271 attack from '[IP::client_addr]' in URI = '[HTTP::uri]'";
        reject;
      }
    }
    

    I've run as many use cases as I could through this iRule. If anyone finds one that is not triggered, please comment with the details...

    -Joe

  • John_Alam_45640's avatar
    John_Alam_45640
    Historic F5 Account

    This works for me:

    curl http://192.168.1.59 -H " User-Agent: () { :;}; echo "

    Result is:

     Rule /Common/bash_vul : Detected CVE-2014-6271 attack from 192.168.1.133
     Rule /Common/bash_vul : GET / HTTP/1.1  Host: 192.168.1.59  Accept: */*  User-Agent: () {
    

    This also works:

    curl http://192.168.1.59 -H " User-Agent: () { :;}; echo "

    Result:

    Rule /Common/bash_vul : Detected CVE-2014-6271 attack from 192.168.1.133
    Rule /Common/bash_vul : GET / HTTP/1.1  User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1e zlib/1.2.3 libidn/0.6.5  Host: 192.168.1.59  Accept: */*   User-Agent: () { :;}; echo
    
  • John_Alam_45640's avatar
    John_Alam_45640
    Historic F5 Account

    Moonlit: How are you sending in the string, (curl, browser, script).

    This works for me:

    curl http://192.168.1.59/?text='DAGSUGER() \{ :;\}; ls -al'

    : Detected CVE-2014-6271 attack from 192.168.1.133
    : GET /?text=DAGSUGER() { :;}; ls -al HTTP/1.1  User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1e zlib/1.2.3 libidn/0.6.5  Host: 192.168.1.59  Accept: */*
    

    This does NOT work, look at the resulting Request, { is not sent:

    curl http://192.168.1.59/?text='DAGSUGER() { :;}; ls -al'

    Resulting request to BigIP:

    : GET /?text=DAGSUGER()  :;; ls -al HTTP/1.1  User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1e zlib/1.2.3 libidn/0.6.5  Host: 192.168.1.59  Accept: */*
    

    HTH

  • Below are two ASM signatures that have to be created separately. The concept on the pcre version is this will detect the initial brackets which are necessary and then the white space, to multiple white spaces before the curly which is also necessary. Whitespaces are usually ignored and can be repeated so but a white space can not be between the () or else it will fail so this signature detects the variances that could be used.

     

    headercontent:"shellshock"; nocase;

     

    pcre: "/()(\s+)?{/Hi";

     

  • Anyway, now F5 has an official iRule :)

     

    https://devcentral.f5.com/articles/shellshock-mitigation-with-big-ip-irules

     

  • We've found that on BIG-IP 9.3.1 Build 37.1, when this iRule tries to load from bigip.conf, it fails and must be reloaded manually.

     

    Has anyone else seen this? Has anyone figured out how to make it load correctly?