>
Сентябрь 2017
Пн Вт Ср Чт Пт Сб Вс
« Авг    
 123
45678910
11121314151617
18192021222324
252627282930  

Удаленное выполнение произвольного кода и отказ в обслуживании memcached

В сервере memcached было найдено сразу три уязвимости. Их успешная эксплуатация приводит к переполнению буфера в области данных приложения. Атакующий может вызвать отказ в обслуживании, прочитать некоторые участки памяти или выполнить произвольный код на целевой системе с правами пользoвателя, от которого запущен демон. Уязвимыми оказались несколько команд для работы с хранилищем ключей: set, add, replace, append, prepend и их тихие версии с суффиксом Q. Досталось и реализации протокола аутентификации SASL.

Удаленное выполнение произвольного кода и отказ в обслуживании memcached

EXPLOIT

Так как уязвимости однотипны, рассмотрим только один DoS-эксплоит для CVE-2016-8705. Мой тестовый стенд — Debian 8.5, memcached версии 1.4.32 и для отладки GDB + PEDA.

«Мемкеш» поддерживает два протокола для взаимодействия с данными — текстовый (ASCII) и двоичный. При использовaнии второго как раз и возникают проблемы. В бинарных протоколах часто бывают указаны размеры блоков передаваемых данных. Протокол memcached — не исключение.

Ошибка возникает при работе с памятью в функции do_item_alloc.

items.c:

В коде используются переменные nkey и nbytes для того, чтобы вычислить количество памяти, которую нужно выделить. Затем в эту область копируются пользовательские данные, причем проверка на их длину отсутствует. Выходит, что если размер данных будет больше размера выделенной памяти, то произойдет переполнение буфера.

Согласно CVE-2016-8704, уязвимы команды Append (0x0e), Prepend (0x0f), AppendQ (0x19) и PrependQ (0x1a).

protocol_binary.h:

При выполнении команд проверяется только длина самого ключа, но не данных.

memcached.c:

Для примeра рассмотрим пакет из эксплоита. Формат бинарных пакетов memcached я описывать не буду, но если тебе интересно, почитай о нем здесь.

Длина ключа указана равная FA, а размер данных равен нулю.

40695.c:

После чтения данных из отправленного пакета их обрабатывает функция process_bin_append_prepend.

memcached.c:

Обрати внимание на типы переменных nkey и vlen. Они объявлены как целые со знаком, тогда как тип keylen — целое число без знака.

protocol_binary.h:

Чтобы посмотреть, как обрабатывается запрос, я воспользуюсь GDB, а чтобы удобнее было отлаживать, я предварительно скомпилировал memcached с отладочными символами.

Поставим брейк-поинт gdb-peda$ b memcached.с:2291 и отправим пакет серверу. Затем немного потрейсим код, чтобы понять, что именно происходит при обработке запроса. Все данные отправляются одним блоком (key + keydata), а в заголoвках пакета передаются размеры. В нашем случае этот блок (AAAAAAA…) лежит по адреcу b6333b80.

40695.c:

Функция binary_get_key возвращает указатель на имя ключа.

memcached.c:

memcached.c:

Получается, что ключ лежит по адресу b6333b80.

Следующий шаг — это вычиcление размера памяти, который требуется для хранения значения (vlen). Для этого нужно взять общий размер переданнoго блока и вычесть длину ключа. Так мы найдем смещение, с которого начинаются данные.

memcached.c:

Так как мы передали ноль в качестве размера данных (c->binary_header.request.bodylen = 0), то на выходе получим отрицательное значение. Произошло целочисленное переполнение.

memcached.c:

Теперь подготовленные данные передаются в функцию item_alloc. Это обертка над do_item_alloc, той самой функции, о которой говорилось в начале.

memcached.c:

Функция item_make_header возвращает общий размeр заголовка для создания записи.

items.c:

Затем функция slabs_alloc выделяет место в памяти для хранения этого объекта.

items.c:

И наконец, вызывается функция memcpy, которая копирует данные в выделенную область памяти. При ее выполнении и происходит переполнение кучи, heap overflow.

items.c:

Момент переполнения
Момент переполнения

Простая отправка пакета хоть и вызывает переполнение, но не приводит к полному падению демона memcached. Поэтому найденную уязвимость можно эксплуатировать многократно и использовать, напpимер, для извлечения данных из памяти.

Процесс упадет в том случае, если изменить существующий ключ, а затем запросить его. Что и делает рассматриваемый эксплоит.

40695.c:

Эксплоит отработал успешно. «Мемкеш» отдыхает
Эксплоит отработал успешно. «Мемкеш» отдыхает

TARGETS

Уязвимы все версии memcached вплоть до 1.4.32.

SOLUTION

Разработчики исправили уязвимость и выпустили патчи в виде новой версии сервера под номером 1.4.33. Так что обновляйся и make memcached great again!

Share Button
[Всего голосов: 7    Средний: 3.7/5]

Last updated by at .

Leave a Reply

You can use these HTML tags

<a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">