HTTP Brute Force Mitigation Playbook: BIG-IP LTM Mitigation Options for HTTP Brute Force Attacks - Chapter 3

HTTP Brute Force Attacks can be mitigated using BIG-IP LTM features. It could be a straightforward rejection of traffic from a specific source IP, network, geolocation, HTTP request properties or monitoring the number requests from a certain source and unique characteristic and rate limiting by dropping/rejecting requests exceeding a defined threshold. 


Prerequisites

Managing the BIGIP configuration requires Administrator access. Ensure access to Configuration Utility (Web GUI) and SSH is available. These management interfaces will be helpful in configuring, verifying and troubleshooting on the BIGIP. Having access to serial console output of the BIGIP is also helpful. 

Local Traffic Manager (LTM) and Application Visibility and Reporting (AVR) license are required to use the related features.


Prevent traffic from a Source IP or Network 

As demonstrated on the Data gathering chapter for iRules, LTM Policy and of F5 AVR, it is possible that a specific IP address or a specific network may be sending suspicious and malicious traffic. One of the common way to limit access to a HTTP Virtual Server is to either define a whitelist or blacklist of IP addresses. 

HTTP Brute Force Attacks on a Virtual Server can be mitigated by blocking a suspicious IP address or network. These can be done thru iRules, LTM Policy or Network Packet filter. 

Note that when blocking source IPs or networks, it is possible that the source IP is a proxy server and proxies request from internal clients and blocking it may have unintentional blocking of legitimate clients. Monitor traffic that are getting blocked and make necessary adjustments to the related configuration.  


The diagram below shows the packet processing path on a BIG-IP. Notice it also shows reference to Advance Firewall Manager (AFM) packet path. 

https://techdocs.f5.com/content/dam/f5/kb/global/solutions/K31591013_images.html/2018-0613%20AFM%20Packet%20Flow.jpg


Mitigation: LTM Packet Filter

On the left side of the BIG-IP packet processing path diagram, we can see the Ingress section and if the packet information is not in the Hardware Acceleration ePVA (Packet Velocity Asic) of the BIG-IP, it will be checked against the packet filter.

Thus, after determining that an IP address or a Network is suspicious and/or malicious based on gathered data from either the LTM Policy/iRules or AVR or external monitoring tools, a packet filter can be created to block these suspected malicious traffic sources.  


Packet Filter(ing) can be enabled in the Configuration Utility, Network ›› Packet Filters : General


Packet filter rules can be configured at Network ›› Packet Filters : Rules


Sample Packet Filter Configuration:

Packet filter configuration to block a specific IP address with the reject action and have logging enabled


Packet filter configuration to block a Network with the reject action


An Existing Packet filter rule


Packet Filter generated logs can be reviewed at System ›› Logs : Packet Filter

This log shows an IP address was rejected by a packet filter rule


Mitigation: LTM Policy

LTM Policy can be configured to block a specified IP address or from a iRule Datagroup. 


Sample LTM Policy:



LTM policy tmsh output:

Tip: TMOS shell (tmsh) command 'tmsh load sys config from-terminal merge' can be used to quickly load the configuration.


Sample:

root@(sec8)(cfg-sync Standalone)(Active)(/Common)(tmos)# load sys config from-terminal merge
Enter configuration. Press CTRL-D to submit or CTRL-C to cancel.

LTM policy will block specified IP address:

ltm policy block_source_ip {
  last-modified 2019-02-20:22:55:25
  requires { http tcp }
  rules {
    block_source_ip {
      actions {
        0 {
          shutdown
          connection
        }
        1 {
          log
          write
          facility local0
          message "tcl:IP [IP::client_addr] is blocked by LTM Policy"
          priority info
        }
      }
      conditions {
        0 {
          tcp
          address
          matches
          values { 172.16.7.31 }
        }
      }
    }
  }
  status published
  strategy first-match
}


LTM policy will block specified IP address in defined iRule Datagroup:


root@(sec8)(cfg-sync Standalone)(Active)(/Common)(tmos)# list ltm policy block_source_ip
ltm policy block_source_ip {
last-modified 2019-12-01:14:40:57
requires { http tcp }
rules {
block_source_ip {
actions {
0 {
shutdown
connection
}
1 {
log
write
facility local0
message "tcl:IP [IP::client_addr] is blocked by LTM Policy"
priority info
}
}
conditions {
0 {
tcp
address
matches
datagroup malicious_ip_dg
}
}
}
}
status published
strategy first-match
}


malicious_ip_dg is an iRule Datagroup where the IP address is defined


Apply the LTM Policy to the Virtual Server that needs to be protected.


Mitigation: iRule to block an IP address

Using iRule to block an IP address can be done in different stages of the BIG-IP packet processing. 

The sample iRule will block the matched IP address during the FLOW_INIT event.  


FLOW_INIT definition:

This event is triggered (once for TCP and unique UDP/IP flows) after packet filters, but before any AFM and TMM work occurs. 

https://clouddocs.f5.com/api/irules/FLOW_INIT.html


Diagram Snippet from 2.1.9. iRules HTTPS Events. FLOW_INIT event happens after packet filter events. If an IP address is identified as malicious, blocking it earlier before further processing would save CPU resource as iRules processing are resource intensive.


Additionally, if the blocking of an IP address can be done using LTM packet filter, or LTM policy, use it instead of iRules approach. 

https://f5-agility-labs-irules.readthedocs.io/en/latest/class1/module1/iRuleEventsFlowHTTPS.html



Sample iRule:

when FLOW_INIT {
  set ipaddr [IP::client_addr]
  if { [class match $clientip equals malicious_ip_dg] } {
     log local0. "Attacker IP [IP::client_addr] blocked"
# logging can be removed/commented out if not required
    drop
  }
}


malicious_ip_dg is an iRule Datagroup where the IP address is defined


Sample iRule is from K43383890: Blocking IP addresses using the IP geolocation database and iRules. there are more sample iRules in the referenced F5 Knowledge Article.

https://support.f5.com/csp/article/K43383890


Apply the iRule to the Virtual Server that needs to be protected.


Mitigation: Rate Limit based on IP address using iRules

Common scenario during increase of connection when a suspected brute force attack on a Virtual Server with HTTP application is looking for options to rate limit connections to it. 

Using iRule to rate limit connection based IP address is possible. It also offers levels of control and additional logic should it be needed.


Here is a sample iRule to Rate limit IP addresses.

when RULE_INIT {
 # Default rate to limit requests
 set static::maxRate 15
 # Default rate to
 set static::warnRate 12
 # During this many seconds
 set static::timeout 1
}
when CLIENT_ACCEPTED {
   # Increment and Get the current request count bucket
   set epoch [clock seconds]
   set currentCount [table incr -mustexist "Count_[IP::client_addr]_${epoch}"]
   if { $currentCount eq "" } then {
     # Initialize a new request count bucket
     table set "Count_[IP::client_addr]_${epoch}" 1 indef $static::timeout
     set currentCount 1
   }
   # Actually check for being over limit
   if { $currentCount >= $static::maxRate } then {
     log local0. "ERROR: IP:[IP::client_addr] exceeded ${static::maxRate} requests per second. Rejecting request. Current requests: ${currentCount}."
     event disable all
     drop
   }
   elseif { $currentCount > $static::warnRate } then {
     log local0. "WARNING: IP:[IP::client_addr] exceeded ${static::warnRate} requests per second. Will reject at ${static::maxRate}. Current requests: ${currentCount}."
   }
   log local0. "IP:[IP::client_addr]: currentCount: ${currentCount}"
 }


Attach the iRule to Virtual Server that needs to be protected.


HTTP information from sample requests

