Security Irules 101: Engage Cloak!

Introduction

iRules are a powerful tool in the F5 administrators arsenal. They allow administrators to adapt and customize the F5 to their needs. They provide extensive power for security engineers as well. We’ve decided it’s time to revisit the Security iRules 101, with updated content, and 100% more monkeys!

In section 3 of the series, let’s talk about cloaking. Those of you whose first response was “I canna doit captain, I doona hav the powe”,  get a gold star for geek awesome.  (Scratching you head?  You need more Star Trek in your life!)   But no, not that kind of cloaking. Here we are talking about server cloaking.  Servers like to let everyone know who they are, what they do, what time they have, and what is for lunch. A raw server is a lot like the chatty human in the queue at the grocer, willing to tell you their life story. 

Why is this bad?

Attackers aren’t just sitting on the internet launching random attacks at a whim.  There is an entire portion of the process devoted to scouting  (aka information gathering). An attacker wants to know as much as he/she can before they begin the assault. Server headers provide a lovely amount of information, if they are allowed to. The technique is often called “Banner Grabbing”, and essentially boils down to connecting to a service and seeing what banners(data) is returned.  An FTP might return the application that is being used, smtp might tell you what version its at, and HTTP… HTTP can tell you many a things.

Example:

# echo -e "HEAD / HTTP\1.1\r\nhost:1.1.1.1\r\n\r\n"|nc 1.1.1.1 80

All this does is opens a Netcat connection to the server on port 80, and sends over a simple head request

Response from server:

HTTP/1.1 200 OK
Date: Thu, 15 Nov 2012 21:37:32 GMT
Server: Apache/2.2.20 (Ubuntu)
Last-Modified: Tue, 25 Sep 2012 10:33:29 GMT
ETag: "a2b54-b1-4ca843cb6ebf3"
Accept-Ranges: bytes
Content-Length: 177
Connection: close
Content-Type: text/html

Request was successful
Date:   Time on the Server (is their NTP Skewed?)
Server: Actual Server data/version
Last-Modified: Last time page was changed
ETag: Entity Tag for the resource requested
Accept-Ranges: Accept Range Request, size of request
Content-Length: Length of content
Connection: Connection keep alive?
Content-Type: Whats in the payload

 

What does an attacker do next? I grab the server and go to exploit-DB and see what vulnerabilities might be publically known for the application. The banner grab has made the attackers life easier, and no security monkey wants to do that.

 

iRule Response:

We can use an iRule to implement a good positive security model.  First we want to define what we should allow the headers to show.  To do that, let’s create a datagroup called allowed_headers:

ltm data-group internal /Common/allowed_headers {
    records {
        Accept-Range { }
        Cache-Control { }
        Content-Encoding { }
        Content-Length { }
        Content-Type { }
        ETag { }
        Last-Modified { }
        Pragma { }
        Set-Cookie { }
    }
    type string
}

These are pretty basic header options (most used in caching, etc).   Part two of the equation is the rule itself:

when HTTP_RESPONSE {
   foreach Headr [HTTP::header names] {
      if {not ([class match $Headr contains allowed_headers])}{
        log local0. "Removing: $Headr: [HTTP::header value $Headr]" 
        log local0. "Header: $Headr"
         HTTP::header remove $Headr
      }
   }
}

That’s it. 

A loop that goes through each header name in an HTTP_Response and looks for headers that are not on the allowed list. If it’s not on the list, we strip it out.

In practice:

 

BEFORE iRule

After iRule

HTTP/1.1 200 OK
Date: Thu, 15 Nov 2012 21:37:32 GMT
Server: Apache/2.2.20 (Ubuntu)
Last-Modified: Tue, 25 Sep 2012 10:33:29 GMT
ETag: "a2b54-b1-4ca843cb6ebf3"
Accept-Ranges: bytes
Content-Length: 177
Connection: close
Content-Type: text/html

HTTP/1.1 200 OK
Last-Modified: Tue, 25 Sep 2012 10:33:29 GMT
ETag: "a2b54-b1-4ca843cb6ebf3"
Accept-Ranges: bytes
Content-Length: 177
Content-Type: text/html


Clean, clear and under control.  I think the monkey board sums it up rather nicely:

 

 

Published Nov 15, 2014
Version 1.0
  • Simon_Kowallik1's avatar
    Simon_Kowallik1
    Historic F5 Account
    You can also restrict HTTP Response Headers with the LTM HTTP Profile.

     

    Use the "Response Headers Allowed" flied to specify a whitespace delimeted list of allowed headers. Of course you wouldn't have any logging, but it's faster.

     

     

    Example:

     

    [root@bigip:Active] config tmsh modify ltm profile http YOUR_HTTP_PROFILE response-headers-permitted add { Accept-Range Cache-Control Content-Encoding Content-Length Content-Type Etag Last-Modified Pragma Set-Cookie }

     

     

    For documentation see AskF5:

     

    https://support.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/ltm-concepts-11-2-1/ltm_http_profiles.html
  • There is also the HTTP::header sanitize command, which provides a built in method for the sanitization of headers.

     

     

    https://devcentral.f5.com/wiki/irules.HTTP__header.ashx

     

     

    These are all great examples of Positive Enforcement (whitelist models).

     

     

    We could reverse this and create a general blanket Negative Security model, saying that no matter the application, we never want to see the server header leave our environment.