Как врапперы php могут быть использованы для атаки на веб-приложения

Преобразование значений при изменении свойств

Валидация значений текстовых полей — постоянная головная боль разработчиков приложений. Существует очень много вещей, которые нужно отслеживать: от банальностей типа кодировки до злонамеренных попыток ввести код через текстовое поле. Рассмотрим применение обёртки свойства для удаления пробелов, которые ввёл пользователь в начале и в конце строки.

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

Ограничения

Свойства не могут генерировать исключения

Как уже было сказано, обёртки свойств могут использовать лишь несколько методов обработки недопустимых значений:

  • игнорировать их;
  • завершить работу приложения при помощи fatalError().

Ограничение на использование композиции из нескольких обёрток свойств

Композиция обёрток свойств — не коммутативная операция: на поведение будет влиять порядок объявления. Рассмотрим пример, в котором свойство slug, представляющее собой url поста в блоге, нормализуется. В этом случае результат нормализации будет различаться в зависимости от того, когда пробелы будут заменены тире, до или после удаления пробелов. Поэтому на данный момент композиция из нескольких обёрток свойств не поддерживается.

Однако это ограничение можно обойти, если использовать вложенные обёртки свойств.

Другие ограничения обёрток свойств

  • Нельзя использовать внутри протокола.
  • Экземпляр свойства с обёрткой не может быть объявлен в .
  • Свойство с обёрткой, объявленное внутри класса, не может быть переопределено другим свойством.
  • Свойство с обёрткой не может быть , , , или .
  • Свойство с обёрткой  должно быть единственным в рамках своего определения (т.е. нельзя ).
  • У свойства с обёрткой  нельзя определить и .
  • Типы у свойства и у переменной в должны иметь тот же уровень доступа, что и тип обёртки свойства.
  • Тип свойство должен иметь тот же уровень доступа, что и тип обёртки свойства.
  • должен иметь тот же уровень доступа, что и тип обёртки свойства.

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

Тег против дополнительного

Следует отметить, что в качестве обёртки иногда может подойти . Вот такая реализация отлично работает:

body {
  margin-right: auto;
  margin-left:  auto;
  max-width: 960px;
  padding-right: 10px;
  padding-left:  10px;
}

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

Однако, лучше этого не делать ради гибкости и устойчивости к изменениям. Представьте любой из этих сценариев на поздней стадии проекта:

Лично я склоняюсь к тому, что для реализации обёртки всё же лучше использовать дополнительный . Таким образом, если требования спецификации позже изменятся, то потом не придётся добавлять обёртку и переписывать стили. В конце концов, речь же об одном-единственном добавочном DOM-элементе.

width против max-width

После установки ширины блочному элементу он больше не сможет растягиваться на всю ширину своего контейнера (полезно для комфортной длины строк). Следовательно, элемент-обёртка займёт указанную ширину. Но если окно браузера Уже указанной ширины обёртки, то появится нежелательный горизонтальный скролл.

Поэтому для окон поуже лучше использовать

Это важно при оптимизации сайтов под мобильные устройства с маленьким экраном. Вот неплохой пример, который демонстрирует эту проблему

See the Pen CSS-Tricks: The Best Way to Implement a CSS Wrapper by Максим (@psywalker) on CodePen.

С точки зрения отзывчивости лучший выбор!

Настройки модуля

Для настроек модуля Joomla Обёртка (Wrapper) ссылка на размещаемый документ или сайт. Для примера я покажу другой сайт. В настройках модуля четыре вкладки:

  • Модуль;
  • Привязка к пунктам меню;
  • Доп. Настройки;
  • Права.

Модуль

Настройки модуля на вкладке «Модуль» — базовые. В левой части страницы вы должны, обязательно, указать: ссылку документа. Остальные настройки заполняются по желанию.

Авто доб. Если ваша ссылка незащищена (http), то её указывать не нужно и настройку авто доб. ставим в «Да». Если размещаемая ссылка защищена (https), то в этой настройке оставляем настройку по умолчанию «Нет», а саму ссылку пишем с протоколом https.

Размеры IFrame окна заполняются по вашему усмотрению. По умолчанию 100% (ширина) высота 200 px. Для модуля это нормально, а если будете вставлять модуль в статью, возможно маловато по высоте.

Если хотите, чтобы ссылка открывалась в новом окне в настройке «Target» пишем IFrame-a.