In the previous chapter "Bad Actor Behavior and Gathering Statistics using BIG-IP LTM Policies and iRules and BIG-IP AVR", some HTTP information will be available via AVR statistics and some may be gathered thru LTM policy or iRules where logs were generated when HTTP requests are received on a F5 Virtual Server which has the iRule or LTM Policy or the HTTP Analytics profile is applied to. These logs are typically logged in /var/log/ltm as normally configured in the irule "log local0." statements or in LTM policy, by default. In the course of troubleshooting and investigation, a customer/incident analyst may decide on what HTTP related information they will consider as malicious or undesirable. In the following sample iRule and LTM Policy mitigation, HTTP related elements were used. Typical HTTP information from the sample request that are used are the HTTP User-Agent header or a HTTP parameter. Other HTTP information can be used as well such as other HTTP headers. 


Mitigation: Prevent a specific HTTP header value

During HTTP Brute Force attacks, HTTP header User-Agent value is often what an incident analyst will review and prevent traffic based on its value, where, a certain user-agent value will be used by automated bots that launches the attack. 


Sample Rule and LTM Policy to block a specific User-Agent


root@(asm6)(cfg-sync Standalone)(Active)(/Common)(tmos)# list ltm policy Malicious_User_Agent
ltm policy Malicious_User_Agent {
last-modified 2019-12-04:17:30:38
requires { http }
rules {
block_UA {
actions {
0 {
shutdown
connection
}
1 {
log
write
facility local0
message "tcl:the user agent [HTTP::header User-Agent] from [IP::client_addr] is blocked"
priority info
}
}
conditions {
0 {
http-header
name User-Agent
values { "Mozilla/5.0 (A-malicious-UA)" }
}
}
}
}
status published
strategy first-match
}


logs generated by LTM Policy in /var/log/ltm


Jan 16 13:11:06 sec8 info tmm3[11305]: [/Common/Malicious_User_Agent/block_UA]: the user agent Mozilla/5.0 (A-malicious-UA) from 172.16.10.31 is blocked

Jan 16 13:11:06 sec8 info tmm5[11305]: [/Common/Malicious_User_Agent/block_UA]: the user agent Mozilla/5.0 (A-malicious-UA) from 172.16.10.31 is blocked

Jan 16 13:11:06 sec8 info tmm7[11305]: [/Common/Malicious_User_Agent/block_UA]: the user agent Mozilla/5.0 (A-malicious-UA) from 172.16.10.31 is blocked


Mitigation: Rate Limit a HTTP Header with a unique value

During a HTTP Brute Force Attack, there may be instances in the attack traffic that a HTTP Header may have a certain value. If the HTTP Header value is being repeatedly used and appears to be an automated request, an iRule can be used to monitor the value of the HTTP header and be rate limited.


Example:  

when HTTP_REQUEST {
 if { [HTTP::header exists ApplicationSpecificHTTPHeader] } {
   set DEBUG 0
   set REQ_TIMEOUT 60
   set MAX_REQ 3
   ##
   set ASHH_ID [HTTP::header ApplicationSpecificHTTPHeader]
    set requestCnt [table lookup -notouch -subtable myTable $ASHH_ID]
   if { $requestCnt >= $MAX_REQ } {
     set remtime [table timeout -subtable myTable -remaining $ASHH_ID]
    if { $DEBUG > 0 } {
      log local0. "Dropped! wait for another $remtime seconds"
    }
    reject
    #this could also be changed to "drop" instead of "reject" to be more stealthy
   } elseif { $requestCnt == "" } {
     table set -subtable myTable [HTTP::header ApplicationSpecificHTTPHeader] 1 $REQ_TIMEOUT
     if { $DEBUG > 0 } {
      log local0. "Hit 1: Passed!"
    }
   } elseif { $requestCnt < $MAX_REQ } {
     table incr -notouch -subtable myTable [HTTP::header ApplicationSpecificHTTPHeader]
    if { $DEBUG > 0 } {
      log local0. "Hit [expr {$requestCnt + 1}]: Passed!"
     }
   }
  }
 }


In this example iRule, the variable MAX_REQ has a value of 3 and means will limit the request from the HTTP Header - ApplicationSpecificHTTPHeader - with specific value to 3 requests.

