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

Технические детали Проблема возникает при многочисленном одновременном вызове системной функции madvise(MADV_DONTNEED) и записи в страницу памяти, к которой пользователь не имеет доступа на изменениеKernel Local Privilege Escalation — CVE-2016-5195 / Redhat. Эти вызовы осуществляются из разных потоков одновременно.

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

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

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

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

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

Эксплуатацию уязвимости обнаружил исследователь безопасности Phil Oester при анализе взлома одного из администрируемых им серверов. Благодаря записи всего HTTP-трафика на протяжении нескольких лет ему удалось получить эксплойт и проанализировать его работу. Эксплойт был скомпилирован компилятором GCC версии 4.8 (вышел в 2013 году), что может свидетельствовать о том, что уязвимость успешно эксплуатируется уже на протяжении нескольких лет. Закрытое обсуждение и подготовка исправления произошли 13 октября 2016 года. 18 октября был внесен патч, исправляющий ошибку; однако при этом Линус не указал, что данное исправление является важным и устраняет уязвимость. Подобное сокрытие важной информации и проблемы в раскрытии уязвимостей лишь усложняют жизнь пользователей и дистрибьюторов, эта практика подверглась критике в LWNDirty COW and clean commit messages / LWN, Jonathan Corbet, October 21, 2016. 19-20 октября информация об уязвимости была опубликована RedHat; также был запущен специальный сайт, рассказывающий об уязвимости и предлагающий различные эксплойты, twitter-аккаунт и интернет-магазин по продаже футболок и сувениров с логотипом уязвимости.

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

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

Примечания

Ссылки CVE-2016-5195 / Redhat CVE-2016-5195 в базе MITRE: «Race condition in mm/gup.c in the Linux kernel 2.x through 4.x before 4.8.3» Kernel Local Privilege Escalation — CVE-2016-5195 / Redhat Dirty COW and clean commit messages / LWN, Jonathan Corbet, October 21, 2016 VulnerabilityDetails / Dirtycow, github Сайт об уязвимости Логотип уязвимости для печати на одежде и кружках.

Категория:Linux Категория:Ошибки программирования Категория:Уязвимости защиты Категория:Атаки и эксплойты