Detecting heartbleed with Trisul and Lua

The big news today is a new extremely serious vulnerability in OpenSSL called the “Heart Bleed”. The Inquirer claims that two thirds (?) of webservers are vulnerable OpenSSL security bug exposes two thirds of webservers to attack

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.

The full script is available at tls-heartbeat-2.lua

if nm == "TLS:RECORD" then
  local  content_type = valbuff:hval_8(0)

  if content_type == 24 then
    local len  = pending_hb_requests[flow:id()]

    -- found pending inflight request, compare sizes and alert 
    if len then 
      local req_len  = pending_hb_requests[flow:id()]

      if req_len ~= len then

        engine:add_alert_full( 
          "{9AFD8C08-07EB-47E0-BF05-28B4A7AE8DC9}", -- GUID for IDS 
          flow:id(),                                -- flow 
          "sid-8000002",                            -- a sigid (private range)
          "trisul-lua-gen",                         -- classification
          "sn-1",                                   -- priority 1, 
          "Possible heartbleed situation ")         -- message 

      end
      pending_hb_requests[flow:id()] = nil 
    else
      -- save size of inflight  TLS hb request 
      pending_hb_requests[flow:id()] = valbuff:size()
    end
  end

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 TLS RFC 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.

Trisul’s existing TLS based counter groups are

  1. TLS Cert Authorities both root and intermediate (Verisign, Comodo, ..)
  2. TLS Orgs (google, twitter, ..)
  3. TLS Cipher Suites

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.

Stay safe !

Free Download Trisul 4.0 !

Leave a Reply

Your email address will not be published. Required fields are marked *