irule logs generated in /var/log/ltm

Jan 16 13:04:39 sec8 info tmm3[11305]: Rule /Common/rate-limit-specific-http-header <HTTP_REQUEST>: Hit 1: Passed!

Jan 16 13:04:39 sec8 info tmm5[11305]: Rule /Common/rate-limit-specific-http-header <HTTP_REQUEST>: Hit 2: Passed!

Jan 16 13:04:39 sec8 info tmm7[11305]: Rule /Common/rate-limit-specific-http-header <HTTP_REQUEST>: Hit 3: Passed!

Jan 16 13:04:39 sec8 info tmm6[11305]: Rule /Common/rate-limit-specific-http-header <HTTP_REQUEST>: Dropped! wait for another 60 seconds

Jan 16 13:04:39 sec8 info tmm[11305]: Rule /Common/rate-limit-specific-http-header <HTTP_REQUEST>: Dropped! wait for another 60 seconds

Jan 16 13:04:39 sec8 info tmm2[11305]: Rule /Common/rate-limit-specific-http-header <HTTP_REQUEST>: Dropped! wait for another 60 seconds


Sample curl command to test the iRule. Notice the value of the ApplicationSpecificHTTPHeader HTTP header.

for i in {1..50}; do curl http://172.16.8.86 -H "ApplicationSpecificHTTPHeader: couldbemaliciousvalue"; done


Mitigation: Rate Limit a username parameter from HTTP payload

Common HTTP Brute Force attack scenario involves credentials being tried repeatedly. In this sample iRule, the username parameter from a HTTP POST request payload can be observed for a HTTP login url and if the username is used multiple times and exceed the defined maximum requests in a defined time frame, the connection will be dropped.


when RULE_INIT {
# The max requests served within the timing interval per the static::timeout variable
set static::maxReqs 4
# Timer Interval in seconds within which only static::maxReqs Requests are allowed.
# (i.e: 10 req per 2 sec == 5 req per sec)
# If this timer expires, it means that the limit was not reached for this interval and
# the request counting starts over. Making this timeout large increases memory usage.
# Making it too small negatively affects performance.
set static::timeout 2
}
when HTTP_REQUEST {
if { ( [string tolower [HTTP::uri]] equals "/wackopicko/users/login.php" ) and ( [HTTP::method] equals "POST" ) } {
HTTP::collect [HTTP::header Content-Length]
}
}
when HTTP_REQUEST_DATA {
set username "unknown"
foreach x [split [string tolower [HTTP::payload]] "&"] {
if { [string tolower $x] starts_with "token=" } {
log local0. "login parameters are $x"
set username [lindex [split $x "="] 1]
set getcount [table lookup -notouch $username]
if { $getcount equals "" } {
table set $username "1" $static::timeout $static::timeout
# Record of this session does not exist, starting new record
# Request is allowed.
}
elseif { $getcount < $static::maxReqs } {
log local0. "Request Count for $username is $getcount"
table incr -notouch $username
# record of this session exists but request is allowed.
}
elseif { $getcount >= $static::maxReqs } {
drop
log local0. "User $username exceeded login limit current count:$getcount from [IP::client_addr]:[TCP::client_port]"
}
else {
#log local0. "User $username attempted login from [IP::client_addr]:[TCP::client_port]"
}
}
}
}


logs generated in /var/log/ltm

Jan 16 12:34:05 sec8 info tmm7[11305]: Rule /Common/post_request_username <HTTP_REQUEST_DATA>: login parameters are username=!@%23$%25

Jan 16 12:34:05 sec8 info tmm7[11305]: Rule /Common/post_request_username <HTTP_REQUEST_DATA>: User !@%23$%25 exceeded login limit current count:5 from 172.16.10.31:57128

Jan 16 12:34:05 sec8 info tmm1[11305]: Rule /Common/post_request_username <HTTP_REQUEST_DATA>: login parameters are username=!@%23$%25

