Показаны сообщения с ярлыком php. Показать все сообщения
Показаны сообщения с ярлыком php. Показать все сообщения

15 сентября 2015

Дебаг PHP скрипта

При необходимости проследить обратный след (backtrace) к какому-либо системному вызову (например, gettimeofday) в PHP скрипте, необходимо воспользоваться рекомендациями, описанными в статье http://habrahabr.ru/post/129982/
Техника основана на использовании gdb:
1) запускаем PHP скрипт, делая в нем вывод PID getmypid() + паузу "Press any key" с помощью fgets(STDIN)
2) параллельно запускаем "gdb php"
3) в консоли gdb вводим "attach {PID}"
4) регистрируем точку остановки с помощью команды: "rbreak gettimeofday"
5) даем команду продолжить выполнение скрипта: "continue"
6) жмем Enter в терминале скрипта
7) далее по статье (bt + f N + print)

20 февраля 2012

Пример удаленного выполнения PHP кода после загрузки изображения на сайт

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

Началось все с того, что клиент обратился с жалобой, что в браузере не отображался загруженный ими логотип. Логотип оказался "гифкой" с расширением .tif, который, естественно браузер и не отображал.

Просмотр кода показал, что существует проверка на то, что загружаемый файл - это изображение в формате GIF, JPEG или PNG и размеры данного изображения не должны превышать 300 пикселей по вертикали и горизонтали. Но вся беда в том, что после данной проверки скрипт перемещяет данный файл в надлежащую директорию, изменяя имя файла, но сохраняя его расширение.

Таким образом на сервер можно загрузить картинку с расширением .php. Что не мудрено, при запросе данной картинки браузером, интерпретатор PHP обработает этот файл. Уязвимость на лицо.

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

Если просто добавить в конец графического файла PHP-код, то интерпретатор отказывается его выполнять (пробовал на PHP 5.3.10). Экспериментальным путем было обнаружено, что интерпретатору мешает наличие в файле символа с кодом 0h - индикатор конца строки в Си. Меняем в файле все вхождения данного символа на что-нибудь другое, и вуаля - интерпретатор успешно выполняет инструкции в конце файла.

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

Сам код валидации основан на валидаторе из состава используемого нами фреймворка, принимающий список допустимых mime-type'ов файла а сам, для определения типа бинарного файла, использует внешнюю программу file (на *nix платформе).

Возьмите любую "гифку", поместите в конец файла PHP код и file покажет, что это image/gif, поскольку читает только заголовок файла.

# file -bi untitled-1.gif.php
image/gif

Фокус в том, что после замены нами символа с кодом 0h на любой другой, файл по прежнему детектируется как image/gif.

Финальный шаг: нужно "подогнать" изображение, чтобы его размеры не превышали 300 пикселей. Из описания GIF формата находим, какие байты информируют о размерах изображения - седьмой и восьмой байты описывают ширину, девятый и десятый - высоту. Если изображение будет меньше, чем 256 на 256 точек, то "старшие" - седьмой и девятый - байты будут нулевыми, что нам никак на подходит. Поэтому заменяем с седьмого по десятый байты на символы c кодом 01h и получаем картинку с размером 257 на 257 пикселей.

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

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