В 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 / Tomas Fano / CC

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


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

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

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

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


  1. interprise
    12.04.2018 20:39
    -1

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

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


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


    1. khim
      13.04.2018 00:22
      +3

      Нет, всё гораздно проще: перепишите beep на rust и покажите как вы избежали гонок и прочего. Утилита-то небольшая.

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

      За выходные справитесь, я надеюсь?


      1. Barafu
        13.04.2018 01:03

        Я вообще не представляю, как можно было такую важную утилиту делать на таком неизкоуровневом языке. И веб-интерфейс ещё прикрутить.


      1. interprise
        13.04.2018 10:09

        Раст на уровне языка защищает от этих уязвимостей — это его основная фишка. Так, что задача для вас, напишите так, не используя unsafe, чтобы БЫЛИ уязвимости.


        1. mayorovp
          13.04.2018 13:34
          +3

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


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


          let p = Path::new("...")
          if p.exists() {
              File::open(p)
          }


    1. Jef239
      13.04.2018 01:00

      Дело не в гонках. Ключ -e указывает устройство, куда выводится сигнал. Чтобы сделать ioctl на этом устройстве, нужны привилегии. Но с привилегиями — мы видим скрытые файлы. А без привилегий — не сможем выполнить основную функцию.

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

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


    1. velovich
      13.04.2018 11:09

      без уязвимость

      Зависит от человека, котрый писать софт.


    1. F0iL
      13.04.2018 13:40
      +2

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


      1. grossws
        13.04.2018 14:14

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


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


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


  1. KennyGin
    12.04.2018 21:15
    +2

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

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

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

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

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

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


    1. interprise
      12.04.2018 21:31

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

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

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

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


      1. KennyGin
        12.04.2018 21:48

        С каких пор в с++ встроена защита от использования после освобождения и гонки? Вы просто нагло врете и передергиваете факты.

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

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

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


        1. Nikita001
          13.04.2018 16:56

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


  1. grossws
    13.04.2018 01:26

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

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


    1. Cenzo
      13.04.2018 01:52

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

      $ beep
      bash: beep: command not found



      1. grossws
        13.04.2018 14:15

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