Forum Discussion

sam_111661's avatar
sam_111661
Icon for Nimbostratus rankNimbostratus
Nov 27, 2008

brute force mitigation

I want to use this irule to authenticate users and allow them only if they have a specific LDAP attribute ldap_attr_value. I would like to know if there is a way to prevent brute force attacks by preventing the username to log in for 15 minutes after 3 authentication failures, many thanks in advance

 

 

 

when HTTP_REQUEST {

 

set username [HTTP::username]

 

set password [HTTP::password]

 

set asid_ldap [AUTH::start pam default_ldap]

 

AUTH::subscribe $asid_ldap

 

AUTH::username_credential $asid_ldap $username

 

AUTH::password_credential $asid_ldap $password

 

AUTH::authenticate $asid_ldap

 

HTTP::collect

 

}

 

when AUTH_RESULT {

 

array set auth_response_data [AUTH::response_data]

 

set ldap_attr [lindex [array get auth_response_data ldap:attr:ldap_attr] 1]

 

if {[AUTH::status $asid_ldap] == 0 && $ldap_attr equals "ldap_attr_value"} {

 

HTTP::release

 

log local0. "ldap_attr is set to: $ldap_attr"

 

}

 

else {

 

HTTP::respond 401

 

}

 

}

 

 

  • Sure, most of the code is from devcentral so credits go to others and devcentral. This is for mobile activesync access, it does allow access only to activesync (not OWA or so) authenticates the user, checks if he has one of the required attributes in LDAP and allows three authentication failures before it blacklists the user. I have taken the original ldap auth irule and modified it. And yes it is working but the issue I'm having is with authenticating each and every get / post which is not ideal, I'm trying now to add HTTP cookie auth (not sure is supported by mobile activesync) to it but the command HTTP::cookie decrypt is not working for me as it should

     

     

    when RULE_INIT {

     

    set ::maxauthfail 3

     

    set ::holdtime 300

     

    array set ::blacklist { }

     

    array set ::usertable { }

     

    }

     

    when HTTP_REQUEST {

     

    set srcip [IP::remote_addr]

     

    set currtime [clock second]

     

    if { not ([HTTP::uri] contains "Microsoft-Server-ActiveSync") } {

     

    log local0. "The IP address $srcip is trying to access a non ActiveSync page and has been dropped"

     

    drop

     

    }

     

    if { [ info exists ::blacklist($srcip) ] } {

     

    log local0. "The black list is $::blacklist($srcip)"

     

    if { $::holdtime > [expr ${currtime} - $::blacklist($srcip) ] } {

     

    drop

     

    log local0. "The IP address $srcip is in the blacklist and has been dropped"

     

    return

     

    } else {

     

    unset ::blacklist($srcip)

     

    log "The IP address $srcip has been removed from the blacklist"

     

    }

     

    }

     

    if {not [info exists tmm_auth_http_sids(ldap)]} {

     

    set tmm_auth_sid [AUTH::start pam default_ldap]

     

    set tmm_auth_http_sids(ldap) $tmm_auth_sid

     

    if {[info exists tmm_auth_subscription]} {

     

    AUTH::subscribe $tmm_auth_sid

     

    }

     

    } else {

     

    set tmm_auth_sid $tmm_auth_http_sids(ldap)

     

    }

     

    AUTH::subscribe $tmm_auth_sid

     

    AUTH::username_credential $tmm_auth_sid [HTTP::username]

     

    AUTH::password_credential $tmm_auth_sid [HTTP::password]

     

    AUTH::authenticate $tmm_auth_sid

     

    log local0. "auth. session is: $tmm_auth_sid"

     

    if {not [info exists tmm_auth_http_collect_count]} {

     

    HTTP::collect

     

    set tmm_auth_http_successes 0

     

    set tmm_auth_http_collect_count 1

     

    } else {

     

    incr tmm_auth_http_collect_count

     

    }

     

    }

     

    when AUTH_RESULT {

     

    if {not [info exists tmm_auth_http_sids(ldap)] or \

     

    ($tmm_auth_http_sids(ldap) != [AUTH::last_event_session_id]) or \

     

    (not [info exists tmm_auth_http_collect_count])} {

     

    return

     

    }

     

    if {[AUTH::status] == 0} {

     

    incr tmm_auth_http_successes

     

    }

     

    If multiple auth sessions are pending and

     

    one failure results in termination and this is a failure

     

    or enough successes have now occurred

     

    if {([array size tmm_auth_http_sids] > 1) and \

     

    ((not [info exists tmm_auth_http_sufficient_successes] or \

     

    ($tmm_auth_http_successes >= $tmm_auth_http_sufficient_successes)))} {

     

    Abort the other auth sessions

     

    foreach {type sid} [array get tmm_auth_http_sids] {

     

    unset tmm_auth_http_sids($type)

     

    if {($type ne "ldap") and ($sid != -1)} {

     

    AUTH::abort $sid

     

    incr tmm_auth_http_collect_count -1

     

    }

     

    }

     

    }

     

    array set auth_response_data [AUTH::response_data]

     

    set my_ldap_attr [lindex [array get auth_response_data ldap:attr:my_ldap_attr] 1]

     

    If this is the last outstanding auth then either

     

    release or respond to this session

     

    incr tmm_auth_http_collect_count -1

     

    if {$tmm_auth_http_collect_count == 0} {

     

    unset tmm_auth_http_collect_count

     

    if {[AUTH::status] == 0 && ($my_ldap_attr == "att_value_1" or $my_ldap_attr == "att_value_2")} {

     

    log local0. "my_ldap_attr LDAP attribute is set to: $my_ldap_attr"

     

    HTTP::release

     

    log "logpoint 1a"

     

    set ::usertable(freq,$srcip) 0

     

    log "logpoint 1ab"

     

    log "$srcip^$::usertable(time,$srcip)^$::usertable(freq,$srcip)"

     

    } else {

     

    if { [ info exists ::usertable(time,$srcip)] } {

     

    incr ::usertable(freq,$srcip)

     

    log "$srcip^$::usertable(time,$srcip)^$::usertable(freq,$srcip)"

     

    log "logpoint is 1abc"

     

    if { $::usertable(freq,$srcip) > $::maxauthfail } {

     

    log "new blacklist member <$srcip>"

     

    set ::blacklist($srcip) $currtime

     

    unset ::usertable(freq,$srcip)

     

    unset ::usertable(time,$srcip)

     

    drop

     

    return

     

    } else {

     

    log "logpoint is 1abcd"

     

    HTTP::respond 401

     

    }

     

    } else {

     

    log "logpoint is 1abcde"

     

    HTTP::respond 401

     

    set ::usertable(freq,$srcip) 1

     

    set ::usertable(time,$srcip) $currtime

     

    }

     

    }

     

    }

     

    }