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



              

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


Такое поведение объясняется тем, что, встретив спецификатор “%s”, функция printf ожидает увидеть указатель на строку, но не саму строку. В результате происходит обращение по адресу 0x5038384B (“K98PN” в символьном представлении), который находится вне пределов досягаемости программы, что и вызывает исключение.

Спецификатор “%s” пригоден для отображения содержимого указателей, ссылающихся на строки или другие читабельные структуры данных. Его использование продемонстрировано в следующем примере:

#include <stdio.h>

#include <string.h>

#include <malloc.h>

void main() { FILE *f; char *pass; char *_pass; pass= (char *)malloc(100); _pass=(char *)malloc(100); if (!(f=fopen("buff.psw","r"))) return; fgets(_pass,100,f); _pass[strlen(_pass)-1]=0; printf("Passw:");fgets(pass,100,stdin); pass[strlen(pass)-1]=0; // Код, проверяющий истинность пароля, введенного // пользователем, для упрощения понимания, опущен printf(pass); }

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

В приведенном примере указатель _pass оказался расположен на верхушке стека, поэтому использование спецификатора “%s” приводит к выводу на экран эталонного пароля, в чем позволяет убедиться следующий эксперимент:

Passw:%s K98PN*

Используя спецификатор “%s”, необходимо доподлинно знать, в каком именно месте стека находится искомый указатель. В противном случае произойдет обращение к незапланированной области памяти. Большинство локальных переменных, находящихся в стеке, содержат значения, не превышающие 0x40000, поэтому попытка использовать их в качестве указателя под операционной системой Microsoft Windows NT приведет к исключению.


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