Защита от уязвимости формата строки - PullRequest
3 голосов
/ 30 декабря 2008

Что такое «уязвимость формата строки» в системе Windows, как она работает и как ее защитить?

Ответы [ 2 ]

4 голосов
/ 30 декабря 2008

Атака форматной строки, в простейшем случае, такова:

char buffer[128];
gets(buffer);
printf(buffer);

Также существует уязвимость переполнения буфера, но суть в следующем: вы передаете ненадежные данные (от пользователя) в printf (или одному из его двоюродных братьев), который использует этот аргумент в качестве строки формата.

То есть: если пользователь вводит "% s", вы получаете уязвимость раскрытия информации, потому что printf будет обрабатывать ввод пользователя как строку формата и будет пытаться напечатать следующую вещь на стек как строка. Это как если бы твой код сказал printf("%s");. Поскольку вы не передали никаких других аргументов printf, он отобразит что-то произвольное.

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

Это все плохо, и это одна из причин, почему вы должны быть чрезвычайно осторожны при использовании printf и двоюродных братьев.

Что вы должны сделать, это:

printf("%s", buffer);

Это означает, что ввод пользователя никогда не обрабатывается как строка формата, поэтому вы защищены от этого конкретного вектора атаки.

В Visual C ++ вы можете использовать аннотацию __Format_string, чтобы сказать ей, что нужно проверять аргументы printf. %n по умолчанию запрещено. В GCC вы можете использовать __attribute__(__printf__) для того же самого.

2 голосов
/ 30 декабря 2008

В этом псевдокоде пользователь вводит некоторые символы для печати, например, «привет»

string s=getUserInput();
write(s)

Это работает как задумано. Но так как запись может форматировать строки, например

int i=getUnits();
write("%02d units",i);

выходы: "03 единицы". Что делать, если пользователь в первую очередь написал «% 02d» ... поскольку в стеке нет параметров, будет получено что-то еще. Что это такое, и если это проблема или нет, зависит от программы.

Простое исправление - заставить программу выводить строку:

write("%s",s);

или используйте другой метод, который не пытается отформатировать строку:

output(s);

a ссылка на википедию с дополнительной информацией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...