Но полученный код еще не готов к употреблению. Со смещения 0х11 (первый расшифровываемый байт) по 0х23 (последний расшифровываемый байт) его необходимо зашифровать, выполнив над каждым байтом операцию XOR 0x90. Такой ключ шифрования выбран потому, что в шифруемом фрагменте нет ни одного байта, равного 0х90. Следовательно, в зашифрованной строке не окажется ни одного нуля. Другим недопустимым символом является код клавиши «ENTER», равный 0xD. Если он встретится во вводимой строке, система воспримет его как завершение строки и прекратит ввод.
Для шифровки можно воспользоваться любой утилитой, наподобие шестнадцатеричных редакторов QVIEW (или HIEW), но нетрудно это реализовать и на языке Си. Один из простейших вариантов приведен ниже (на диске, прилагаемом к книге, он находится в файле “/SRC/buff.crypt.c”). Для упрощения понимания его работы никакие проверки не выполняются.
· #include «stdio.h»
·
· main()
· {
· FILE *fin,*fout;
· char buff[40];
· int a=0x11;
·
· fin=fopen("buff.raw","rb");
· fout=fopen("buff.ok","wb");
· fread( amp;buff[0],1,40,fin);
· for (;a«0x24;a++) buff[a]=buff[a] ^ 0x90;
· fwrite( amp;buff[0],1,40,fout);
· close(fin);
· close(fout);
·}
·
·
Полученный в результате шифровки файл должен выглядеть следующим образом (на диске, прилагаемом к книге, он находится в директории “/SRC” и называется “buff.ok”)
· 00000000: 83 EC 30 8B C4 33 C9 83 ¦ C1 13 80 70 19 90 40 E2 Гь0Л-3гГ+!АpvР@т
· 00000010: F9 C0 13 50 84 C0 28 91 ¦ 16 79 E7 6F 40 7B 6E F3 •L!PДL(С-yчo@{nє
· 00000020: FD F4 90 A4 58 FF 12 00 ¦ ¤ЇРдX ¦
То же самое в десятичном виде, предназначенное для ввода в компьютер с помощью клавиши Alt выглядит так:
· 131 236 048 139 196 051 201 131 193 019 128 112 025
· 144 064 226 249 192 019 080 132 192 040 145 022 121
· 231 111 064 123 110 243 253 244 144 164 088 255 018
Если все ввести правильно и без ошибок, запустится командный интерпретатор.
Дополнение. Поиск уязвимых программ.
Код, получаемый управление при срыве стека, запускается от имени и с привилегиями уязвимой программы. Отсюда, наибольший интерес представляют программы, обладающие наивысшими привилегиями (системные сервисы, демоны и т.д.). Это значительно сужает круг поиска и ограничивает количество потенциальных кандидатов в жертвы.
Врезка «замечание» *
Существует некоторые методы, позволяющие предотвратить последствия срыва стека, даже при наличии грубых ошибок реализации. В главах, посвященных безопасности операционных систем UNIX и Windows NT, отмечалось, что все они разрешают выполнение кода в стеке, и поэтому потенциально уязвимы, или же, другими словами, чувствительны к ошибкам программного обеспечения.
На самом же деле это не совсем верно. Существуют экзотические ядра UNIX, запрещающие подобную операцию - при попытке выполнить код, размещенный в стеке, происходит исключение, и выполнение программы прерывается. Но вместе с этим перестают работать многие легальные программы, «на лету» генерирующие код и исполняющие его в стеке [330]. Но запрет на выполнение кода в стеке не затрагивает модификацию переменных, указателей, поэтому принципиальная возможность атак по-прежнему остается. Поэтому, такие ядра используются крайне редко. Тем более, вызов исключение при попытке злоумышленника проникнуть на компьютер, не самая лучшая защита [331].
Некоторые компиляторы (тот же gcc) способны генерировать код, автоматически обнаруживающий выход за границы буфера, но это вызывает снижение производительности в десятки раз и чаще всего оказывается неприемлемо.
Врезка «информация» *
В рамках проекта Synthetix (http://www.cse.ogi.edu/DISC/projects/synthetix) удалось найти несколько простых и надежных решений, затрудняющих атаки, основанные на срыве стека. Например, “StackGuard” - одна из «заплат» к компилятору gcc, дополняет пролог и эпилог каждой из функций, особым кодом, контролирующим целостность адреса возврата. Алгоритм в общих чертах следующий: в стек вместе с адресом возврата заносится, так называемый, “Canary Word”, расположенный до адреса возврата. Искажение адреса возврата обычно сопровождается и искажением Canary Word, что легко проконтролировать. Соль в том, что Canary Word содержит символы “\0”, CR, LF, EOF, которые не могут быть обычным путем введены с клавиатуры. А для усиления защиты добавляется случайная привязка, генерируемая при каждом запуске программы.
Такая мера действительно затрудняет атаки, но не исключает их принципиальную возможность. Существует возможность перезаписи любой области памяти как искажением регистра EBP, используемого для адресации локальные переменных, так и модификацией переменных указателей. Этого StackGuard отследить не в силах. Кроме того, если происходит переполнение буферов, в которых помещается информация, считанная из двоичного файла или принятая по сети, то отсутствует всякое ограничение на передаваемые в строке символы. А узнать значение привязки можно, например, с помощью уязвимости в функции printf (и подобным ей) и т.д.
Существуют различные способы поиска уязвимых программ. Например, с помощью дизассемблирования и тщательного изучения кода, или тривиального ввода строк переменной длины. Как уже отмечалось в главе «Технология срыва стека» недостаточно ограничится вводом максимально длинных строк. Необходимо перебирать все длины от нулевой до максимально возможной.
Манипуляция со строками разной длины - наиболее простой (но не всегда действенный) путь. Если удается подобрать строку, вызывающую исключение, то, следовательно, исследуемая программа содержит уязвимость. Но вовсе не факт, что удастся передать управление на свой код, изменить адрес возврата или каким-то иным способом проникнуть на атакуемую машину. В некоторых случаях ошибки переполнения приводят к возможности блокирования программы, но не позволяют злоумышленнику совершить никакие осмысленные действия.
Поэтому, перед атакующим стоят следующие вопросы: возможно ли искажение адреса возврата таким образом, чтобы он указывал на переданную строку? Если да, то какой байт строки попадает в буфер? Большинство операционных систем при возникновении аварийной ситуации выдают информацию, способную пролить свет на причины аварии. Род и форма выдача информации варьируются от одной операционной системы к другой, но практически всегда приводится содержимое регистров, верхушки стека, инструкции, вызвавшей исключение и номера самого исключения. Этими сведениями и может воспользоваться злоумышленник, чтобы ответить на интересующие его вопросы.
Наименее информативной оказывается Windows 2000, не сообщающая ни содержимое регистров, ни состояние стека. Однако она позволяет загрузить отладчик, с помощью которого легко получить необходимую информацию. Существует так же утилита «Dr. Watson», предназначенная для выяснения причин возникновения аварийных ситуаций. Она великолепно подходит для анализа уязвимых программ.
Ниже будет показано, как можно использовать эту информацию для проникновения на удаленный компьютер. Поскольку, после возникновения исключения ни одна операционная система не передает клиенту сведения о причине аварии (содержимое регистров, состояние стека), то все исследования необходимо проводить на локальной машине. Т.е. злоумышленник должен иметь физический доступ к своей жертве или установить на своем компьютере ту же самую операционную систему и то же самое программное обеспечение.