Важно! Используя настройку «Target», помните, что некоторые браузеры заблокируют переход с незащищенного сайта, на защищённый сайт (документ) в новом окне. Если настройку «Target» не ставить, документ (сайт) будет листаться в пределах IFrame окна на вашем сайте

В правой части экрана:

  • Показываем или срываем название модуля (оно обязательно);
  • Указываем позицию модуля в рабочем шаблоне;
  • Публикуем или сохраняем черновик модуля, меняя его состояние в настройке «Состояние»;
  • Если нужно отсрочить публикацию модуля выставляем настройки «Начало публикации» и «Завершение публикации»;
  • Настройкой доступа вы можете ограничить доступ пользователей к просмотру модуля различным группам пользователей;
  • Порядок модуля укажет расположение модуля в выбранной позиции;
  • Примечание нужно для административной памяти, оно будет показано в списке модулей административной панели.

Привязка к пунктам меню

Здесь вам нужно выбрать пункты меню, где этот модуль будет показан. Если такого выбора не нужно, ставим показывать на всех страницах.

Эти настройки внешнего вида данного модуля. Если не используете свои стили, то оставляем настройки по умолчанию.

Права

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

Wrapper’ы

В PHP есть такое понятие, как потоки (Streams), которые появились в интерпретаторе начиная с версии 4.3.0. Это абстрактный слой для работы с файлами, сетью, сжатыми данными и другими ресурсами, использующими единый набор функций. В простейшем определении, поток — это ресурс, имеющий «потокообразное» поведение. То есть ресурс, из которого можно читать, в который можно писать и внутри которого можно перемещаться. Для примера рассмотрим функцию fopen. Согласно официальной документации, она имеет следующий синтаксис:

где в качестве $filename может быть использован путь до локального файла. Хорошо известно, что получить содержимое локальных файлов можно так:

Но помимо тривиального пути к файлу могут быть использованы так называемые врапперы (wrapper). Лучший способ пояснить, что это такое, — привести несколько примеров. Итак, с использованием врапперов через все ту же функцию fopen становится возможным:

  • скачивать файлы с FTP: ftp://user:password@10.0.0.1/pub/file.txt;
  • обращаться, если доступ к ним ограничен, к server-status/server-info по IP: http://127.0.0.1/server-status;
  • обращаться к файловым дескрипторам, открытым на чтение (PHP >= 5.3.6): php://fd/XXX;
  • и даже выполнить команды OS (если установлено расширение expect): expect://ls.

Врапперы (они же обработчики протокола или обертки) указывают функциям, каким образом обрабатывать данные из потока. Поэтому функции, поддерживающие врапперы, могут быть использованы для получения данных из различных источников. Врапперы позволяют гибко и удобно обрабатывать данные, поступающие в программу через какой-либо поток, а также модифицировать их при необходимости.

Секция Registered PHP Streams в выводе phpinfo()
Другие статьи в выпуске:

Хакер #163. Лучшие гаджеты для хакера

  • Содержание выпуска
  • Подписка на «Хакер»-30%

В рассмотренном примере врапперы использовались в режиме read. Если же происходит запись данных, то и в этом случае врапперы также могут расширить возможности многих функций. Например, функция copy() поддерживает врапперы в обоих своих аргументах, и если во втором аргументе используется обертка php://output, то копируемый файл отправляется в выходной буфер. Таким образом, функция copy() позволяет не только копировать файлы, но и читать их.

Аналогичным образом можно использовать функцию file_put_contents и любую другую функцию, поддерживающую враппер в режиме write:

В версии PHP 5.3.6 появился враппер php://fd, который предоставляет прямой доступ к файловым дескрипторам. Если PHP установлен как модуль Apache’а, враппер php://fd дает возможность записывать произвольные данные в access_log/error_log (обычно права на этих файлах 644, и напрямую в них может писать только root).

Надо сказать, что в PHP довольно много встроенных врапперов, но при этом можно создавать и регистрировать собственные обертки, используя функцию stream_wrapper_register. Более подробную информацию ты сможешь найти на официальном сайте PHP. Полный список доступных врапперов можно посмотреть с секции phpinfo — Registered PHP Streams.

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

Какой HTML-элемент выбрать

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

Невольно возникает вопрос, а может ли для этой цели подойти элемент . Однако, спецификация W3C говорит вот что:

Элемент несёт в себе собственную семантику. Он подходит для тематической группировки контента. В каждом разделе должен быть заголовок (элемент h1-h6) в качестве дочернего элемента (прим. перев.: это не строгое правило, но крайне желательно соблюдать его).

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

Основная информация

ID

265164591

Можно редактировать:
нет

Можно скрыть настройками приватности:
нет

Уникальный идентификатор пользователя, определяется при регистрации ВКонтакте.

Домен

id265164591

Можно редактировать:
да

Обязательно к заполнению:
нет

Можно скрыть настройками приватности:
нет

Домен служит для установки красивой запоминающейся ссылки на страницу пользователя ВКонтакте.

Имя

Арпрпа

Можно редактировать:
да

Обязательно к заполнению:
да

Можно скрыть настройками приватности:
нет

Фамилия

Раппр

Можно редактировать:
да

Обязательно к заполнению:
да

Можно скрыть настройками приватности:
нет

Отчество

не указано

Можно редактировать:
нет

Обязательно к заполнению:
нет

Можно скрыть настройками приватности:
нет

ВКонтакте больше нельзя редактировать отчество для пользователей, у которых оно не было указано ранее.

Пол

мужской

Можно редактировать:
да

Обязательно к заполнению:
да

Можно скрыть настройками приватности:
нет

Дата рождения

скрыта или не указана

Можно редактировать:
да

Обязательно к заполнению:
да

Можно скрыть настройками приватности:
да

ВКонтакте присутсвует возможность скрыть дату рождения полностью или частично (при этом будут отображены только день и месяц рождения).

«Обёртка» против «Контейнера»

Я вижу разницу между элементом-обёрткой и элементом-контейнером.

В языках программирования слово «контейнер» обычно используется для структуры, содержащей более одного элемента. «Обёртка» же — это нечто, что оборачивается вокруг одного объекта, чтобы предоставить интерфейс к нему и расширить его функциональность.

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

Обёртка ассоциируется с , который содержит весь остальной HTML в документе. Уверен, что многие помнят то время, когда мы устанавливали для ширину и центрировали основной контент. Обёртки так же были полезны, чтобы прижать футер.

Контейнер, напротив, обычно предполагает другой вид содержимого. То, которое иногда необходимо для реализации поведения или оформления множественных компонентов. Он служит задаче группировки семантических и визуальных элементов. Например, у , которые содержат их систему сеток или другие различные компоненты.

Термины «Обёртка» и «Контейнер» также могут означать одно и то же в зависимости от разработчика и его целей. Могут быть и другие соглашения, так что лучший совет, как правило — делать так, как вам самим логичнее. Но помните, что наименование — одна из наиглавнейших фундаментальных вещей в практике разработчика. Система наименования делает код читабельнее и предсказуемее. Выбирайте тщательнее!

Вот пример общей обёртки страницы:

/**
 * 1. Центрируем содержимое. Да, это немножко вкусовщина.
 * 2. См. раздел «width против max-width»
 * 3. См. раздел «Дополнительные внутренние отступы»
 */
.wrapper {
  margin-right: auto; /* 1 */
  margin-left:  auto; /* 1 */

  max-width: 960px; /* 2 */

  padding-right: 10px; /* 3 */
  padding-left:  10px; /* 3 */
}

Дополнительные внутренние отступы

Я видел, как многие разработчики забывали один граничный случай. Допустим, есть обёртка с max-width: 980px. Этот граничный случай проявляется при экране устройства 980px. Поэтому, её содержимое прилипнет точно к краям экрана, не оставляя «воздуха».

Эта проблема нехватки «воздуха»

Обычно нам нужны отступы по краям. Вот почему, когда мне нужна обёртка шириной 980px, я делаю так:

.wrapper {
  max-width: 960px; /* на 20px меньше, чтобы уместить отступы по краям. */

  padding-right: 10px;
  padding-left: 10px;

  /* ...  */
}

Вот почему добавление и к обёртке будет хорошей идеей, особенно на мобильных устройствах.

Или подумайте о box-sizing, чтобы отступы вообще не влияли на общую ширину.

Что таит в себе ZIP?

ZIP — популярный формат сжатия данных и архивации файлов. Поддержка этого формата реализована во всех современных операционных системах, а библиотеки для работы с ним написаны для большинства языков программирования. В PHP для работы с этим форматом удобно использовать модуль zip.

В Linux-системах модуль zip становится доступным, если PHP скомпилирован с опцией —enable-zip. Архивировать можно не только отдельные файлы, но и целые каталоги; чтобы сохранялась структура каталога, в именах файлов, добавляемых в архив, допустимо использовать слеш /

Еще одной важной особенностью модуля zip является возможность обрабатывать файлы с произвольным именем: главное, чтобы содержимое файла было корректно сформированным zip-архивом

