Литмир - Электронная Библиотека

· fputs( amp;out[0],stdout);

·}

· return 0;

·}

Но как в этом случае заставить программу выводить результаты работы в файл, а не терминал? Стандартный ввод-вывод выгодно отличается возможностью направить его куда угодно, указав в командной строке специальный символ “»” для вывода и “«” для ввода.

Например, используем ранее созданный файл myfile и выведем результат работы iostd в файл “out.txt”. Это можно сделать следующим образом:

· iostd.exe «myfile»out.txt

· copy out.txt con

· 0x48

· 0x65

· 0x6C

· 0x6C

· 0x6F

· 0x2C

· 0x20

· 0x53

· 0x61

· 0x69

· 0x6C

· 0x6F

· 0x72

· 0x21

· 0xA

· 1 файлов скопировано

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

Перенаправление ввода-вывода полезная штука, но зачастую слишком уж уязвимая для атак. Рассмотрим следующий код (расположенный на диске под именем “/SRC/iohack.c”), часто встречающийся в UNIX-приложениях.

· #include «stdio.h»

· main()

· {

· FILE *f;

· char buf[100],c=2;

· printf("$");

· fgets( amp;buf[0],100,stdin);

· if (buf[0]!='«')

· printf("%s\n", amp;buf[0]);

· else

· {

· while(buf[c]!=0xA) c++;

· buf[c]=0;

· if (f=fopen( amp;buf[1],"r"))

· while((c=fgetc(f))!=EOF)

· printf("%c",c);

·}

·}

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

· iohack.exe

· $Hello!

· Hello!

·

· iohack.exe

· $«myfile

· Hello, Sailor!

С одной стороны, поддержка приложением перенаправления ввода-вывода очень удобна и облегчает работу с компьютером (в самом деле, зачем вводить текст вручную, если его можно взять из файла?), но… часто приводит к последствиям никак не запланированными разработчиком [94].

Приведенный выше пример, запущенный в среде UNIX, встретив конструкцию “«/etc/passwd” выдаст на экран содержимое файла паролей, или любого другого файла который будет запрошен. С первого взгляда ничего страшного в этом нет, - программа наследует все привилегии пользователя и получает доступ к тем, и только к тем, файлам, которые пользователь мог бы просмотреть и без помощи этой программы, скажем, командой “cat”.

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

Разумеется, SendMail не одинок, и подобные ошибки допущены во множестве приложений, щедро разбросанных по серверам. Часто для их поиска даже не требуется кропотливого изучения исходных текстов программы - достаточно во всех вводимых строках (или полях заголовка) подставить символ “«” и посмотреть на реакцию программы - нет-нет, да повезет!

Однако возможности перенаправления ввода-вывода очень ограничены. Рассмотрим это на следующем примере, - пусть требуется получить отсортированный в обратном порядке список файлов текущей директории. Команда ‘ls’ не предоставляет такого сервиса, поэтому придется воспользоваться утилитой ‘sort’ Сперва сохраним результат работы команды ‘ls’ (или dir в MS-DOS) в файле temp. Затем используем его в качестве входного потока данных утилиты ‘sort’, запушенной с ключом ‘-r’ для задания обратного порядка сортировки.

· $ ls»temp

· $ sort -r «temp

· temp

· sioux.pl

· passwd

· iohack.o

· iohack.c

· index_hack.htm

· demos.txt

· bomb.pl

· attack2.htm

Да, это работает, но требует создания лишнего файла на диске и в целом недостаточно удобно. А нельзя ли связать стандартный вывод одной программы со стандартным вводом другой? Можно! И такая конструкция называется конвейер или труба (от английского pipe).

Для создания конвейера необходимо использовать символ “|”, разделяющий запускаемые программы следующим образом: “программа 1 параметры | программа 2 параметры | программа 3 параметры”. Разумеется, стандартный ввод первой программы в цепочке и стандартный вывод последней могут быть перенаправлены с помощью символов “«” и “»” соответственно (результат попытки перенаправления остальных непредсказуем, и обычно разрывает цепочку конвейера).

Интереснее проследить, как происходит взаимодействие процессов и передача данных по конвейеру. Конвейер - сути дела тот же файл, но скрытый от пользователя, построенный по принципу FIFO (от английского First Input First Output - первый пришел - первым и уйдешь). Так, запись в конвейер, из которого никто не читает, рано или поздно вызывает его переполнение (а размер буфера обычно порядка четырех килобайт) и приводит к блокировке процесса-писателя, до тех пор, пока хотя бы один байт из конвейера не будет прочитан. Точно так, попытка чтения из пустого конвейера приводит к остановке процесса-читателя до тех пор, пока в нем не окажется хотя бы один байт.

Техника сетевых атак - img_24

Схематическое изображения конвейера

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

· $ ls | sort -r

· sioux.pl

· passwd

· iohack.o

· iohack.c

· index_hack.htm

· demos.txt

· bomb.pl

· attack2.htm

Не правда ли намного проще и элегантнее? Между прочим, конвейеры поддерживаются не исключительно одной UNIX, - не хуже с ними справляется и старушка MS-DOS. Доказывает это эксперимент, приведенный ниже:

26
{"b":"837821","o":1}