iRule: CAPTCHA Challenge during Brute Force Attack

Brute force attacks can be painful especially if your application has no logic to help mitigate the attack. Since December of 2015 I have seen several brute force attacks that have traversed multiple business verticals.

I know what you are thinking, “But Brian, we have a cloud based WAF so we are protected.” In every vertical listed above, they all had a cloud based WAF, specifically one of the following:  Akamai Kona, Imperva Incapsula, and CloudFlare WAF. To the customers surprise, these services were not able to mitigate these attacks.

Customer feedback on Akamai Kona:

“They (Akamai Kona) are supposed to be our cloud WAF. Until recent events, we thought we were covered. Turns out, they can’t stop simple HTTP POST attacks!” CISO

Customer feedback on Imperva Incapsula:

“We were originally led to believe that Incapsula was their SecureSphere product in the cloud–it is actually nothing more than a modified version of ModSecurity.

Note: Incapsula is NOT a modified version of ModSecurity–the lack of features in Incapsula led them to believe it was.

When we asked why they didn’t detect the attack they told us that the 4,000 to 6,000 IPs that did the brute force attack (we had to provide the IPs too) weren’t classified in Incapsula as known bad actors. They do not have any mechanisms available to detect bot traffic based on behavior, only IP. The tricky part of this Bot Net was how it behaved, it wasn’t a ton of HTTP POSTS, the Bot behaved as a regular user and only performed 33 to 50 POSTs over a 48 hour period. ” -Security Correlation Specialist

Edit: I had a reference to Skyfence in the above paragraph, copy/paste mistake on my behalf. Credit Ofer Gayer.

Customer feedback on CloudFlare WAF:

“I think CloudFlare’s WAF most innovative feature is holding customers hostage with their crippling low self esteem. Seriously, they are like the prettiest Denny’s waitress of cloud based services and their attitude is “Appreciate what you got, even if what you got is a woman built like mashed potatoes.”” -Network Engineer

Not all cloud based WAFs are created equal. F5 Siverline WAF is the only  cloud based WAF  (F5 ASM) that is recognized in the Gartner Magic Quadrant for Web Application Firewalls. What does this mean to  you? Well for starters, you get:

  • Consistent Security Policy for both on prem and in the cloud
  • Perfect forward secrecy so you can obtain that A+ rating on SSL Labs
  • Complete managed solution, just wear your architect hat if you want to
  • Positive logic security model; ability to learn every HTTP method, header, url, parameter, referrer, cookie, etc
  • Behavioral based detection for botnets, not just IP based
  • The power of iRules!

Since each customer had F5 on prem, they were able to mitigate these attacks when their Cloud WAF couldn’t. One popular technique that was effective was F5 Proactive BOT Defense and CAPTCHA.  Using the iRule below, when the site was being brute forced, we were able to throw a CAPTCHA page to the BOTs and successfully mitigate the attack.

when BOTDEFENSE_ACTION {
    # LOGGING OFF  = 0
    # LOGGING ON   = 1
    set DEBUG_LEVEL 0
    if {[BOTDEFENSE::action] eq "allow"} {
        if {[BOTDEFENSE::captcha_status] ne "correct"} {
                set res [BOTDEFENSE::action captcha_challenge]
                if {$res ne "ok"} {
                    if { $DEBUG_LEVEL == 1} { log local0. "Unable to send captcha_challenge: \"$res\"""}
                    BOTDEFENSE::action tcp_rst
                }
        }
    }
}

While this iRule was used to mitigate the attack on prem, if the customer wanted to use the exact same iRule with F5 Silverline WAF they could. Pretty sweet.

Regards,

BD

iRules: IP Reputation based on X-Forwarded-For HTTP Header

Recently I had a customer that wanted to use the IP Reputation Database on the F5 WAF however the client IP address was being proxied by an upstream device. Luckily for us, the client IP address was being sent in the X-Forwaded-For HTTP Header and we were able to hone in on that information and apply the IP Reputation logic via iRules.

The example below allows you to extract the client IP address from the X-Forwarded-For HTTP Header, check the IP Reputation Database, and either silently drop the traffic or respond with HTTP content.

when HTTP_REQUEST {
    # LOGGING OFF=0, LOGGING ON=1
    set DEBUG_LEVEL 1
    # SLIENT DROP BAD TRAFFIC=0, FRIENDLY DROP BAD TRAFFIC=1
    set BAD_ACTOR 1
    # Make sure XFF is present and the IP matches IPI
    if { ([HTTP::header exists "X-Forwarded-For"]) and not ( [IP::reputation [HTTP::header values "X-Forwarded-For"]] =="") } {
        set ip_reputation_categories [IP::reputation [HTTP::header values "X-Forwarded-For"]]
        set is_reject 0
        switch -glob $ip_reputation_categories {
            *Spam* { set is_reject 1  }
            *Proxy* { set is_reject 1 }
            *Denial* { set is_reject 1 }
            *Attacks* { set is_reject 1 }
            *Botnets* { set is_reject 1 }
            *Scanners* { set is_reject 1 }
            *Exploits* { set is_reject 1 }

        }
        if { ($is_reject)} {
            if { $BAD_ACTOR == "1"}{
                if { $DEBUG_LEVEL == 1} { log local0. "XFF:[HTTP::header values "X-Forwarded-For"] matched IPI Category:$ip_reputation_categories and was rejected with a page."}
                HTTP::respond 403 content "
                <HTML>
                <HEAD>
                <TITLE>Rejected Request</TITLE>
                </HEAD>
                <BODY>The request was rejected. <BR>Attempted access from malicious IP address</BODY>
                </HTML>"
                return
            }
            if { $BAD_ACTOR == "0"} {
                if { $DEBUG_LEVEL == 1} { log local0. "XFF:[HTTP::header values "X-Forwarded-For"] matched IPI Category:$ip_reputation_categories and was sliently dropped."}
                drop
                return
                }
            }
        }
        if { [HTTP::header exists "X-Forwarded-For"] } {
            if { $DEBUG_LEVEL == 1} {log local0. "XFF:[HTTP::header values "X-Forwarded-For"] and did not match any categories"}
            return
        }
    if { $DEBUG_LEVEL == 1} {log local0. "No XFF Sent and nothing was dropped"} 
}

You may also download a txt version of the iRule here.

Note: You can replace X-Forwarded-For to any HTTP Header that contains the client IP address, e.g, true-client-ip.

Regards,

BD