8(495)909-90-01
8(964)644-46-00
pro@sio.su
Главная
Системы видеонаблюдения
Охранная сигнализация
Пожарная сигнализация
Система пожаротушения
Система контроля удаленного доступа
Оповещение и эвакуация
Контроль периметра
Система домофонии
Парковочные системы
Проектирование слаботочных сетей
Аварийный
контроль
Раздел: Документация

0 ... 51 52 53 54 55 56 57 ... 102

Перевод шестнадцатеричных значений в символьное представление сопряжеп с определенными неудобствами, но использование спецификатора "*s" приведет не к выводу строки в удобочитаемом виде, а к аварийному завершению приложения. Такое поведение объясняется тем, что, встретив спецификатор "js» функция printf ожидает увидеть указатель на строку, но не саму строку. В результате происходит обращение по адресу 5038384Bh ("K98PN" в символьном цред. ставлении), который находится вне пределов досягаемости программы, что и вызывает исключение.

Спецификатор "Xs" пригоден для отображения содержимого указателей, ссылающихся на строки или другие «читабельные» структуры данных. Его использование продемонстрировано в следующем примере (листинг 4.43).

Листинг 4.43. Пример, демонстрирующий использование спецификатора %s

#include <stdio.h> include <string.h> #include <ma11oc.h> void mainO {

FILE *f: char *pass: char * pass:

pass= (char *)malloc(100):

pass=(char *)malloc(100):

if (!(f=fopen("buff.psw"."r"))) return:

fgets( pass.lO0.f):

pass[strler( pass)-l]=0:

pnr,tf("Passw:"):fgets(pass.lO0.stdin):

pass[strler(pass)-l]=0:

// Код. проверяющий истинность пароля, введенного пользователем. // для упрощения понимания опущен printf(pass):

}

