\n\n\n\n\n\n\n\n\n\n\n

flawopen.com/Симуляторы/Heartbleed Buffer Overread

Безопасность памяти / OpenSSL TLS

Интерактивный симулятор переполнения буфера OpenSSL Heartbleed (CVE-2014-0160)

Интерактивная визуальная модель памяти в браузере, демонстрирующая чтение за пределами буфера кучи (heap overread) из-за отсутствия проверки длины пакета TLS Heartbeat.

💡 Простое объяснение (ELI5)

Представьте, что вы говорите дрессированному попугаю слово из 4 букв «BIRD» и просите: «Повтори это слово, но сделай ответ длиной в 64 000 букв». Попугай выкрикивает «BIRD», а затем начинает непрерывно выдавать следующие 63 996 символов из своей оперативной памяти — включая секретные пароли, приватные ключи SSL и финансовые данные других посетителей. В уязвимости Heartbleed OpenSSL слепо доверял заявленной клиентом длине, не проверяя реальный размер пакета, и копировал байты серверной памяти прямо злоумышленнику.

Ключевые понятия и термины подсистемы

TLS Heartbeat Extension
Механизм поддержания соединения RFC 6520 для проверки работоспособности канала без повторного согласования.
\n
Payload Length Field
16-битное целое число в заголовке пакета, заявляющее длину полезной нагрузки (до 65 535 байт).
\n
Buffer Overread
Уязвимость безопасности памяти, при которой программа читает данные за пределами выделенного буфера процесса.
\n
Неограниченный memcpy()
Функция копирования памяти, длина которой задается непроверенными входными данными клиента.

Пошаговая механика атаки и выполнения

1

Отправка искаженного запроса Heartbeat

Злоумышленник отправляет запрос с телом в 1 байт ('A'), но в поле длины указывает 65 535 байт (0xFFFF).

\n
2

Отсутствие проверки границ пакета

OpenSSL считывает заявленный размер через n2s(p, payload) без проверки условия 1 + 2 + payload + 16 <= rrec.length.

\n
3

Выделение буфера ответа на 64 КБ

Сервер выделяет в куче буфер размером 64 КБ, полностью полагаясь на фиктивные данные клиента.

\n
4

Утечка памяти процесса кучи

Вызов memcpy() считывает 64 КБ данных за пределами входящего байта, сливая приватные ключи RSA и токены сессий.

Дифф исходного кода: проверка границ в tls1_process_heartbeat()

УЯЗВИМЫЙ КОД: ОТСУТСТВИЕ ПРОВЕРКИ ГРАНИЦ В OPENSSL 1.0.1f
/* Чтение 16-битной длины напрямую из пакета без проверки */
n2s(p, payload);
pl = p;

/* Выделение буфера ответа на основе размера, заявленного клиентом */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;

/* ОШИБКА: Копирует до 64 КБ соседней памяти кучи сервера! */
memcpy(bp, pl, payload);
r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
ИСПРАВЛЕНИЕ: СТРОГАЯ ПРОВЕРКА РЕАЛЬНОГО РАЗМЕРА ЗАПИСИ (RFC 6520)
/* Чтение 16-битной длины из пакета */
n2s(p, payload);
pl = p;

/* ИСПРАВЛЕНИЕ: Проверяем, что заявленная длина не превышает реально полученную запись */
if (1 + 2 + payload + 16 > s->s3->rrec.length)
    return 0; /* Бесшумно отбрасываем искаженный пакет */

buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
memcpy(bp, pl, payload);

Чек-лист по усилению безопасности системы

← Все симуляторы Читать полный разбор CVE-2014-0160 Heartbleed →