«Holey beep»: найдена критическая уязвимость в «бипере» Linux

    В beep — стороннем модуле Linux — обнаружена уязвимость, позволяющая запускать побочные эффекты файлов и просматривать их типы, не имея на то соответствующих прав. Расскажем, в чем суть проблемы и как варианты её решения предложило ИТ-сообщество.


    / Flickr / Chris / CC

    Что делает Beep


    Модуль beep формирует звуковые оповещения об ошибках, возникающих при работе в командной строке и в целом позволяет управлять «бипером» ПК. Утилиту создал разработчик Джонатан Найтингейл (Johnathan Nightingale), который хотел получить больше возможностей при работе с консолью, чем позволяла обычная команда printf("\a").

    Суть уязвимости


    Первые новости появились на сайте holeybeep.ninja, который описывает уязвимость в сатирической манере. В The Register полагают, что эта веб-страница — попытка высмеять тех, кто популяризирует баги и создает для них отдельные сайты. Уже позже начали появляться официальные отчеты об ошибках.

    В отчете, опубликованном Debian, отмечено, что Beep выдает сведения о наличии любого файла, даже если он должен быть скрыт от пользователя, который сделал запрос.

    $ ls -ld /etc/hidden/
    drwx------ 2 root root 4096 Apr 7 08:18 /etc/hidden/
    
    $ ls -l /etc/hidden/secret
    ls: cannot access '/etc/hidden/secret': Permission denied
    $ ls -l /etc/hidden/nonexistent
    ls: cannot access '/etc/hidden/nonexistent': Permission denied
    
    $ beep -e /etc/hidden/secret
    ioctl: Inappropriate ioctl for device
    ioctl: Inappropriate ioctl for device
    $ beep -e /etc/hidden/nonexistent
    Could not open /etc/hidden/nonexistent for writing
    open: No such file or directory
    

    При этом система выдает информацию о типе файла, даже если у запрашивающего пользователя нет на это прав (например, сокет может выдать сообщение: «No such device or address»). Этого не должно происходить, если файл лежит в директории, недоступной вызывающему пользователю. Кроме того, с помощью уязвимости злоумышленники могут запускать побочные эффекты и блокировать запуск произвольных программ. Например, запуск beep -s -e /bin/sh приведет к ошибке ETXTBSY («Текстовый файл занят»), что можно назвать DoS-атакой.

    Как отмечают пользователи GitHub, причина уязвимости связана с возникновением гонок при использовании обработчиками сигнала функции free(). Эта функция не входит в список async-signal-safe, то есть не может быть безопасно вызвана внутри обработчика. Работа free() может прерваться другим сигналом, что вызывает нарушение структур данных и глобальных переменных управления кучей.

    Резидент GitHub отмечает, что в последней версии beep.c один обработчик работает сразу с двумя сигналами (SIGINT и SIGTERM). Это позволяет повторно запускать handle_signal () несколько раз подряд, что приводит к двойному высвобождению памяти.


    / Flickr / Tomás Fano / CC

    Патчи и решение проблемы


    Чтобы устранить уязвимость, разработчики некоторых операционных систем (например, Ubuntu) выпустили фикс. Однако, по мнению сообщества, он адресует не все трудности, связанные с Beep. Как отмечают в обсуждении на GitHub, он решает ситуацию с гонками, но проблемы с раскрытием данных остаются.

    По этим причинам, в качестве кардинального решения проблемы, исследователь Ханно Бок (Hanno Böck) предлагает перестать устанавливать Beep как suid. Он также отметил, что модуль Beep в принципе не нужен современным устройствам, так как биперы стоят не во всех компьютерах. В качестве замены Ханно Бок предлагает вернутся к простой и безопасной команде printf("\a"), как это сделали разработчики дистрибутива SUSE.

    Материалы по теме из корпоративного блога 1cloud:

    1cloud.ru
    248,00
    IaaS, VPS, VDS, Частное и публичное облако, SSL
    Поделиться публикацией

    Комментарии 16

      –17
      Еще раз повторю свой комментарий:
      Давно очевидно что на c/c++ невозможно написать софт без уязвимость, используйте rust.


      Раст кстати защищает и от гонок и от использования после освобождения. Жду комментариев, что просто программисты google, Microsoft, apple и другие не захотели написать хороший софт. Только мне кажется, что эти комментаторы даже не представляют как сложно отследить эти уязвимости, это вам не банальное переполнение буфера.
        +15
        Нет, всё гораздно проще: перепишите beep на rust и покажите как вы избежали гонок и прочего. Утилита-то небольшая.

        Если «магический» rust спасёт вас от раскрытия информации без явных проверок — можно будет о чём-то говорить. Если потребуются явные if'ы — то говорить не о чем.

        За выходные справитесь, я надеюсь?
          0
          Я вообще не представляю, как можно было такую важную утилиту делать на таком неизкоуровневом языке. И веб-интерфейс ещё прикрутить.
            –5
            Раст на уровне языка защищает от этих уязвимостей — это его основная фишка. Так, что задача для вас, напишите так, не используя unsafe, чтобы БЫЛИ уязвимости.
              +3

              Он защищает только от гонок при доступе к памяти. Гонки при доступе к файлам никуда не делись.


              Да, вот вам пример с гонкой:


              let p = Path::new("...")
              if p.exists() {
                  File::open(p)
              }
            +9
            Дело не в гонках. Ключ -e указывает устройство, куда выводится сигнал. Чтобы сделать ioctl на этом устройстве, нужны привилегии. Но с привилегиями — мы видим скрытые файлы. А без привилегий — не сможем выполнить основную функцию.

            Таких программ много. Условий для ошибки два:

            1. Программа должна открывать файл, недоступный обычному пользователю.
            2. Имя этого файла должно передаваться через командную строку.
              0
              без уязвимость

              Зависит от человека, котрый писать софт.
                +4
                Rust, может быть, и неплохой язык (хотя вырвиглазый синтаксис сразу бросается в глаза), но больше всего от него отталкивают его упоротые фанаты, которые прибегают в каждый пост, где упоминаются C, C++ или уязвимости в ПО, и начинают сразу твердить всем что нужно срочно перейти на раст и начать писать на нём и только на нём. Вам самим-то не тошно еще?
                  +5

                  Судить о сообществе раста по данному экземпляру — то же, что судить о Си по воплям царя. Мне от таких товарищей, которые стараются агрессивно пропагандировать что угодно тошно вне зависимости от того как я отношусь к конкретной технологии.


                  Загляните в релевантные посты, особенно в англоязычном сегменте: у раста очень приветливое и приятное сообщество. И много выходцев из си и плюсов, что неудивительно.


                  Что же до синтаксиса — это штука вторичная. Если вам не нравится синтез MLного и плюсового синтаксиса — дело ваше. Мне, например, местами не нравится си-подобный синтаксис после языков с выводом типов, где декларация параметров и их типов выполняется в обратном порядке (scala, rust). Но это не повод на них не писать.

                +11
                Еще раз повторю свой комментарий:

                И ещё раз словите минусы, потому что слишком топорно набрасываете

                Давно очевидно что на c/c++ невозможно написать софт без уязвимость

                Программа beep написана на чистом C, зачем вы притягиваете C++, причём тут он вообще?
                Но раз уж притянули: на современном C++ в прикладном коде использование сырых new и delete можно свести к минимуму. Побибикать динамиком — это как раз прикладуха, здесь жонглирование указателями и голой памятью в стиле C неоправдано. Так что переписывание на C++ даст точно такой же эффект, как и переписывание на Rust.

                Жду комментариев, что просто программисты google, Microsoft, apple и другие не захотели написать хороший софт.

                Программа beep написана сторонним разработчиком (Johnathan Nightingale), и даже не устанавливается по умолчанию (по-крайней мере, на Ubuntu). В репозиториях вы и не такое найдете. При чём тут «программисты google, Microsoft, apple» — совершенно неясно.
                  –14
                  Программа beep написана на чистом C, зачем вы притягиваете C++, причём тут он вообще?
                  Но раз уж притянули: на современном C++ в прикладном коде использование сырых new и delete можно свести к минимуму. Побибикать динамиком — это как раз прикладуха, здесь жонглирование указателями и голой памятью в стиле C неоправдано. Так что переписывание на C++ даст точно такой же эффект, как и переписывание на Rust.

                  С каких пор в с++ встроена защита от использования после освобождения и гонки? Вы просто нагло врете и передергиваете факты. На Rust не используя unsave невозможно написать так, чтобы появились эти типы уязвимость. На с++ или даже с можно свести к минимуму, а можно еще было не допускать уязвимости описанной в статье, только вывод, что все зависит от программиста.

                  Программа beep написана сторонним разработчиком (Johnathan Nightingale), и даже не устанавливается по умолчанию (по-крайней мере, на Ubuntu). В репозиториях вы и не такое найдете. При чём тут «программисты google, Microsoft, apple» — совершенно неясно.

                  В google chrome были найдены уязвимости? да
                  в windows? да
                  и так далее, приходим к выводу, что у крупных компаний не получалось это сделать. Видимо нужно нанять вас, вы то им покажете как нужно. Сейчас еще раз вспомним про openbsd, только вопрос кол-во пользователей и интерес хакеров. Вот как будет популярность на уровне хрома, тогда и поговорим. С вашей логикой мое приложение которое я в школе написал лет 12 назад самое безопасное в мире, ни одной уязвимости, а вот если посмотреть на популярный софт, то там сразу программисты какие-то не те.
                    +13
                    С каких пор в с++ встроена защита от использования после освобождения и гонки? Вы просто нагло врете и передергиваете факты.

                    Разговаривать на таких тонах с вами совершенно не имею желания. Если хотите содержательного диалога — потрудитесь указать конкретное место, где я «нагло соврал и передергивал факты». Про «встроенную защиту от use after free» в моём сообщении ничего не было.

                    На Rust не используя unsave невозможно написать так, чтобы появились эти типы уязвимость.

                    А вы сами-то много приложений на Rust написали? Или так, просто потролллить? Не представляю, как практикующий Rust-программист может сделать ошибку в кейворде 'unsafe' :)
                      +1

                      Вы нагло врете передергивая факты говоря практикующий программист не путает save и safe. Нет бога кроме Rust и interprise пророк его, а c++ это язычничество.

                  0
                  В модуле beep операционной системы Linux

                  Это сторонняя утилита для GNU/Linux, коих десятки тысяч, как минимум. Вы б хоть какого-нибудь технического специалиста подпускали к статьям перед публикацией, то такие ошибки глаз режут.

                    0
                    Именно так. Как тот бедный вирус из анекдота, сначала его от рута поставь…

                    $ beep
                    bash: beep: command not found


                      –1

                      Но нашлись обиженные страдальцы, считающие стороннюю утилиту — "модулем ОС Linux". Не говоря уже о том, что linux — это ядро, а не ОС.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.