Since we just announced a powerful Lua API, we thought we’d take a crack at detecting this attack.

The detection is extremely straightforward, just compare the size of the pending heartbeat request when the response arrives. If they dont match, we have a hit. I saw some tools trying to use a single heartbeat packet to declare an attack by comparing the two length fields. That will work but only when the heartbeats are sent before the change_cipher_spec record. After switching over to encryption it is not possible to compare the two length fields.

A rough sketch of the attack is shown below. The 64K packet is likely to be chopped up into 16K pieces using TLS segmentation. We havent tried to get a packet capture going yet. That detail may not impact our script.

Use a LUA flowmonitor

For the Lua script, our weapon of choice is the flowmonitor One of the attributes extracted from flows is TLS:RECORD. All TLS records, with the notable exception of 23 (application_data) are passed to your Lua script. We just pick up from there as shown below.

Explanation

On receiving a heartbeat record, we just check if there is a pending request and compare that length with this one. If they mismatch we’ve got a hit. Needs to be seen if the TLSRFC allows multiple inflight heartbeats. This lookup is very cheap in Lua, even without LuaJIT.

Monitoring approach

This kind of IDS style detection is certainly possible as shown here. But Trisul’s approach is to meter more and more things about TLS. If we had stats for TLS record types seen over time, we could have picked up any abnormal bump in heartbeat activity.

We have also published a little Lua script that measures “TLS Record” types called tls-monitor.lua Stick this in your plugins/lua folder and going forward you can keep track of the what types of records are seen.