Jan 16 12:34:05 sec8 info tmm1[11305]: Rule /Common/post_request_username <HTTP_REQUEST_DATA>: User !@%23$%25 exceeded login limit current count:5 from 172.16.10.31:57130


Additional reference:

lindex - Retrieve an element from a list

https://www.tcl.tk/man/tcl8.4/TclCmd/lindex.htm




Prevent traffic source based on Behavior


Mitigation: TLS Fingerprint

In the reference Devcentral Article, https://devcentral.f5.com/s/articles/tls-fingerprinting-a-method-for-identifying-a-tls-client-without-decrypting-24598, it was demonstrated that clients using certain TLS fingerprints can be identified. In a HTTP brute force attack, attacking clients may have certain TLS fingerprint that can be observed and be later on, rate limited or dropped.

TLS fingerprint can be gathered and used to manually or dynamically prevent malicious and suspicious clients coming from certain source IPs from accessing the iRule protected Virtual Server.

The sample TLS Fingerprint Rate Limiting and TLS Fingerprint proc iRules (see HTTP Brute Force Mitigation: Appendix for sample iRule and other related configuration) works to identify, observe and block TLS fingerprints that are considered malicious based on the amount of traffic it sent. 

The TLS Fingerprinting Proc iRule extracts the TLS fingerprint from the client hello packet of the incoming client traffic which is unique for certain client devices.

The TLS Fingerprint Rate Limiting iRule checks a TLS fingerprint if it is an expected TLS fingerprint or is considered malicious or is suspicious. The classification of an expected or malicious TLS fingerprint is done thru LTM rule Data Group.


Example:

Malicious TLS Fingerprint Data Group

ltm data-group internal malicious_fingerprintdb {
records {
0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102 {
data curl-bot
}
}
type string
}

In this example Malicious TLS Fingerprint Data Group, the defined fingerprint may be included manually as decided by a customer/analyst as the TLS fingerprint may have been observed to be sending abnormal amount of traffic during a HTTP brute force event. 


Expected / Good TLS Fingerprint Data Group

ltm data-group external fingerprint_db {
external-file-name fingerprint_db
type string
}


System ›› File Management : Data Group File List ›› fingerprint_db

Properties

Namefingerprint_dbPartition / PathCommonData Group Name fingerprint_db TypeStringKey / Value Pair Separator:=

sample TLS signature: signatures:#"0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102" := "User-Agent: curl-bot",


Taking the scenario where a TLS fingerprint is defined in the malicious fingerprint data group, it will be actioned as defined in the TLS fingerprint Rate Limiting iRule.

If a TLS fingerprint is neither malicious or expected, the TLS fingerprint Rate Limiting iRule will consider it suspicious and be rate limited should certain number of request is exceeded from this particular TLS fingerprint and IP address combination.


Here are example logs generated by the TLS Fingerprint Rate Limiting iRule.

Monitor the number of request sent from the suspicious TLS fingerprint and IP address combination. from the generated log, review the "currentCount"

Dec 16 16:36:58 sec8 info tmm1[11545]: Rule /Common/fingerprintTLS-irule <CLIENT_DATA>: fingerprint:172.16.7.31_0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102: currentCount: 14


Dec 16 16:36:58 sec8 info tmm7[11545]: Rule /Common/fingerprintTLS-irule <CLIENT_DATA>: fingerprint:172.16.7.31_0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102: currentCount: 15


The HTTP User-Agent header value is included in the log to have a record of the TLS fingerprint and the HTTP User-Agent sending the suspicious traffic. This can later be used to define the suspicious TLS fingerprint and the HTTP User-Agent as a malicious fingerprint.


Dec 16 16:36:58 sec8 info tmm1[11545]: Rule /Common/fingerprintTLS-irule <HTTP_REQUEST>: WARNING: suspicious_fingerprint: 172.16.7.31_0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102: User-Agent:curl/7.47.1 exceeded 12 requests per second. Will reject at 15. Current requests: 14.


Dec 16 16:36:58 sec8 info tmm7[11545]: Rule /Common/fingerprintTLS-irule <HTTP_REQUEST>: WARNING: suspicious_fingerprint: 172.16.7.31_0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102: User-Agent:curl/7.47.1 exceeded 12 requests per second. Will reject at 15. Current requests: 15.


The specific TLS fingerprint and IP combination is monitored and as it exceeds the defined request per second threshold in the TLS Fingerprint Rate Limiting iRule, further attempt to initiate a TLS handshake with the protected Virtual Server will fail. The iRule action in this instance is "drop". This will cause the connection to stall on the client side as the BIG-IP will not be sending any further traffic back to the suspicious client. 


Dec 16 16:36:58 sec8 info tmm1[11545]: Rule /Common/fingerprintTLS-irule <CLIENT_DATA>: ERROR: fingerprint:172.16.7.31_0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102 exceeded 15 requests per second. Rejecting request. Current requests: 16.


Dec 16 16:36:58 sec8 info tmm1[11545]: Rule /Common/fingerprintTLS-irule <CLIENT_DATA>: fingerprint:172.16.7.31_0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102: currentCount: 16


Dec 16 16:40:04 sec8 warning tmm7[11545]: 01260013:4: SSL Handshake failed for TCP 172.16.7.31:24814 -> 172.16.8.84:443


Dec 16 16:40:04 sec8 info tmm7[11545]: Rule /Common/fingerprintTLS-irule <CLIENT_DATA>: ERROR: fingerprint:172.16.7.31_0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102 exceeded 15 requests per second. Rejecting request. Current requests: 17.


Dec 16 16:40:04 sec8 info tmm7[11545]: Rule /Common/fingerprintTLS-irule <CLIENT_DATA>: fingerprint:172.16.7.31_0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102: currentCount: 17


Dec 16 16:40:04 sec8 warning tmm7[11545]: 01260013:4: SSL Handshake failed for TCP 172.16.7.31:35509 -> 172.16.8.84:443


If a TLS fingerprint is observed to be sending abnormal amount of traffic during a HTTP brute force event, this TLS fingerprint may be included manually as decided by a customer/analyst in the Malicious TLS Fingerprint Data Group. In our example, this is the malicious_fingerprintdb Data group.


from the reference observed TLS fingerprint, an entry in the data group can be added.


String:
0301+0303+0076+C030C02CC028C024C014C00A00A3009F006B006A0039003800880087C032C02EC02AC026C00FC005009D003D00350084C02FC02BC027C023C013C00900A2009E0067004000330032009A009900450044C031C02DC029C025C00EC004009C003C002F00960041C012C00800160013C00DC003000A00FF+1+00+000B000A000D000F3374+00190018001600170014001500120013000F00100011+060106020603050105020503040104020403030103020303020102020203+000102
Value: malicious-client


Sample Data group in edit mode to add an entry:


Mitigation: Prevent based on Geolocation

It is possible during a HTTP Brute Force Attack that the source of the attack traffic is from a certain Geolocation. Attack traffic can be easily dropped from unexpected Geolocation thru an irule. The FLOW_INIT event is triggered when a packet initially hits a Virtual Server. be it UDP or TCP traffic. During an attack the source IP and geolocation information can be observed using the sample iRule and manually update the reference Data Group with country code where the attack traffic is sourcing from.


Example:

Unexpected Geolocation (Blacklist) iRule:
when FLOW_INIT {
set ipaddr [IP::client_addr]
set clientip [whereis $ipaddr country]
#logging can be removed/commented out if not required

log local0. "Source IP $ipaddr from $clientip"
if { [class match $clientip equals unexpected_geolocations] } {
log local0. "Attacker IP detected $ipaddr from $clientip: Drop!"
#logging can be removed/commented out if not required
drop
}
}


Data Group:

root@(sec8)(cfg-sync Standalone)(Active)(/Common)(tmos)# list ltm data-group internal unexpected_geolocations
ltm data-group internal unexpected_geolocations {
records {
KZ {
data Kazakhstan
}
}
type string
}


