В ядре Linux обнаружена опасная 0-day уязвимость Dirty COW (CVE-2016-5195)



    В ядре Linux обнаружена опасная уязвимость, которая связана с обработкой подсистемой памяти ядра механизма copy-on-write (COW). Эксплуатируя баг можно спровоцировать так называемое состояние гонки (race condition). При эксплуатации уязвимости неавторизованный локальный пользователь сможет получить доступ к memory mappings с правом записи, хотя доступ должен быть ограничивать только чтением (read-only). Уязвимость относится к privilege escalation.

    Уязвимость была обнаружена в самом ядре Linux и, что немаловажно, присутствует в составе любых дистрибутивов почти десять лет => 2.6.22.
    «Как заметил Линус Торвальдс в своем коммите, этот древний баг живет в ядре уже много лет. Всем пользователям Linux стоит отнестись к проблеме серьезно и установить патч как можно быстрее»

    Уязвимость присвоен CVE-2016-5195, ей подвержены большинство современных дистрибутивов Linux, более того, исследователь (Phil Oester), обнаруживший уязвимость, утверждает что эта уязвимость эксплуатируется злоумышленниками.

    В четверг, 20 октября, один из ключевых разработчиков ядра Linux Грег Кроа-Хартман (Greg Kroah-Hartman) сообщил о выходе обновлений для версий Linux 4.8, 4.7 и 4.4 LTS, исправляющих уязвимость Dirty COW.

    Уязвимость вызвана состоянием гонки при обработке copy-on-write (COW) операций в подсистеме управления памятью и позволяет нарушить работу маппинга памяти в режиме только для чтения. С практической стороны, проблема позволяет осуществить запись в области памяти, отражённые в режиме только для чтения. Например, в прототипе эксплоита показано как использовать данную проблему для изменения содержимого файла, принадлежащего пользователю root и доступного только на чтение. В том числе, при помощи предложенного метода атаки непривилегированный злоумышленник может изменить исполняемые системные файлы, обойдя штатные механизмы управления доступом.

     $ sudo -s
       # echo this is not a test > foo
       # chmod 0404 foo
       $ ls -lah foo
       -r-----r-- 1 root root 19 Oct 20 15:23 foo
       $ cat foo
       this is not a test
    
       $ gcc -lpthread dirtyc0w.c -o dirtyc0w
       $ ./dirtyc0w foo m00000000000000000
       mmap 56123000
       madvise 0
       procselfmem 1800000000
    
       $ cat foo
       m00000000000000000
    

    Для проверки уязвимости доступен Proof-of-Concept эксплоит: клик.
    Support the author
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 51

      –7
      Был 11 лет и никому дела не было… как работало, так и будет работать. Да и область бага как бы ограниченная.
        +1
        но вполне себе опасный момент
          –3
          Таких опасных моментов вагон и маленькая тележка.
          Веб серверу — насрать.
          Файлопомойке — насрать.
          Игровым серверам/серверам стримминга — насрать.

          Вообще всему вебсегменту, где зверьки в клетках и не могут запускать программы вне белого списка — насрать.

          Проболема носит чисто ДОМАШНИЙ характер, то есть та система, где админ юзер сидит и все ставит и ставит и ставит в систему рандомное говно.

          Ей богу развели панику.
          +4
          Ничего себе ограниченная область! Если можно изменить файл, доступный только root — это всё, компьютер уже не Ваш. Такую штуку обернуть в скрипт, обфусцировать, и впаривать в виде решения какой-то распространённой проблемы под линуксом — и спокойно можно поиметь кучу домашних компов под линуксом в своё распоряжение. Остаётся придумать, как заставить пользователя сделать файл исполняемым (без этого он не запустится).

          Интересно, поможет ли от этого флаг -i (immutable)? Ведь с этим флагом даже рут не может редактировать файл, пока не снимет атрибут. Правда, на raiserfs нет поддержки его (разок попалось).
            +8
            > Остаётся придумать, как заставить пользователя сделать файл исполняемым (без этого он не запустится).

            curl | sh

            Я серьёзно, многие сайты предлагают так устанавливать софт.
              0
              Атрибут immutable не канает:
              $ cat foo
              I do it every day!
              $ lsattr foo
              ----i----------- foo
              $ ./dirtyc0w foo «I do what I want!»
              mmap 14922000

              madvise 0

              procselfmem 1700000000
              $ cat foo
              I do what I want!!!
            +18
            С другой стороны, владельцы разнообразных залоченных устройств возрадовались возможности наконец-то их рутануть.
              +5
              Тот случай, когда баг принесет пользу :)
                0
                «Это не баг, это фича» (с)

                В таком случаи — да :)
                0
                На Xperia XA (Linux 3.18.22, 64 битный, SELinux включен) не сработало — телефон перезагрузился, результат выполнения отрицательный. Скомпилировал эксплоит C4Droid`ом, создал файл с правами 0404, натравил бинарник в терминале adb, но телефон ушел в ребут, а содержимое файла осталось прежним. Сразу скажу, что рут права есть на телефоне, но мне было интересно попробовать. Если кто знающий увидит в моих действиях ошибку — подскажите
                –1
                Linux Mint 17.3 — PoC сработал.

                При компиляции пришлось немного поколдовать (я ни разу не разбираюсь в C).
                dirtyc0w.c:96:3: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘void *’ [-Wformat=]
                   printf("mmap %x\n\n",map);

                Тут я просто убрал printf под комментарий, как не самый важный функционал.

                $ gcc -lpthread dirtyc0w.c -o dirtyc0w
                /tmp/ccJWttLa.o: In function `main':
                dirtyc0w.c:(.text+0x1c3): undefined reference to `pthread_create'

                Скомпилировал вот так: gcc -pthread dirtyc0w.c -o dirtyc0w

                После запуска PoC завис, однако файл был успешно перезаписан.
                  +8

                  Директива у printf должна быть p, а не x. Опять кто-то перепутал указатель и число.


                  - printf("mmap %x\n\n",map);
                  + printf("mmap %p\n\n",map);
                    +1
                    Про printf просто предупреждение, можно игнорировать. Ошибка в -lpthread — его надо либо убрать в конец, либо заменить на -pthread.

                    Сработало в убунте 16.04
                      0
                      В debian 8.4 — без проблем: gcc -lpthread dirtyc0w.c -o dirtyc0w
                        +5

                        Обычно флага линкера -lpthread недостаточно для корректной компиляции. -pthread не только линкует libpthread, он ещё и выставляет макрос _REENTRANT, который используется в заголовках libc и меняет поведение стандартной библиотеки (переменная errno становится thread_local переменной, к примеру).
                        Т.е. программа скомпилируется, но может работать неправильно.

                          0
                          В Debian 8.5 аналогично не вызвало проблем. И тоже сработало, так же зависло, но перезаписало.
                    • UFO just landed and posted this here
                        +17

                        Методом пристального взгляда.

                          +4
                          Это со стороны они не очевидны.
                          Но если знаешь как работают эти механизмы, то начинаешь анализировать и всячески ковырять опасные участки. Да, это не «раз два и готово», работа часто нудная. Для этого пишут различные тулзы автоматизирующие этот процес. Тут все зависит от того, на сколько ты хорошо знаешь как работает этот участок. Ну и еще немного везения)
                            +10
                            Когда я занимался постоянным тестированием одной проги для разработки мебели перед тем, как внедрять ее обновления на производство, то я места поиска ошибок в программе понимал еще только читая релиз разрабов: что они добавили и что исправили. Просто исходя из опыта того, как их программисты любят делать и понимания нюансов системы. Самое эпичное было, когда я однотипную ошибку в третий раз нашел именно по принципу, что новый функционал был основан на старом, а в старом они уже дважды так косячили и исправляли.

                            Чем больше понимания работы того или иного механизма в системе и опыта по нахождению косяков программистов, тем больше «чуйка» срабатывает на слабые места. Опять же, уязвимость вроде как эксплуатировали и человек мог целенаправленно искать в нужном направлении.
                            0
                            Интересно, в Windows 10 проблема присутствует?
                              +3
                              А откуда?
                              Там не ядро линуха, а wine наоборот. Прослойка которая системные вызовы приложений транслирует.
                                0
                                Серьёзно? А можно пруф-линк в студию?
                                    0
                                    Не написано там, что ядро линукс внедряют. А всего лишь подсистему линукс в виндоус.
                                      0
                                      Там написано:
                                      На слайде указано, что речь идет именно о полноценной подсистеме Linux, а не о псевдо-эмуляции или виртуальных машинах. Да, Linux становится частью Windows 10 и так же как POSIX и OS/2 будет работать в пользовательском режиме с реализацией семантики системных вызовов на уровне ядра.

                                      Так что никакого «wine наоборот», как указали здесь выше. Поэтому и запросил пруф.
                                        0
                                        А чем UML отличается от «wine наоборот»? Тем что линукс открыт и не приходится переписывать тонну кода и угадывать недокументированные API?
                                          0
                                          Я немного слукавил, wine работает в пространстве пользователя и работает поверх системных вызовов, а в десятке транслятор это модуль самого ядра.
                                          Так что формально я не прав.
                                            0
                                            а в десятке транслятор это модуль самого ядра.

                                            Вроде как подсистема над ядром, на одном уровне с Win32.
                                              0
                                              Спасибо.
                                        +1

                                        Реализован собственный драйвер, реализующий часть системных вызовов, используемых приложениями. Также реализован ряд концепций, необходимых для совместимости с POSIX: VFS с инодами и правами, pipe, и т.п. А также ряд новых потенциальных уязвимостей. При желании можно поизучать содержимое lxss.sys / lxcore.sys и/или почитать подробные логи использования подсистемы (инструкции есть в https://github.com/Microsoft/BashOnWindows/blob/master/CONTRIBUTING.md)


                                        Пруф: BlackHat 2016, ALEX IONESCU (Co-author of Windows Internals 5th and 6th Editions), доклад "THE LINUX KERNEL HIDDEN INSIDE WINDOWS 10"
                                        https://github.com/ionescu007/lxss/blob/master/The%20Linux%20kernel%20hidden%20inside%20windows%2010.pdf


                                        WSL COMPONENT OVERVIEW: Pico Provider driver (LXSS.SYS / LXCORE.SYS) which provides the kernel-mode implementation of a Linux-compatible Kernel ABI and API… implements a virtual file system (VFS) interface, including a device inode
                                        LXCORE.SYS is the large (800KB) kernel-mode Ring 0 driver which implements all the functionality that a Linux application inside of a Pico process will see
                                        • In some cases, functionality is implemented from scratch (such as pipes)
                                        • In other cases, functionality is wrapped on top of an existing NT kernel mechanism or subsystem (scheduling)
                                        • In yet other cases, functionality is heavily built on top of an existing NT kernel primitive, with some from-scratch functionality
                                        SYSTEM CALLS… 216 implemented as of the release build…
                                        VFS / FILE SYSTEM Implements a “VolFs” system, which is the Linux-facing file system with support for UNIX rights, etc.
                                        Provides emulation/wrapping/actual implementation for various virtual file system concepts:
                                        • ProcFs mostly works (calls kernel query APIs as needed) or just already has the data
                                        • TmpFs also exists and implements various devices, including the Binder (key Android IPC from the BeOS days)
                                        • SysFs is there, etc…

                                        В https://github.com/ionescu007/lxss есть различные экспериментальные утилиты по работе с WSL.


                                        Еще линк от авторов WSL и сотрудников MS — https://github.com/benhillishttps://github.com/Microsoft/BashOnWindows/issues/178#issuecomment-249443216


                                        Lxcore.sys is a clean room implementation of the Linux kernel ABI. It contains no code from the Linux kernel and we have a policy that our developers cannot even look at any of the kernel source.

                                        https://github.com/bitcrazedhttp://bitcrazed.com/about/https://github.com/Microsoft/BashOnWindows/issues/107#issuecomment-209147763


                                        The Windows Subsystem for Linux (WSL) doesn't modify or derive any GPL code: It runs native, unmodified ELF binaries by loading them into a lightweight process created by the Windows Kernel, binding the ELF binary's imports to our syscall implementation and then executing as normal. Bash.exe is a simple Windows app that binds a console (i.e. terminal) window to a process that loads and runs the native /bin/bash from the Ubuntu… It was named Bash.exe as a convenience since, in end-user testing, most users expected bash to

                                        Посты от разработчиков WSL про системные вызовы и подсистемы и их трансляцию в запросы к NT ядру — https://blogs.msdn.microsoft.com/wsl/2016/04/22/windows-subsystem-for-linux-overview/ https://blogs.msdn.microsoft.com/wsl/2016/06/08/wsl-system-calls/

                                    0
                                    Статические анализаторы кода, видимо, не особо помогают в выявлении таких ошибок?
                                      0
                                      Статические — нет. Вот динамические (типа ASAN/TSAN) — могут поймать… а могут и не поймать, там нет детерминизма, увы.
                                        0
                                        На самом деле статический анализатор кода может указать на подобную уязвимость. Не понятно как давно эксплуатируется баг, думаю можно самостоятельно устроить проверку каким-нибудь Coverity
                                        +3
                                        А из OpenVZ контейнера с помощью этой Dirty COW можно выскочить?
                                          0

                                          Хороший вопрос. Я лично думаю что нет… Жаль что сейчас протестировать не могу, но если да то OpenVZ/Virtuozzo скажут :)

                                          0
                                          Несет ли опасность уязвимость для веб-серверов, или для этого необходимо иметь возможность запустить исполняемый файл на машине?
                                            +5

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

                                            +1
                                            Есть инструкция для непрограммистов, как пофиксить это уязвимость?
                                              +4
                                              yum update (RHEL/CentOS) или sudo apt-get upgrade (Debian/Ubuntu)
                                                +7
                                                Сделал апдейт к посту.
                                                0
                                                Прошли почти сутки, а патча для RHEL 6 всё ещё нет. Для RHEL 7 и Ubuntu 16.04 прилетели какие-то обновления ядра.
                                                  0

                                                  в интернетах пишут, что на RHEL 6 уязвимость не работает, хотя формально и есть.

                                                    +1
                                                    В коде эксплоита такой комментарий:
                                                    > The in the wild exploit we are aware of doesn't work on Red Hat
                                                    > Enterprise Linux 5 and 6 out of the box because on one side of
                                                    > the race it writes to /proc/self/mem, but /proc/self/mem is not
                                                    > writable on Red Hat Enterprise Linux 5 and 6.
                                                      0
                                                      Стоит отметить, что этот комментарий относится к конкретной реализации сплоита. Вот тут можно найти несколько вариантов, в том числе тот, который не используется /proc/self/mem.
                                                    +2
                                                    «Исходники в свободном доступе же! Над ними долго и упорно работает столько народу, что там попросту не может быть сколь-нибудь серьёзных уязвимостей — это же не дырявая венда»

                                                    Почему-то вспомнилось. К чему бы это…
                                                    • UFO just landed and posted this here
                                                      0
                                                      Судя по всему, вот патч:
                                                      https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619
                                                        0
                                                        Одно хорошо — на Linux машинах, на которые гарантированно логинятся только не-злоумышленники (например, на личных и домашних ПК), эту уязвимость можно эксплуатировать только если спровоцировать пользователя запустить левый бинарник/скрипт, от чего, надеюсь, большинство отучено.

                                                        (Я, правда, не учитываю системные аккаунты вида apache, ftp и т.д.)
                                                          0
                                                          1. на личных машинах для злоумышлеников интересней папка /home
                                                          2. ну а если каким то образом через уязвимсоть в других программах удается выполнять код из под юзера то повысить права до рута через эту уязвимость уже как бонус будет.
                                                            +1
                                                            под винду, знаете ли, то же большая часть локеров запускалась пользователем, которые еще и уак игнорировали.
                                                            пользователи — это главная проблема безопасности…

                                                          Only users with full accounts can post comments. Log in, please.