А как работает баг Heartbleed!

Добро пожаловать в серию статей об эксплуатации двоичных файлов! В этой серии мы узнаем об эксплуатации двоичных файлов, теории, лежащей в основе методов эксплуатации двоичных файлов, и механизмах защиты, разработанных против них.

Сегодня давайте поговорим о классе уязвимостей, который очень похож на переполнение буфера: переполнение буфера. Кстати, про переполнение буфера обязательно ознакомьтесь здесь:



Что такое переполнение буфера?

Переполнение буфера похоже на переполнение буфера, за исключением того, что оно происходит во время операции чтения. При чтении из буфера программа переходит границу буфера и читает соседнюю память.

* Program is suppose to read til here * But reads til here...
<-------------------------------------><--------------------------->
     Buffer                                Other program data

В таких языках, как C и C ++, программы могут свободно обращаться к данным в любой части виртуальной памяти через указатель. Из-за этого проблемы с переполнением буфера могут возникать, когда указатели или их индексы увеличиваются за пределами буфера (при итерации массива или чтении строки) или когда арифметика указателей дает результат за пределами допустимого адреса памяти.

Иногда злоумышленники могут использовать это для утечки конфиденциальной информации.

Как работает Heartbleed

Большинство из вас, вероятно, уже слышали о Heartbleed (CVE-2014–0160). Heartbleed - это ошибка безопасности, обнаруженная в криптографической библиотеке OpenSSL и раскрытая еще в 2014 году. Уязвимость привела к широкомасштабной эксплуатации и краже финансовой и медицинской информации миллионов людей.

Основная причина этой уязвимости - ошибка переполнения буфера в реализации OpenSSL расширения пульса TLS / DTLS, которое используется для проверки работоспособности защищенных каналов связи. Протокол работает так:

  1. Machine1 отправляет серверу сообщение heartbeat-запроса. Это сообщение включает полезную нагрузку (произвольную строку) и payload_length (длину указанной полезной нагрузки).
  2. Machine2 отвечает сообщением контрольного сигнала. Он включает ту же строку полезной нагрузки, которая получена от отправителя.
  3. Machine1 получает ответ и проверяет, содержит ли ответное сообщение ожидаемую строку полезной нагрузки.

Так в чем же была ошибка?

Ошибка Heartbleed возникла из-за неправильного выполнения шага 2. Уязвимая версия OpenSSL выделяет буфер, содержащий возвращаемую полезную нагрузку на основе значения payload_length, не проверяя, соответствует ли фактическая длина полезной нагрузки равно payload_length.

Таким образом, злоумышленник может осуществить утечку информации с целевой машины, отправив сообщение с запросом пульса с длиной полезной нагрузки, превышающей фактическую длину полезной нагрузки. Целевая машина тогда вернет данные из соседних ячеек памяти до размера payload_length. Шаги эксплуатации выглядят так:

  1. Машина злоумышленника отправляет запрос пульса с десятибайтовой полезной нагрузкой и размером полезной нагрузки, равным 1000 байтов.
  2. Сервер-жертва отвечает десятибайтовой полезной нагрузкой вместе с 990 байтами данных из соседних областей памяти.
* Program reads payload_length (1000 bytes) from memory ......
<--------------------------------------><-------------------------->
  Payload (10 bytes)                      Other program data

Вывод

Надеюсь, этот пост был полезен в разъяснении того, что такое переполнение буфера. Перечитывание буфера - простое, но действенное средство, которое может привести к серьезным последствиям.

Для разработчиков чрезвычайно важно реализовать проверки, чтобы убедиться, что программа не считывает и не выводит информацию за пределы выделенного буфера.

И на сегодня все! Спасибо за чтение и увидимся в следующий раз!

📝 Прочтите этот рассказ позже в Журнале.

👩‍💻 Просыпайтесь каждое воскресное утро и слышите самые интересные истории недели в области технологий, ожидающие в вашем почтовом ящике. Прочтите информационный бюллетень« Примечательные в технологиях ».