После того как zip-архив создан, с помощью враппера zip:// можно напрямую обращаться к файлам внутри архива.

Возможность помещать в архив файлы, в именах которых присутствует слеш, позволяет эксплуатировать уязвимости типа Remote File Include, при отсутствии null-байта. Для примера рассмотрим следующий простой скрипт:

Конечно, добиться выполнения кода в данном случае можно разными путями. Но использование врапперов http://, ftp://, data:// ограничивается директивой allow_url_include, а использованию null-байта при инклуде локальных файлов скорей всего помешает директива magic_quotes_gpc. И может даже показаться, что при allow_url_include=Off и magic_quotes_gpc=On проэксплуатировать уязвимость никаким образом не получится. Но есть еще один способ, не описанный ранее в паблике!

Для начала предположим, что есть возможность создавать на атакуемом сервере файлы. Тогда, создав zip-архив, как показано в примере выше, возможно выполнить PHP-код, используя враппер zip://.

Если нет возможности создать нужный файл с помощью PHP-функции, то можно использовать временные файлы, которые создает PHP при загрузке контента через HTML-форму. Путь до временного файла можно узнать из phpinfo(). Более подробные сведения о том, как использовать временные файлы при эксплуатации уязвимостей типа LFI/RFI, можно почерпнуть на форуме rdot.org

Важно отметить, что директива allow_url_fopen не ограничивает применение обертки zip://

Intro

Уязвимости, связанные с реализованным в PHP механизмом врапперов, обсуждаются достаточно давно. Ссылки на них присутствуют в OWASP TOP 10 и WASC TCv2. Однако ряд особенностей реализации кодирования данных приводит к тому, что даже приложения, разработанные с учетом требований безопасности, могут содержать уязвимости (включая критические). В этой статье мы сначала кратко рассмотрим, что представляют собой PHP wrappers и как они могут быть полезны программистам. Затем разберем их особенности, которые позволяют обходить встроенные в приложение фильтры безопасности и реализовывать атаки, связанные с несанкционированным доступом к файловой системе и выполнением произвольного кода.

Where is my data://?

Враппер data:// с момента своего появления привлекал внимание специалистов по веб-безопасности. В официальной документации этот враппер предлагают использовать в очень ограниченной форме

Но согласно спецификации RFC 2379, эта обертка допускает более развернутый синтаксис:

При этом mediatype может либо полностью отсутствовать, либо быть заполнен произвольными значениями:

Эту особенность враппера можно использовать для обхода проверок и фильтров. Например, в популярном скрипте TimThumb v1.x есть такой фильтр:

Обойти эту проверку можно следующим образом:

В PHP существует такая функция, как stream_get_meta_data(). Согласно официальной документации, она извлекает метаданные из потоков и файловых указателей:

При этом в возвращаемом массиве содержатся элементы с четко заданными ключами, и задача добавления в этот массив новых элементов выглядит на первый взгляд довольно проблематичной. Но с помощью враппера data:// можно довольно просто манипулировать этим массивом! Как? Приведу пример:

Документация к врапперу data://

Если в переменной $file вместо имени локального файла использовать враппер data,

то можно легко переопределить параметр $password и, используя куки, пройти авторизацию.

Эксплуатация уязвимостей в TimThumb v1.x

TimThumb — это популярный скрипт для работы с изображениями, который используется во многих темах и плагинах для WordPress. В августе 2011 года в скрипте TimThumb v 1.32 была найдена критическая уязвимость, позволяющая загружать на атакуемый сервер вместо изображений с доверенных хостов файлы с PHP-кодом. Почти в одночасье в публичном доступе появилась адвизори, подробно рассказывающая об эксплуатации этой уязвимости.

Суть уязвимости заключалась в том, что скрипт некорректно проводил проверку URL по списку доверенных хостов, с которых возможно было загрузить изображения. Для обхода фильтров, к примеру по доверенному хосту blogger.com, предлагалось зарегистрировать домен четвертого уровня, содержащего в себе URL доверенного хоста, например blogger.com.attacker.com, и загружать файлы с этого домена.

Этим способом можно было проэксплуатировать уязвимость до версии 1.32 (revision 142). Но более новые версии оказались также уязвимы. Рассмотрим, каким образом происходит загрузка изображений в версии 1.34 (revision 145):

