Рубрики

Уязвимость форматирования строки и предотвращение с примером

Строка формата — это строка ASCII, которая содержит текст и параметры формата.

Пример:

// A statement with format string
printf("my name is : %s\n", "Akash");

// Output
// My name is : Akash

Есть несколько строк формата, которые определяют вывод в C и многих других языках программирования, но мы фокусируемся на C.

Уязвимости форматной строки представляют собой класс ошибок, использующих преимущество легко предотвратимой ошибки программиста. Если программист передает контролируемый злоумышленником буфер в качестве аргумента для printf (или любой из связанных функций, включая sprintf, fprintf и т. Д.), Злоумышленник может выполнять запись в произвольные адреса памяти. Следующая программа содержит такую ошибку:

// Простая C программа с форматом
// строковая уязвимость
#include<stdio.h>

  

int main(int argc, char** argv)

{

    char buffer[100];

    strncpy(buffer, argv[1], 100);

  

    // Мы передаем командную строку

    // аргумент для 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 (nil) 0xffffdcd4 0xffffdc74 (nil) 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 и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

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

Рекомендуемые посты:

Уязвимость форматирования строки и предотвращение с примером

0.00 (0%) 0 votes