Совсем чуть-чуть о cgi
23 01 2010 | Рубрика: Web, Безопасность, Кодинг, Хак |
|
Популярность таких языков программирования, как php используемых для создания web-приложений, заставила нас позабыть о том, что для написания web-софта можно использовать любой язык программирования. Способный работать со стандартными устройствами ввода, вывода, будь то C, C++, Pascal, Delphi, Basic, Assembler (если постараться можно и в машинных кодах написать). В чем же мы выиграем, если приложение будет написано, допустим на C, а не на том же php. Всем известно, что C – это компилируемый язык, а php – интерпретируемый. Компилируемые языки работают в разы быстрее, мы сможем использовать это преимущество, когда нужно выполнить ресурсоемкие операции непосредственно на web-странице. Подобные приложения принято называть CGI-скриптами.
CGI — стандарт интерфейса, используемого для связи внешней программы с web-сервером. Программу, которая работает по такому интерфейсу совместно с web-сервером, принято называть шлюзом, хотя многие предпочитают названия «скрипт» (сценарий) или «CGI-программа».
Листинг: Пример GCI- программы на C:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Content-Type: text/html\r\n\r\n"); //HTTP - заголовок
printf("<b>Hello World</b>"); // печатаем на экране сообщение Hello World
}
Листинг: Пример GCI- программы на C.
Для того чтобы сервер правильно обрабатывал наши данные, ему нужно послать заголовок с их фактическим указанием. Content-Type: text/html, говорит о том, что данные текстовые, формата html, если же мы укажем Content-Type: image/png, то это будет означать рисунок формата png, если не послать серверу заголовка, то он выдаст вам ошибку с номером 500. Собственно здесь все понятно. Но смысл cgi-скриптов, не в статической печати кода, а в динамической, в зависимости от какого либо условия html –код должен меняться, сам скрипт делать те или иные действия. В большинстве случаев выполнение или не выполнение условия строится на данных полученных от пользователя.
Листинг: Пример GCI- программы на C, получаем данные от пользователя:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *usedb = getenv("QUERY_STRING");
printf("Content-Type: text/html\r\n\r\n"); //HTTP – заголовок
printf("%s", usedb); //данные, которые ввел пользователь
}
Листинг: Пример GCI- программы на C, получаем данные от пользователя.
Давайте откомпилируем данные пример, пускай наш cgi-скрипт называется script.c, откомпилируем его (gcc -o script script.c) и поместим в директорию для cgi-скриптов (cgi, cgi-bin), нашего web-сервера. Обратимся к скрипту следующим образом: «http://localhost/cgi-bin/script?hello», сгенерируется web-страница с надписью «hello»
QUERY_STRING – это переменная окружения, помимо нее еще существуют и другие. В этой переменной храниться все, что мы передали серверу после знака «?». Функция getenv() возвращает, нам указатель на QUERY_STRING, его мы и сохраняем в переменной типа указатель – usedb. Затем выводим значение по адресу в указателе на экран. Так же данные от пользователя можно принять с помощью переменной PATH_INFO, только тогда обращаться к скрипту нужно иначе, допустим, вы используете выше приведенный скрипт, только берете другую переменную окружения(PATH_INFO), тогда обращаемся так:
«http://localhost/cgi-bin/script/peremennay1&peremennay2»
вывод:
/peremennay1&peremennay2
В принципе выше перечисленного достаточно для программирования cgi-приложений, при условии, что вы уже знаете язык, на котором программируете. Кстати говоря, cgi-скрипты можно писать и на языке команд операционной системы.
Уязвимости cgi
Переполнение Буфера:
Листинг: GCI- программа на C, переполнение буфера:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *usedb = getenv("QUERY_STRING");
char dann[10];
printf("Content-Type: text/html\r\n\r\n");
strcpy(dann, usedb);
printf("%s", dann);
}
Листинг: GCI- программа на C, переполнение буфера.
Обратитесь к скрипту следующим образом «http://localhost/cgi-bin/script?0123456789012345» и сервер наградит вас ошибкой под номером 500. Но это меньшее, что может случиться, в лучшем (для взломщика) случае он получит доступ к серверу с правами уязвимого скрипта, а там и до root’а не далеко. Чтобы избежать, подобных ошибок используйте безопасный аналог функции strcpy – trlcpy, а также следите за границами массивов.
Уязвимость Форматной строки (подробнее можно почитать в моей статье «Недостатки форматной строки»):
Листинг: GCI- программа на C, уязвимость форматной строки:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *usedb = getenv("QUERY_STRING");
printf("Content-Type: text/html\r\n\r\n");
printf(usedb);
}
Листинг: GCI- программа на C, уязвимость форматной строки.
Пошлите серверу следующий запрос «http://localhost/cgi-bin/script?%x%x%x» и увидите содержимое стэка. И это лишь маленькая толика всей проблемы. При печати данных не забывайте использовать спецификаторы.
Произвольное чтение файлов:
Листинг: GCI- программа на C, чтение произвольных файлов:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{ char *OpenFile(char *arg);
char *filename = getenv("QUERY_STRING");
printf("Content-Type: text/html\r\n\r\n");
printf("%s", OpenFile(filename));
}
char *OpenFile(char *filename)
{
int i=0;
char line[256], text[10240];
FILE *f;
f=fopen(filename,"r");
while(!feof(f))
{
fgets(line,256,f);
strcpy(&text[i], line); // Здесь лучше использовать безопасную функцию strlcpy
i=i+strlen(line);
}
fclose(f);
return &text[0];
}
Листинг: GCI- программа на C, чтение произвольных файлов.
Теперь обратитесь к скрипту примерно так:
«http://localhost/cgi-bin/script?/../../../etc/passwd»
На странице появится содержимое файла /etc/passwd. Перед использованием функций foren, open фильтруйте данные. Если ваш скрипт работает с БД, фильтруйте данные, дабы избежать уязвимости типа sql-injection, xss.
Сегодня мы разобрали типичные ошибки программистов, это относится не только к cgi-скриптам, но и к обычным программам. Большинство ошибок не поддается классификации, поэтому следите за логикой выполнения программы, стоит ей выполнится не так как задумал разработчик и вся безопасность сойдет на нет.
Kerny
q@sa-sec.org
Тэги: cgi, web-сервер, уязвимости
Возник вопрос после прочтения? Или автор не описал важный момент?
Есть что сказать на эту тему, а комментарий - это не твое?
Тогда Go на наш форум.
Общайся на темы ИТ свободно, развивайся и рассказывай новое другим! Мы будем рады принять тебя в нашу компанию













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