Информационная безопасность



              

Неизвестная уязвимость функции printf - часть 3


off aXX ('%x %x') (строка спецификаторов) var_4 ('a') (аргумент функции printf)

var_8 ('b') (локальная переменная) var_4 ('a') (локальная переменная)

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

Для поддержки функций с переменным количеством аргументов в языке Си был принят обратный порядок заталкивания параметров в стек, т.е. самый левый аргумент заносится в последнюю очередь и оказывается на верхушке стека. Было бы замечательно, если бы компилятор напоследок передавал бы функции число используемых аргументов или, по крайней мере, сообщал бы их суммарный размер (тем более, что технически в этом нет ничего затруднительного). Но, увы! Разработчики языка не реализовали такой механизм, и отсюда следует неутешительное заключение о принципиальной невозможности защиты содержимого стека материнской функции. Дочерняя функция может беспрепятственно обращаться к любой ячейке стека – от верхушки до самого низа, читая как "свои", так и "чужие" данные.

При вызове “printf("%x %x\n",a)“ функция извлекает из стека на одно слово больше, чем было ей передано, и в результате происходит вторжение в область памяти, занятой локальными переменными материнской функции. Переменная “b” принимается за аргумент функции и выводится на экран. (В зависимости от используемого компилятора в заданном месте стека может оказаться все что угодно, например переменная “a”, сохраненные значения регистров общего назначения, "черная дыра" – область памяти, отведенная для выравнивания данных и т.д.).

По идее программист должен следить за тем, чтобы каждому спецификатору соответствовала "своя" переменная, однако в некоторых ситуациях отсутствие одного из аргументов не приводит к нарушению работоспособности программы.


Содержание  Назад  Вперед