The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Пример анализа потенциально серьезной уязвимости в OpenSSH

02.08.2011 13:15

В списке рассылки Full Disclosure опубликован разбор достаточно интересной уязвимости в OpenSSH, найденной в реализации алгоритма аутентификации через вызов модулей GSSAPI. Сама по себе уязвимости малопригодна для осуществления атаки, так как может быть использована для осуществления DoS-атаки (исчерпание доступной процессу памяти) на стадии после совершения аутентификации, т.е. эксплуатировать проблему можно только имея работающий аккаунт в системе. Тем не менее интерес вызывает то, что несмотря на проявление проблемы в большинстве современных Linux-дистрибутивов, которые используют метод аутентификации "gssapi-with-mic", ошибка была найдена еще в 2008 году и обнародована только сейчас.

По словам нашедшего ошибку исследователя, проблема была так долго не обнародована так как было предположение, что ошибку можно использовать на стадии до совершения аутентификации, т.е. оставалась надежда на возможность эксплуатации без наличия рабочего аккаунта. После детального изучения вопроса был сделан вывод, что проблема проявляется только после выполнения стадии аутентификации, что сводит на нет опасность уязвимости. Исследователь отмечает, что если бы в связанном с GSSAPI коде OpenSSH было на один вызов меньше, то уязвимость можно было использовать до начала аутентификации.

Суть проблемы сводится к возможности организации передачи произвольного значения аргумента при вызове функции xmalloc(), осуществляющей выделение памяти. Передав заведомо большое значение можно запросить большой блок памяти, ограниченный выставленным для процесса лимитом. Выполнив параллельно несколько подобных атак на одном сервере можно добиться исчерпания свободной памяти в системе.

  1. Главная ссылка к новости (http://seclists.org/fulldisclo...)
  2. OpenNews: Для OpenSSH реализована поддержка дополнительной изоляции
  3. OpenNews: Во FreeBSD 4.x с включенным сервисом SSH найдена удаленная root-уязвимость
  4. OpenNews: Вышло обновление OpenSSH 5.8 с исправлением недоработки, связанной с безопасностью
  5. OpenNews: Неподтвержденная информация о наличии критической уязвимости в OpenSSH (дополнено)
  6. OpenNews: US-CERT предупреждает об атаке на Linux системы с использованием SSH ключей
Лицензия: CC-BY
Тип: Проблемы безопасности
Ключевые слова: openssh, security
При перепечатке указание ссылки на opennet.ru обязательно
Обсуждение (24) Ajax | 1 уровень | Линейный | Раскрыть всё | RSS
  • 1.1, anonymous (??), 13:47, 02/08/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А разве нельзя установить квоты на максимальный размер выделяемой памяти для sshd?
     
     
  • 2.2, codejumper (?), 13:56, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    если ограничивать на каждый процесс, то их можно ещё кучу наплодить
    если по сумме, то легальные пользователи не смогут заходить, т.ч. также получаем dos
     
     
  • 3.4, Аноним (-), 16:48, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Вообще-то достаточно ограничить пользователя и всё. Если уязвимость требует наличия аккаунта, значит sshd уже сделал setuid и работает из-под пользователя - итого никакой опасности и в логах сразу будет видно кто шалит.
     

  • 1.3, Аноним (-), 16:45, 02/08/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Большими malloc'ами нельзя исчерпать свободную память в системе, потому что при malloc'е физические страницы не выделяются - делается банальный анонимный mmap. Либо переводчик лажанул и там было что-нибудь про заполнение этой памяти, либо это уязвимость - чушь на постном масле, либо работает только на редких системах с ущербной виртуальной памятью.
     
     
  • 2.5, Аноним (-), 17:38, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > Большими malloc'ами нельзя исчерпать свободную память в системе, потому что при malloc'е
    > физические страницы не выделяются - делается банальный анонимный mmap.

    Вы бы вначале на код посмотрели, прежде чем критиковать. OpenSSH сразу забивает содержимое буфера перед использованием, что и приводит к физическому выделению страниц:

    name->value = xmalloc(name->length+1);
    memcpy(name->value, tok+offset, name->length);

     
     
  • 3.6, pro100master (ok), 18:49, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    рискую быть неправым, но разве в современных менеджерах не copy-on-write схема? Где копирование физически происходит только при изменении исходных данных? Память она такая - сейчас самая дорогая операция, глупо писать бит при пенальти в 50-200 тактов.
     
     
  • 4.8, Аноним (-), 19:13, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > рискую быть неправым, но разве в современных менеджерах не copy-on-write схема?

    При чём тут cow? Если вы думаете что процессор через libastral определяет что содержимое страниц идентично и шарит страницы вместо копирования, то это бред.

     
     
  • 5.9, pro100master (ok), 19:17, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Ни процессор, ни процесс тут совершенно не причем. Это забота MM. Он как раз всё про всех знает. Причем, он еще и тем самым астралом планирует выделения/освобождения на основе своей статистики.
     
     
  • 6.10, Аноним (-), 19:20, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > Ни процессор, ни процесс тут совершенно не причем. Это забота MM. Он как раз всё про всех знает. Причем, он еще и тем самым астралом планирует выделения/освобождения на основе своей статистики

    Лол.

     
     
  • 7.11, pro100master (ok), 19:35, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    понятно, работа менеджера памяти ядра недоступна до понимания...
     
     
  • 8.12, Аноним (-), 21:22, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Вполне доступна, если захотите разберётесь Начните с осознания того, что менедж... текст свёрнут, показать
     
     
  • 9.13, pro100master (ok), 00:21, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    вот это точно лол ... текст свёрнут, показать
     
     
  • 10.14, Сергей (??), 02:26, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • +1 +/
    А что лол-то Это чистая правда ... текст свёрнут, показать
     
     
  • 11.18, ананим (?), 12:28, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    угу как и я к примеру пишу файлы на винт из юзер-спейсной проги это магия... текст свёрнут, показать
     
  • 10.15, Аноним (-), 05:05, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Начали нормально с рискую быть неправым , а закончили пятой точкой глубоко в лу... текст свёрнут, показать
     
  • 4.16, Andrew Kolchoogin (?), 10:22, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    Нет. Аллокатор всегда выделяет страницы сразу.

    Функция malloc() возвращает либо указатель на область ОЗУ, либо NULL, если выделение ОЗУ по каким-либо причинам не удалось. Если выделять ОЗУ фиктивно, тогда от момента вызова malloc() до момента записи в выделенную область ОЗУ вполне может выполниться несколько malloc()'ов других процессов (напоминаю: UNIX -- система многозадачная), и когда фиктивное выделение придётся сделать физическим, ОЗУ может просто закончиться.

    Что тогда? SIGKILL "Out of swap space"? Это неправильно. Противоречит семантике работы malloc(). Если ОЗУ нет -- возвратите NULL и не полируйте моск. Если возвратили указатель -- отдайте моё ОЗУ мне.

     
     
  • 5.17, Михаил (??), 11:26, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    >Если ОЗУ нет - возвратите NULL и не полируйте моск. Если возвратили указатель - отдайте моё ОЗУ мне.

    echo "vm.overcommit_memory = 2" >> /etc/sysctl.conf

     
     
  • 6.19, Andrew Kolchoogin (?), 17:51, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    ===
    {3} user@host:~ $ sysctl -a | grep overcommit_memory | wc -l
           0
    ===

    sysctl сами придумали?-)

     
     
  • 7.24, Аноним (24), 17:46, 04/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    sudo sysctl -a | grep overcommit_memory | wc -l
    1
     
  • 6.23, Andrew Kolchoogin (?), 23:48, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • –1 +/
    Тщательный анализ grep'ом по исходникам ядра показал, что слово 'overcommit' встречается в vm/swap_pager.c, но отвечает только за возможность выделения ФИЗИЧЕСКОГО ОЗУ для процесса в количестве, большем, чем есть СВОБОДНОГО СВОПА.
    Такая ситуация возможна, если в системе размер ОЗУ больше размера свопа, но для FreeBSD такие настройки нехарактерны -- Handbook рекомендует иметь свопа больше, чем физического ОЗУ.
    Впрочем, доки на Солярис говорят, что лучше наоборот, но там и sysctl такого нет. :)
     
  • 5.20, Аноним (-), 21:47, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • +1 +/
    > Нет. Аллокатор всегда выделяет страницы сразу.

    Вы уже не раз показали себя ламером, может пора научиться хотя-бы проверять, прежде чем говорить о том, о чём понятия не имеете? Сделайте программу, malloc(); system("ps"); memset(); system("ps"); и посмотрите что будет с VM и RSS.

    > Что тогда? SIGKILL "Out of swap space"?

    Именно, и это правильно.

    > Противоречит семантике работы malloc()

    OOM killer не имеет никакого отношения к семантике работы malloc, и избежать его всё равно нельзя из-за фундаментальных принципов работы системы виртуальной памяти. Кроме того, выделение физических страниц на аллокации - это кошмарное падение производительности, рост потребления памяти,  невозможность выделить фрагмент больше размера физической памяти.

    Почему нельзя избежать OOM - показываю на примере: процесс выделил много памяти, допустим даже честно выделил физические страницы, далее он форкается. Либо вы честно копируете всё адресное пространство (а с такой системой вы никому не нужны), либо одна из копий будет убита при записи в память, когда при cow кончатся физические страницы.
    Другой пример - процесс выделил память-ok, был вытеснен в swap и весь его занял. Другой процесс выделил память-ok, и занял всё физическую. Когда проснётся первый процесс и полезет из swap'а, он будет прибит безо всяких malloc по причине исчерпания физических страниц.

    Итого - на деле malloc вернёт 0 скорее всего только в одном случае - при исчерпании адресного пространства (т.е. невозможности сделать анонимный mmap). Во всех остальных случаях процесс будет убит по OOM, это полностью ожидаемое и корректное поведение.

     
     
  • 6.21, Andrew Kolchoogin (?), 23:02, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • –1 +/
    Я бы порекомендовал вам перед тем, как говорить о личности собеседника, научитьс... текст свёрнут, показать
     
  • 6.22, Andrew Kolchoogin (?), 23:19, 03/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > Итого - на деле malloc вернёт 0 скорее всего только в одном
    > случае - при исчерпании адресного пространства (т.е. невозможности сделать анонимный mmap).
    > Во всех остальных случаях процесс будет убит по OOM, это полностью
    > ожидаемое и корректное поведение.

    По уточнённым данным:

    ===
    {40} user@host:/usr/src/lib/libc $ cc -I /usr/src/lib/libc/include -E stdlib/malloc.c | grep -v "^#" | grep '= mmap'|wc -l
           1
    {41} user@host:/usr/src/lib/libc $ cc -I /usr/src/lib/libc/include -E stdlib/malloc.c | grep -v "^#" | grep 'return (0)' | wc -l
          16
    ===

    Итого, случаев возврата NULL'ей в malloc() ровно в 16 раз больше случаев вызова mmap().

     
  • 3.7, Аноним (-), 19:11, 02/08/2011 [^] [^^] [^^^] [ответить]  
  • +/
    > Вы бы вначале на код посмотрели

    Я, по-моему, всё ясно написал:

    > Либо переводчик лажанул и там было что-нибудь про заполнение этой памяти

     
     Добавить комментарий
    Имя:
    E-Mail:
    Текст:



    Спонсоры:
    Слёрм
    Inferno Solutions
    Hosting by Ihor
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2019 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру