ssl_hx_rlimit - iRule Countermeasure for no-crypto SSL handshake attacks¶
Contributed by: David Holmes¶
Description¶
This is an iRule countermeasure for a new class of so-called
“no-crypto” SSL handshake attack tools. These attack tools are similar
to the original SSL Renegotiation DoS
attack
but they are much more efficient. This efficiency allows them to
effectively achieve an asymmetric multiplier of 100 times processing
power. The original DoS iRule and the new built-in renegotiation
countermeasures in 11.5.0 do not stop these attacks, since the attack
tools use a single TCP connection for each handshake request.
The ssl_hx_rlimit iRule detects consecutive failed SSL handshakes. If
any source address sends more than five consecutive bad handshakes in
a three-minute time period it will be blacklisted until that period
expires.
Breakdown:
- Each new TCP connection gets a “state” variable in a table index by the client source address.
- If the connection sends an SSL ClientHello, then the state moves to SSL_STARTED.
- Good: If the handshake completes, clear the state.
- Bad: If connection closes then this as an attack attempt (increment table count).
When the same IP address sends five consecutive attack attempts
subsequent connections will be blocked until the table entry times out
(180 seconds). You’ll see a log message like this in /var/log/ltm.
May 7 19:00:58 alert tmm: Rule ssl_hx_rlimit – Handshake attack
underway, blocking for 180 seconds.
iRule Source¶
# ssl_hx_rlimit - handshake attack countermeasure
#
# Simple iRule to detect and reject SSL handshake attacks that would bypass normal
# SSL Renegotiation countermeasure. Does not handle megaproxies.
#
# If any IP address starts 5 consecutive SSL connections without completing
# and sending HTTP data, it gets blocked for 180 seconds (the default table timeout)
#
# David Holmes d.holmes at f5.com
#
# v1.1 - use CLIENTSSL_HANDSHAKE complete instead of HTTP_REQUEST to
# reset the state clock to okay for that IP address
#
proc debugmsg { str } {
if { $static::debug_me } {
log local0.info $str
}
}
when RULE_INIT {
# max no. of handshakes started to be allowed
set static::maxhx 5
# log debug info?
set static::debug_me false
# various states that a connection can be in
set static::state_accepted 0
set static::state_ssl_started 1
set static::state_sent_data 2
}
when CLIENT_ACCEPTED {
set cstate $static::state_accepted
set hx [table lookup -notouch [IP::client_addr]]
if { $hx >= $static::maxhx } {
if { $static::debug_me } {
set te [table timeout -remaining [IP::client_addr]]
call debugmsg "[IP::client_addr] BLACKLISTED for $te more seconds"
}
# A drop will slow down the client, but the client will still send
# the ChangeCipherSpec message and that which will chew up our processing
# resources. Send a reject instead, which will decrease the turnaround
# time but will defend our processors.
reject
}
}
when CLIENTSSL_CLIENTHELLO {
set cstate $static::state_ssl_started
call debugmsg "clienthello received [IP::client_addr]"
}
when CLIENTSSL_HANDSHAKE {
# Any successful handshake from that IP and will "clear" the table
if { $cstate == $static::state_ssl_started } {
table delete [IP::client_addr]
set cstate $static::state_sent_data
call debugmsg "client request started, clearing table [IP::client_addr]"
}
}
when CLIENT_CLOSED {
if { $cstate == $static::state_ssl_started } {
call debugmsg "HANDSHAKE ATTACK PROBABLE [IP::client_addr]"
if { [table incr [IP::client_addr]] == $static::maxhx } {
# recommend using HSL instead of log for production
log local0.alert "Handshake attack underway, blocking [IP::client_addr] for 180 seconds."
}
}
else {
call debugmsg "closing conn [IP::client_addr] state = $cstate"
}
}
The BIG-IP API Reference documentation contains community-contributed content. F5 does not monitor or control community code contributions. We make no guarantees or warranties regarding the available code, and it may contain errors, defects, bugs, inaccuracies, or security vulnerabilities. Your access to and use of any code available in the BIG-IP API reference guides is solely at your own risk.