Уязвимость форматной строки и предотвращение с примером
Строка формата - это строка ASCII, содержащая текст и параметры формата.
Пример:
// Оператор со строкой формата printf ("меня зовут:% s n", "Акаш"); // Выход // Меня зовут: Акаш
Есть несколько строк формата, которые определяют вывод на C и многих других языках программирования, но мы сосредоточены на C.
Format string vulnerabilities are a class of bug that take advantage of an easily avoidable programmer error. If the programmer passes an attacker-controlled buffer as an argument to a printf (or any of the related functions, including sprintf, fprintf, etc), the attacker can perform writes to arbitrary memory addresses. The following program contains such an error:
// A simple C program with format // string vulnerability #include<stdio.h> int main( int argc, char ** argv) { char buffer[100]; strncpy (buffer, argv[1], 100); // We are passing command line // argument to printf printf (buffer); return 0; } |
Поскольку printf имеет переменное количество аргументов, он должен использовать строку формата для определения количества аргументов. В приведенном выше случае злоумышленник может передать строку «% p% p% p% p% p% p% p% p% p% p% p% p% p% p% p» и заставить printf думать, что это имеет 15 аргументов. Он наивно напечатает следующие 15 адресов в стеке, думая, что они его аргументы:
$ ./a.out "%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p" 0xffffdddd 0x64 0xf7ec1289 0xffffdbdf 0xffffdbde (nil) 0xffffdcc4 0xffffdc64 (nil) 0x25207025 0x70252070 0x20702520 0x25207025 0x70252070 0x20702520
Примерно с 10 аргументами в стеке мы можем увидеть повторяющийся шаблон 0x252070 - это наши% ps в стеке! Мы начинаем нашу строку с AAAA, чтобы увидеть это более подробно:
$ ./a.out "AAAA% p% p% p% p% p% p% p% p% p% p" AAAA0xffffdde8 0x64 0xf7ec1289 0xffffdbef 0xffffdbee (ноль) 0xffffdcd4 0xffffdc74 (ноль) 0x41414141
0x41414141 - это шестнадцатеричное представление AAAA. Теперь у нас есть способ передать произвольное значение (в данном случае мы передаем 0x41414141) в качестве аргумента printf. На этом этапе мы воспользуемся еще одной функцией форматной строки: в спецификаторе формата мы также можем выбрать конкретный аргумент. Например, printf («% 2 $ x», 1, 2, 3) напечатает 2. Как правило, мы можем использовать printf («% $ x»), чтобы выбрать произвольный аргумент для printf. В нашем случае мы видим, что 0x41414141 является 10-м аргументом printf, поэтому мы можем упростить нашу строку1:
$ ./a.out "AAAA% 10 $ p" AAAA0x41414141
Предотвращение уязвимостей строки формата
- Всегда указывайте строку формата как часть программы, а не как ввод. Большинство уязвимостей строки формата решаются путем указания «% s» в качестве строки формата, а не использования строки данных в качестве строки формата.
- Если возможно, сделайте строку формата постоянной. Извлеките все переменные части как другие аргументы вызова. Трудно сделать с некоторыми библиотеками интернационализации
- Если две вышеупомянутые практики невозможны, используйте средства защиты, такие как Format_Guard. Редко во время разработки. Возможно, это способ продолжить использовать устаревшее приложение и снизить расходы. Повысьте уверенность в безопасности стороннего приложения.
использованная литература
https://www.owasp.org/index.php/Format_string_attack
https://www.exploit-db.com/docs/28476.pdf
Эта статья предоставлена Акашем Шараном . Если вам нравится GeeksforGeeks, и вы хотели бы внести свой вклад, вы также можете написать статью с помощью provide.geeksforgeeks.org или отправить ее по электронной почте на deposit@geeksforgeeks.org. Посмотрите, как ваша статья появляется на главной странице GeeksforGeeks, и помогите другим гикам.
Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по теме, обсужденной выше.