HeartBleed/Heartbeet

Федеральное государственное образовательное бюджетное

Учреждение высшего образования

«Финансовый университет

При Правительстве Российской Федерации»

(Финансовый университет)

Студент группы ИБ4-1

Анточи А.

Откуда растут "ноги" у уязвимости? (1)

При обмене идентичными парами "запрос-ответ" подслушивающая сторона сможет определить какие-то данные по статистическому анализу при использовании слабых протоколов блочного шифрования

Данная опасность устарела, так как все современные реализации TLS используют надежные блочные шифры (ciphersuites)

Откуда растут "ноги" у уязвимости? (2)

Устанавливать новое TLS-соединение слишком долго, поэтому выгоднее его открыть однажды и держать открытым. Чтобы отследить факт "ненужности" соединения, клиент постоянно пингует сервер, и, как только пинг прекращается, сервер разрывает соединение

Откуда растут "ноги" у уязвимости? (3)

Нужно как-то определить максимальный размер пакета, найдя минимально разрешенный размер между всеми узлами (Path MTU)

Все 3 задачи решаются единой функциональностью

...Расширением протокола TLS на уровне RFC - TLS Heartbeat

По документации данное расширение позволяет периодически обмениваться с сервером простыми сообщениями, состоящими из трех полей, что в итоге решает все три перечисленные проблемы.

Формат Heatbeat-сообщений расширения

struct {
      HeartbeatMessageType type;
      uint16 payload_length;
      opaque payload[HeartbeatMessage.payload_length];
      opaque padding[padding_length];
   } HeartbeatMessage;
type:  The message type, either heartbeat_request or
      heartbeat_response.

   payload_length:  The length of the payload.

   payload:  The payload consists of arbitrary content.

   padding:  The padding is random content that MUST be ignored by the
      receiver.  The length of a HeartbeatMessage is TLSPlaintext.length
      for TLS and DTLSPlaintext.length for DTLS.  Furthermore, the
      length of the type field is 1 byte, and the length of the
      payload_length is 2.  Therefore, the padding_length is
      TLSPlaintext.length - payload_length - 3 for TLS and
      DTLSPlaintext.length - payload_length - 3 for DTLS.  The
      padding_length MUST be at least 16.

Ответ на сообщение клиента (отвечает уязвимый сервер)

struct {
      HeartbeatMessageType type;
      uint16 payload_length;
      opaque payload[HeartbeatMessage.payload_length];
      opaque padding[padding_length];
   } HeartbeatMessage;

// та же строка, которую прислал клиент

// длина, которую указал клиент

// тип сообщения - heartbeat_response

// случайный шум, дополняющий длину пакета до максимальной

// и помогающий определить PMTU  (решение 2 и 3 проблем)

Но реализация оказалась ошибочной...

Сервер СЛЕПО верит клиенту в том, что его строка именно той длины, которую он указал, что позволяет выйти за пределы буфера и прочитать память (ОЗУ) за его пределами.

Эта уязвимость имеет название "buffer overread".

"Легендарный" коммит, добавивший уязвимость:

https://github.com/openssl/openssl/commit/bd6941cfaa31ee8a3f8661cb98227a5cbcc0f9f3#diff-38dc72994741420e2b6c5ee074941a45

Что в упрощенной форме можно описать так

Made with Slides.com