На этот раз буфер, хранящий эталонный пароль, размещен не в стеке, а в ку4 области памяти, выделенной функцией mall ос. В самом же стеке никаких ретных данных уже не содержится. Но это никак не усиливает затишен» программы, поскольку вместо самого буфера в стеке расположен УкялаГС ( него. Даже перенос указателя в глобальную переменную не смог бы спас ложения, но об этом немного позднее.

В приведенном примере указатель pass оказался расположен на верху* , ка, поэтому использование спецификатора "Xs" приводит к выводу ч* эталонного пароля, в чем позволяет убедиться следующий экспериме,,т"

Passw:ls

K98PN*

Используя спецификатор "*s", необходимо доподлинно знать, в клК° 10 месте стека находится искомый указатель. В противном случае ироизо


секреты проектирования shell-кода .——-

щение к незапланированной области памяти. Большинство локальных переменных, находящихся в стеке, содержат значения, не превышающие 40000П1, поэтому попытка использовать их в качестве указателя под операционной системой Microsoft Windows NT приведет к исключению. Злоумышленник может использовать это обстоятельство для блокирования вычислительных систем или нарушения их нормальной работы.

Можно ли предотвратить угрозу раскрытия секретной информации переносом критичных к разглашению данных из стека в глобальные неременные? Прежде чем ответить на этот вопрос, необходимо заметить, что в некоторых операционных системах стек, данные и код программы находятся в одном и том же сегменте, поэтому механизмы получения содержимого локальных и глобальных переменных в таких случаях идентичны друг другу. Поэтому, если специальным образом не оговорено, на какой именно платформе будет выполняться разрабатываемая программа, бессмысленно спрашивать, каким образом влияет на ее защищенность использование глобальных неременных. Операционная система Microsoft Windows NT выделяет каждому процессу непрерывный регион адресного пространства, в которой уживаются код, данные и стек выполняющегося приложения. Поэтому теоретически возможно «дотянуться» до любой ячейки памяти и «подсмотреть» ее содержимое. Однако на практике осуществлению такой операции препятствует ограничение длины вводимой строки. Потребовалось бы ввести миллионы спецификаторов, прежде чем удалось бы достичь области памяти, занятой локальными переменными. Никакое приложение не допускает использование строк такой длины. Злоумышленник чаще всего ограничен не более сотни-другой символов, что позволяет просмотреть ему приблизительно четыреста-пятьсот бант содержимого стека2. Попадание секретных данных в столь непротяженную область настолько маловероятно, что трудно найти хотя бы одно приложение, подверженное подобной атаке.

Однако существует механизм, позволяющий прочитать содержимое практически любой ячейки памяти независимо от ее местоположения (разумеется, при условии, что приложение обладает правами на ее чтение). Если строка, введенная пользователем, помещается в стек (а именно так чаще всего и происходит), существует возможность «вручную» сформировать требуемый указатель и затем вывести строку, на которую он ссылается посредством спецификатора -*s".

Поскольку некоторые символы невозможно ввести с клавиатуры, то на искомый Указатель наложены некоторые ограничения. В частности, он не должен содер-*ать ни одного нуля, так как стандартные библиотеки языка Си интерпретируют н°ль как символ завершения строки. Но некоторые ухищрения позволяют обой-™ эти препятствия: злоумышленник может использовать в качестве старшего

, Базовый адрес .игрузки большинства приложении равен 0x400000. СиеЦификатор "%р «съедает» восемь бант, но сам занимает два байта, таким образом, в ста байтах Во1имой строки можно расположить не более пятидесяти спецификаторов "%(", которые ныне-ЛУГ "«чреда байт.


- ----——Jvijh

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

Таким образом, существует принципиальная возможность получения да1ш памяти атакуемой программы, что позволяет злоумышленнику нроанализпро вать систему защиты или по крайней мере выяснить, какое именно програкщ ное обеспечение использует жертва и что за «заплатки» у нее установлены Описанную выше уязвимость можно было бы отнести к забавным курьер если бы она ограничивалась одной лишь функцией printf. Но функции с перс. менным количеством аргументом — не редкость в программистской практике и многие из них используют ненадежные алгоритмы определения числа переданных параметров. Кроме того, существует множество «швейцарских» функций многоцелевого назначения. Например, функция open языка Perl в зависимости от символов, содержащихся в имени файла, может не только открывать файлы, по и запускать другие приложения, клонировать манипуляторы, выдавать содержимое директории и т. д.

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

Достаточно очевидно, что число переданных аргументов может быть не равно количеству занесенных в стек машинных слов, но вовсе не факт, что размер машинного слова равен размеру машинного слова. Такая путаница объясняется тем, что термин «машинное слово» в одних случаях равен разрядности процессора, а в других приравнивается к двум байтам. Поэтому использование nargs порождает совершенно непереносимый код, работоспособность которого может быть нарушена даже изменением некоторых опций компилятора! Некоторые разработчики предлагают собственный вариант реализации nargs. который сводится к следующему алгоритму: из стека извлекается адрес возврат из функции, и, исходя из предположения, что он указывает на команду наподобие ADD ESP, хх, производится попытка определить значение хх, равное колтчС ству байт, помещенных в стек перед вызовом функции. Недостатки такого при-ема следующие: он не переносим на отличные от Intel 80x86 платформа-современные компиляторы ведут себя не так, как пять-десять лет назад И гене-рируют чрезвычайно запутанный код, допускающий дисбаланс стека пан»*0 тором промежутке, отчего процедура анализа количества переданных функиИ" аргументов по сложности приближается к самому компилятору. Иногда можно встретить рекомендации последним аргументом переДаваТ функции нулевой указатель, позволяющий определить количество испоДЬЗ}е

1 Том самым он откроет доступ к коду и данным 32-разрялных приложении, исполняющих*" "" управлением операционной системы Windows NT, поскольку большинство из них растюл1*1" в памяти но адресу выше 0x00401000.



0 ... 51 52 53 54 55 56 57 ... 102