Generated log in /var/log/ltm:

Dec 16 21:21:03 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Source IP 5.188.153.248 from KZ

Dec 16 21:21:03 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Attacker IP detected 5.188.153.248 from KZ: Drop!

Dec 16 21:21:04 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Source IP 5.188.153.248 from KZ

Dec 16 21:21:04 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Attacker IP detected 5.188.153.248 from KZ: Drop!

Dec 16 21:21:06 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Source IP 5.188.153.248 from KZ

Dec 16 21:21:06 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Attacker IP detected 5.188.153.248 from KZ: Drop!

Dec 16 21:21:11 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Source IP 5.188.153.248 from KZ

Dec 16 21:21:11 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Attacker IP detected 5.188.153.248 from KZ: Drop!

Dec 16 21:21:15 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Source IP 5.188.153.248 from KZ

Dec 16 21:21:15 sec8 info tmm7[11545]: Rule /Common/block_unexpected_geolocation <FLOW_INIT>: Attacker IP detected 5.188.153.248 from KZ: Drop!


Similarly, it is sometime easier to whitelist or allow only specific Geolocation to access the protected Virtual Server. Here is a sample iRule and its Data Group as a possible option.


Expected Geolocation (Whitelist) iRule:

when FLOW_INIT {
set ipaddr [IP::client_addr]
set clientip [whereis $ipaddr country]
#logging can be removed/commented out if not required
log local0. "Source IP $ipaddr from $clientip"
if { not [class match $clientip equals expected_geolocations] } {
log local0. "Attacker IP detected $ipaddr from $clientip: Drop!"
#logging can be removed/commented out if not required
drop
}
}


Data Group:

root@(sec8)(cfg-sync Standalone)(Active)(/Common)(tmos)# list ltm data-group internal expected_geolocations
ltm data-group internal unexpected_geolocations {
records {
US {
data US
}
}
type string
}


sample curl command which will source the specified interface IP address 


[root@asm6:Active:Standalone] config # ip add | grep 5.188.153.248

inet 5.188.153.248/32 brd 5.188.153.248 scope global fop-lan


[root@asm6:Active:Standalone] config # curl --interface 5.188.153.248 -k https://172.16.8.84

curl: (7) Failed to connect to 172.16.8.84 port 443: Connection refused


Mitigation: Prevent based on IP Reputation

IP Reputation can be used along with many features in the BIG-IP. IP reputation is enabled thru an add-on license and when licensed, the BIG-IP downloads an IP reputation database and is checked against the IP traffic, usually done during connection establishment and matches the IP's category . If a condition to block a category is set, depending on the BIG-IP feature being used, the connection can be dropped or TCP reset or even, return a HTTP custom response page.

It is possible that IPs with bad reputation will send the attack traffic during a HTTP Brute Force attack and blocking these categorised bad IP will help in lessening the traffic that a website needs to process.


Example:

Using LTM Policy

Using a LTM Policy, IP reputation can be checked and be TCP Reset if the IP matches a defined category

[root@sec8:Active:Standalone] config # tmsh list ltm policy IP_reputation_bad
ltm policy IP_reputation_bad {
draft-copy Drafts/IP_reputation_bad
last-modified 2019-12-17:15:08:52
rules {
IP_reputation_bad_reset {
actions {
0 {
shutdown
client-accepted
connection
}
}
conditions {
0 {
iprep
client-accepted
values { BotNets "Windows Exploits" "Web Attacks" Proxy }
}
}
}
}
status published
strategy first-match
}


Verifying the connection was TCP Reset after the Three Way Handshake via tcpdump 

tcpdump -nni 0.0:nnn host 72.52.179.174


15:15:12.905996 IP 72.52.179.174.8500 > 172.16.8.84.443: Flags [S], seq 4061893880, win 29200, options [mss 1460,sackOK,TS val 313915334 ecr 0,nop,wscale 7], length 0 in slot1/tmm0 lis= flowtype=0 flowid=0 peerid=0 conflags=0 inslot=63 inport=23 haunit=0 priority=0 peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0