Несложно заметить, что при проектировании функции check_external было допущено несколько логических ошибок:

  1. После выполнения большинства проверок в функцию parse_str попадают нефильтрованные пользовательские данные. Таким образом, можно переопределить переменные, которые до этого проверялись: $url_info, $src, $local_filepath. Поэтому возможно загружать файлы с любых серверов.
  2. После загрузки файла на сервер на основе getimagesize проверяется, является ли файл изображением. Если проверка не пройдена, то файл удаляется. Но так как есть возможность влиять на переменную $local_filepath, то к локальному файлу можно обращаться, используя врапперы php://filter, compress.zlib://. А в этом случае функция unlink не сможет удалить файл.

Немного покопавшись, я написал эксплойт для загрузки файлов. С произвольным именем и с произвольным содержимым, в произвольное место системы.

Ветка 1.х заканчивается 149-й ревизией, в которой тоже есть уязвимости. В этой ревизии уже убрана функция parse_str и поэтому нет возможности произвести перезапись переменных. Но фильтры, проверяющие валидность URL, проверяют только вхождение соответствующих подстрок в строке $src. При этом если функция curl_init недоступна на атакуемом сервере, то загрузка файлов осуществляется с помощью file_get_contents/file_put_contents

Важно отметить, что эти функции, в отличие от curl_init, поддерживают все доступные в PHP врапперы

Таким образом, с помощью враппера data:// можно обойти все фильтры и создать файл в директории кеша с произвольным содержимым:

Или с помощью враппера compress.zlib:// скопировать в кеш локальный файл:

Профит в том, что к файлам из кеша можно обращаться напрямую, в результате чего добиться RCE через запись шелла с помощью враппера data, а также получить содержимое локальных файлов, используя compress.zlib.

English[edit]

English Wikipedia has articles on:wrapper

Wikipedia

Woman’s wrapper

Candy wrappers

Nounedit

wrapper (plural )

  1. Something that is wrapped around something else as a cover or protection: a wrapping.
  2. An outer garment; a loose robe or dressing gown.
    • 1839, Edgar Allan Poe, ‘William Wilson’:

      ‘Please to examine, at your leisure, the inner linings of the cuff of his left sleeve, and the several little packages which may be found in the somewhat capacious pockets of his embroidered morning wrapper.’
    • 1855, Charles Dickens, The Holly-Tree

      It was eight o’clock to-morrow evening when I buckled up my travelling writing-desk in its leather case, paid my Bill, and got on my warm coats and wrappers.
  3. One who, or that which, wraps.
    He proved to be a remarkably efficient wrapper of parcels.
  4. (object-oriented programming) A construct, such as a class or module, that serves to mediate access to another.

    We need a Perl wrapper for this C++ library.

Usage notesedit

In the computing sense, wrapper is often used attributively: one can speak of a “wrapper class”, a “wrapper object”, a “wrapper function”, and so on. More broadly, one can speak of the “wrapper pattern”, which is a general term for the creation and use of such wrappers.

Translationsedit

something that is wrapped around something else as a cover or protection

  • Arabic: ‎ m (ḡilāf)
  • Armenian:  (hy) (šapik)
  • Chinese:
    Mandarin:  (zh),  (zh) (bāozhuāngzhǐ)
  • Dutch:  (nl),  (nl)
  • Esperanto: please add this translation if you can
  • Estonian: please add this translation if you can
  • French:  (fr) f,  (fr) m
  • Georgian: please add this translation if you can
  • German:  (de) f,  (de) m
  • Japanese: (ほうそうし, hōsōshi), 上包み (うわづつみ, uwadzutsumi)
  • Khmer: please add this translation if you can
  • Latin:  n
  • Latvian: please add this translation if you can
  • Lithuanian: please add this translation if you can
  • Mongolian: please add this translation if you can
  • Russian:  (ru) f (objórtka),  (ru) f (upakóvka),суперобло́жка (ru) f (superoblóžka) (for books, magazines),  (ru) m (fántik) (for candies),  (ru) m (čexól) (case, hood)
  • Spanish:  (es),  (es)
  • Swedish:  (sv)
  • Thai: please add this translation if you can
  • Vietnamese: please add this translation if you can

a negligée or loose dressing gown

  • Irish:  f
  • Russian:  (ru) f (nakídka),  (ru) m (xalát), пеньюа́р (ru) m (penʹjuár), ночну́шка (ru) f (nočnúška)

a person who wraps parcels etc

(computing) A construct that serves to mediate access to another object.

  • Finnish:  (fi), kääreluokka, wrapperi
  • French:  (fr) f
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector