Уязвимость Dirty COW

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

Уязвимость Dirty COW (CVE-2016-5195, от англ. dirty + copy-on-write — копирование при записи) — серьезная программная уязвимость в ядре Linux, существующая с 2007 года и исправленная в октябре 2016 года. С её помощью локальный пользователь может повысить свои привилегии из-за ошибки состязания (гонки) в реализации механизма копирования при записи (COW) для страниц памяти, помеченных флагом Dirty bit (изменённая память).[1][2][3] На октябрь 2016 года сообщается об активной эксплуатации уязвимости при взломах серверов.[3]

Технические детали[править | править код]

Проблема возникает при многочисленном одновременном вызове системной функции madvise(MADV_DONTNEED) и записи в страницу памяти, к которой пользователь не имеет доступа на изменение[4]. Эти вызовы осуществляются из разных потоков одновременно.

При попытке записи в read-only COW страницу памяти ядро автоматически создаёт её копию, после чего записывает данные в новую копию. Исходная страница памяти при этом остаётся нетронутой. Код уязвимого ядра Linux не проверял, завершено ли создание копии и существует ли она все ещё, прежде чем начать запись по запрашиваемому адресу памяти. Поскольку это две последующие инструкции, считалось маловероятным, что что-либо может «вклиниться» между ними.

Для использования эксплойта создаются два потока A и B. Системный вызов madvise(MADV_DONTNEED) в потоке A сообщает ядру о том, что программа больше никогда не собирается использовать указанную страницу памяти, поэтому ядро сразу же удаляет все копии этой страницы (но не лишает доступа к ней по прежнему адресу!). Запись в эту же страницу из потока B приводит к необходимости заново создавать её копию. При одновременном выполнении описанных выше инструкций с очень малой вероятностью может произойти ситуация, когда копия страницы удаляется сразу же после её создания, но перед операцией записи. В этот неблагоприятный момент ядро запишет данные в исходную read-only страницу памяти, а не в её копию. При многочисленном повторении запросов из разных потоков происходит гонка и маловероятное событие обязательно произойдёт, в результате чего эксплойт получает право на изменение исходной read-only страницы. Обычно процесс занимает не более нескольких секунд[5].

Необходимым условием для использования уязвимости является доступ на чтение к файлу или участку памяти. Это означает, что локальный пользователь не может напрямую перезаписать системные файлы, которые не доступны для чтения, как например /etc/shadow, что позволило бы сменить пароль суперпользователя. Однако уязвимость позволяет записать произвольный код в любой исполняемый файл, в том числе любой suid-файл. Таким образом, пользователь получает возможность «подменить» системные файлы, запускаемые им от имени root. Например, становится возможным заменить «безобидный» suid-файл ping на системный терминал, который запустится от имени root.

Несмотря на то, что ошибка повышения привилегий реализуется для локальных пользователей, удаленные злоумышленники могут использовать её в сочетании с другими эксплойтами, которые позволяют произвести удаленное выполнение непривилегированного кода. Такое сочетание приведет к полному взлому удаленной системы.[2] Использование уязвимости DirtyCOW само по себе не оставляет следов в системных журналах.[3][1]

История[править | править код]

Уязвимость получила обозначение CVE CVE-2016-5195, предварительно оценивается по шкале CVSS на 6.9-7.8 баллов из 10.[6] Ошибка присутствует в ядре с 2007 года (версия 2.6.22)[1] и может быть использована на большом числе дистрибутивов, в том числе на Android[7]. Эта уязвимость стала самой длительно существовавшей критической ошибкой в ядре Linux[8]. Лишь в единичных дистрибутивах (RHEL5/6) эксплуатация одного из стандартных эксплоитов невозможна из-за отключения интерфейса «proc mem»[9]. Линус Торвальдс признался, что уже делал попытки исправления этой гонки в августе 2005 года, однако этот патч был некачественным и почти сразу был отменён из-за проблем на архитектуре S390[10].

Эксплуатацию уязвимости обнаружил исследователь безопасности Phil Oester при анализе взлома одного из администрируемых им серверов. Благодаря записи всего HTTP-трафика на протяжении нескольких лет, ему удалось получить эксплоит и проанализировать его работу. Эксплоит был скомпилирован компилятором GCC версии 4.8 (вышел в 2013 году), что может свидетельствовать о том, что уязвимость успешно эксплуатируется уже на протяжении нескольких лет. Закрытое обсуждение и подготовка исправления произошли 13 октября 2016 года[11][12]. 18 октября был внесен патч, исправляющий ошибку; однако при этом Линус не указал, что данное исправление является важным и устраняет уязвимость. Подобное сокрытие важной информации и проблемы в раскрытии уязвимостей лишь усложняют жизнь пользователей и дистрибьюторов, эта практика подверглась критике в LWN[13]. 19-20 октября информация об уязвимости была опубликована RedHat; также был запущен специальный сайт[11], рассказывающий об уязвимости и предлагающий различные эксплоиты, twitter-аккаунт и интернет-магазин по продаже футболок и сувениров с логотипом уязвимости.

Исправление уязвимости требует обновления ядра. Уязвимость была исправлена в ядрах версий 4.8, 4.7, 4.4 и других[14], исправление представляет собой добавление нового флага FOLL_COW (изменены 7 строк кода)[10]. Ряд дистрибутивов GNU/Linux, например, Debian, Ubuntu, RedHat и другие, уже объявили о выпуске исправленных пакетов ядра.[15] В то же время, существуют многочисленные уязвимые устройства и системы на кристалле, выпуск обновлений для которых закончен производителем и может быть невозможен сторонними лицами из-за проприетарных дополнений и нарушений GPL. Например, уязвимость может использоваться для получения прав суперпользователя практически на всех Android-устройствах,[16][17] с версией ОС до Android 6 включительно[18] и с ранними версиями Android 7.

В декабре 2017 был представлен вариант «Huge Dirty COW» (CVE-2017-1000405), связанный с аналогичной ошибкой в обработке больших страниц (2 МБ)[19].

Примечания[править | править код]

  1. 1 2 3 В ядре Linux устранена 0-day уязвимость Dirty COW, уже взятая на вооружение хакерами, xakep.ru (21 октября 2016). Дата обращения 22 октября 2016.
  2. 1 2 Goodin, Dan. "Most serious" Linux privilege-escalation bug ever is under active exploit (updated) (англ.), Ars Technica (20 October 2016). Дата обращения 21 октября 2016.
  3. 1 2 3 Vaughan-Nichols, Steven J. The Dirty Cow Linux bug: A silly name for a serious problem. Дата обращения 21 октября 2016.
  4. Kernel Local Privilege Escalation — CVE-2016-5195 / Redhat
  5. Dirty COW explained: Get a moooo-ve on and patch Linux root hole, The Register (21 Oct 2016). Дата обращения 22 октября 2016.
  6. Kernel Local Privilege Escalation - CVE-2016-5195 - Red Hat Customer Portal. Дата обращения 21 октября 2016.
  7. Alex Hern. 'Dirty Cow' Linux vulnerability found after nine years (англ.), The Guardian (21 October 2016). Дата обращения 23 октября 2016.
  8. Security bug lifetime. CVE-2016-5195 (англ.). Kees Cook (10/20/2016). Дата обращения 23 октября 2016.
  9. Bug 1384344 — CVE-2016-5195 kernel: mm: privilege escalation via MAP_PRIVATE COW breakage / RedHat: «The in the wild exploit ..doesn’t work on Red Hat Enterprise Linux 5 and 6 … proc/self/mem is not writable on Red Hat Enterprise Linux 5 and 6.»
  10. 1 2 Linus Torvalds. mm: remove gup_flags FOLL_WRITE games from __get_user_pages() (англ.). 19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619. Kernel.org GIT (18 October 2016). Дата обращения 22 октября 2016.
  11. 1 2 Graeme Burton. Linux users urged to protect against 'Dirty COW' security flaw. All Linux users should take this seriously, says security expert (англ.), V3 (20 October 2016). Дата обращения 23 октября 2016.
  12. oss-security — CVE-2016-5195 «Dirty COW» Linux kernel privilege escalation vulnerability
  13. Dirty COW and clean commit messages / LWN, Jonathan Corbet, October 21, 2016 (англ.)
  14. В ядре Linux исправлена самая серьезная уязвимость повышения привилегий, securitylab.ru (21 Октября 2016). Дата обращения 22 октября 2016.
  15. CVE-2016-5195. Дата обращения 21 октября 2016.
  16. Android phones rooted by “most serious” Linux escalation bug ever (англ.), Ars Technica (October 24, 2016).
  17. Every Android device potentially vulnerable to «most serious» Linux escalation attack, ever / Boing Boing
  18. Dirty COW затрагивает не только Linux, но и все версии Android
  19. Tom Spring. Flaw Found In Dirty COW Patch. threat post (December 1, 2017). Дата обращения 18 декабря 2017. (en)

Ссылки[править | править код]