15:15:12.906077 IP 172.16.8.84.443 > 72.52.179.174.8500: Flags [S.], seq 2839531704, ack 4061893881, win 14600, options [mss 1460,nop,wscale 0,sackOK,TS val 321071554 ecr 313915334], length 0 out slot1/tmm0 lis=/Common/vs-172.16.8.84 flowtype=64 flowid=56000151BD00 peerid=0 conflags=100200004000024 inslot=63 inport=23 haunit=1 priority=3 peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0


15:15:12.907573 IP 72.52.179.174.8500 > 172.16.8.84.443: Flags [.], ack 1, win 229, options [nop,nop,TS val 313915335 ecr 321071554], length 0 in slot1/tmm0 lis=/Common/vs-172.16.8.84 flowtype=64 flowid=56000151BD00 peerid=0 conflags=100200004000024 inslot=63 inport=23 haunit=0 priority=0 peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0


15:15:12.907674 IP 172.16.8.84.443 > 72.52.179.174.8500: Flags [R.], seq 1, ack 1, win 0, length 0 out slot1/tmm0 lis=/Common/vs-172.16.8.84 flowtype=64 flowid=56000151BD00 peerid=0 conflags=100200004808024 inslot=63 inport=23 haunit=1 priority=3


rst_cause="[0x273e3e7:998] reset by policy"


peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0


Using an iRule

Using an iRule, IP reputation can be checked and if the client IP matches a defined category, traffic can be dropped 

See reference article https://clouddocs.f5.com/api/irules/IP-reputation.html

In this example iRule, if a source IP address matches any of IP reputation categories, it will be dropped.


#Drop the packet at initial packet received if the client has a bad reputation
when FLOW_INIT {
# Check if the IP reputation list for the client IP is not 0
if {[llength [IP::reputation [IP::client_addr]]] != 0}{
log local0. "[IP::client_addr]: category: \"[IP::reputation [IP::client_addr]]\""
#remove/comment log if not needed
# Drop the connection
drop
}
}


Generated log for blocked IP with bad reputation

Dec 17 16:22:49 sec8 info tmm6[11427]: Rule /Common/ip_reputation_block <FLOW_INIT>: 72.52.179.174: category: "Proxy {Mobile Threats}"


Final Thoughts on LTM based iRule and LTM Policy Mitigations

The usage of iRule and LTM policy for mitigating HTTP Brute Force Attacks are great if there is only LTM module provisioned in the BIGIP and situation requires quick mitigation. iRules are community supported and are not officially supported by F5 Support. The sample iRules here are tested in a lab environment and will work based on lab scenario which are closely modeled on actual observed attacks. iRules are best configured and implemented by F5 Professional Services which works closely with customer and scope the functionality of the iRule as per customer requirement. 


Some of the mitigation can be done thru LTM Policy. LTM Policy is a native feature of BIGIP and unlike iRules, does not need "on the fly compilation", and thus will be faster and is the preferred configuration over iRules. LTM Policy configuration are straightforward while iRules can be complicated but also flexible and its advantage over LTM Policies.


Rate limiting requests during HTTP Brute Force attack may be a way to preserve some of the legal requests and using iRules, flexible approaches can be done. 


There are more advanced mitigation for HTTP Brute Force attacks using the Application Security Manager (ASM) Module and is preferred over iRules. Example in BIGIP version 14 for ASM, TLS Fingerprinting is a functionality included in the ASM Protection Profiles. TPS based mitigation can also be configured using the ASM protection profiles - example, if request from a source IP is exceeding the defined request threshold, it can be action-ed as configured - example, blocked or challenged using CAPTCHA. Using an ASM Security Policy, attacks such as Credential Stuffing can be mitigated using the Brute Force Protection configuration. Bots can also be categorized and be allowed or challenged or blocked using Bot Defense Profile and Bot Signatures.

Published Apr 14, 2020
Version 1.0

Was this article helpful?

No CommentsBe the first to comment