CodeShare
Have some code. Share some code.
cancel
Showing results for 
Search instead for 
Did you mean: 
John_Alam_45640
Historic F5 Account

Problem this snippet solves:

F5 has updated the official KB article K43451236 on AskF5 to include an enhanced version of the iRule below that will protect your vulnerable web servers behind the BIG-IP that will mitigate Apache strut2 vulnerability, cve-2017-5638

How to use this snippet:

Add the irule to a virtual server.

Irule below contributed by LinJing.

Code :

# Contributed by LinJing
when HTTP_REQUEST {
if {([HTTP::header exists "Content-Type"])}{
    set ctheader [string tolower [HTTP::header "Content-Type"]]
    if {($ctheader contains "multipart/form-data") and (($ctheader contains "'") or ($ctheader contains "ognl") or ($ctheader contains "java.lang") or ($ctheader contains "bash") or ($ctheader contains "cmd") or ($ctheader contains "org.apache")) }{
          log local0. "Found Struts S2-045 attack! Rejecting a request with Content-type [HTTP::header "Content-Type"] to  [HTTP::uri]  from  [IP::client_addr]"
          #if you do not want to reset the connection, then comment out the lien below
          reject
        }
    }
}
Comments
mortoj_167568
Altocumulus
Altocumulus

Thank you. May I ask what the script might look like if I wanted to also look for GET or any other/multiple HTTP Method? Would it be a separate IF line for each Method or is there a 'wildcard' that can be used?

 

thank you

 

Jeon_Byeong_Jun
Nimbostratus
Nimbostratus

IN ASM, how do i protect this vulnerability using attack signature?

 

mortoj_167568
Altocumulus
Altocumulus

For what it might be worth. We mocked an attack with this exploit by using the PoC found on the net. When we targeted a known server that was vulnerable before we patched it, we found that our current Attack Signature database (We're on version 11.x) was already protecting against CVE-2017-5638

 

These are the Attack Signatures that detected the attempted exploit Code Injection Java (Accessing attributes) Java Code Injection (java packages) (Header) "/bin" execution attempt (Headers)

 

hth

 

John_Alam_45640
Historic F5 Account

Someone just reported that this irule causes a false positive when the Content-Type header includes a boundry string:

 

Content-Type: multipart/form-data; boundary=-------2c5ad0c0c449

 

Also note that the F5 ASM (WAF) has built-in signatures that mitigates this.

 

John_Alam_45640
Historic F5 Account

Here is a modified version which takes care of false positive mentioned above, removes the POST request checking and, adds a few more values to the white-list.

 

Inspecting Content-Type from GET requests requires a much larger white-list and increases the chance for blocking legitimate requests. It also reduces the effectiveness of this iRule and therefore this iRule is not to be trusted to provide complete protection. White-listing values may not be good for all applications.

 

The best protection is using a WAF. Check here.

 

WARNING: the iRule below can produce false-positives and block legitimate traffic. Make sure you adjust the list of Content-types for you application before relying on this iRule.

 

when HTTP_REQUEST {
    switch -glob -- [string tolower [HTTP::header value "Content-Type"]] {
        "" - 
        "multipart/form-data" -
        "text/xml; charset=utf-8" - 
        "text/???" -
        "text/javascript" -
        "image/??? -
        "image/jpeg" -
        "text/html" -
        "multipart/form-data; boundary=*" -
        "application/x-javascript" -
        "application/x-www-form-urlencoded" {
             Allow request with empty or white listed "Content-Type" headers
        }
        default {
             Reject request with unknown "Content-Type" headers
            reject
            log local0. "Rejecting a request with Content-type [HTTP::header Content-Type]  to  [HTTP::uri]  from  [IP::client_addr]"
        }
    }

}
Todd_Zullinger
Nimbostratus
Nimbostratus

FWIW, the vulnerability can be executed via GET requests, as I've seen in the Qualys report on it. I've confirmed this on some systems under my control.

 

Malcolm_Heath_5
Historic F5 Account

Todd's comment is correct. Here is a revised version of the irule that I believe will address this:

 when HTTP_REQUEST {
   if { [HTTP::method] equals "POST" || [HTTP::method] equals "GET" } {
    switch -glob -- [string tolower [HTTP::header value "Content-Type"]] {
        "" - 
        "multipart/form-data; boundary=*" -
        "multipart/form-data" -
        "text/xml" -
        "text/xml; charset=utf-8" - 
        "application/x-www-form-urlencoded" {
             Allow request with empty or white listed "Content-Type" headers
        }
        default {
             Reject request with unknown "Content-Type" headers
            reject
        }
    }
  }
}
linjing
F5 Employee
F5 Employee

If really want to explore the vulnerability, the content-value should include OGNLcommand in %{.....} or ${....}

 

beanwu_8841
Historic F5 Account

Maybe white list the value is not a good idea since there are so many. Some users reported their application is broke after applying the irule. We found the values below.

 

application/x-java-serialized-object application/json

 

John_Alam_45640
Historic F5 Account

Agreed, white-listing only works for some applications and only if you can modify the iRule to fit that app.

 

linjing
F5 Employee
F5 Employee

Here is another iRule that can block most but NOT all attacks. This irule is based on attack signatures that be been seen.

If you decide to use this iRule please test it thoroughly against your application to make sure it does not block legitimate requests.

when HTTP_REQUEST {
if {([HTTP::header exists "Content-Type"])}{
    set ctheader [string tolower [HTTP::header "Content-Type"]]
    if {($ctheader contains "multipart/form-data") and (($ctheader contains "'") or ($ctheader contains "ognl") or ($ctheader contains "java.lang") or ($ctheader contains "bash") or ($ctheader contains "cmd") or ($ctheader contains "org.apache")) }{
          log local0. "Found Struts S2-045 attack! Rejecting a request with Content-type [HTTP::header "Content-Type"] to  [HTTP::uri]  from  [IP::client_addr]"
          if you do not want to reset the connection, then comment out the lien below
          reject
        }
    }
}

Here is another irule that reference a famous FW vendor's sig, Pls test:

when HTTP_REQUEST {
if {([HTTP::header exists "Content-Type"])}{
    set ctheader [string tolower [HTTP::header "Content-Type"]]
    if {($ctheader contains "multipart/form-data") and not($ctheader starts_with "multipart/form-data")}{
         log local0. "Found Struts S2-045 attack! Rejecting a request with Content-type [HTTP::header "Content-Type"] to  [HTTP::uri]  from  [IP::client_addr]"
         if you do not want to reset the connection, then comment out the lien below
         reject
        }
    }
}
Jobs_Hu_135845
Nimbostratus
Nimbostratus

The RCA is the function 'findText' will execute the injection code. That means, before execute the injection code, attacker need to trigger an exception.

 

Thus, the necessary and sufficient conditions are as below:

 

  • The Request contains 'Content-Type'
  • The Content-Type contains 'multipart/form-data'
  • The Content-Type should be illegal to trigger Error Key 'struts.messages.error.content.type.not.allowed'

(refer to: https://cwiki.apache.org/confluence/display/WW/File+UploadFileUpload-AlternateLibraries)

 

This maybe explained why the FW vendor's sig is using starts_with like below (currently, most PoC codes are added additional characters in the beginning of Content-Type):

 

if {($ctheader contains "multipart/form-data") and not($ctheader starts_with "multipart/form-data")}{

I suspect that if modify the PoC string like 'haha%{}multipart/form-data' or 'multipart/form-datahaha%{}' may have same result. That means 'starts_with' may not be exact enough for block the injection. Therefore, I would prefer to choose Linjing's irule. It would be better.

 

Version history
Last update:
‎07-Mar-2017 10:50
Updated by:
Contributors