C: Чтение большего количества байтов, чем строка формата с вставкой строки форматирования

В статье Использование уязвимостей форматирования строк авторы приводят следующий пример кода, где input - это нефильтрованный ввод пользователя.

char outbuf[512];
char buffer[512];
sprintf (buffer, "ERR Wrong command: %400s", input);
sprintf (outbuf, buffer);

Затем они объясняют, что, используя специальную строку формата в качестве входных данных, они могут обойти ограничение %400s:

"%497d\x3c\xd3\xff\xbf<nops><shellcode>"
</shellcode></nops>

Это создает строку длиной 479 символов. Однако я не могу найти объяснение того, как %479d обходит ограничение %400s. Как этот ввод позволяет sprintf писать строку длиной более 400 символов?

2 ответа

Второй sprintf() переполняет outbuf, потому что он использует строку формата, сгенерированную первым sprintf(), и размещение "% 497d" в этой строке делает печать целого поля 497- char (дополненное пробелы, чтобы получить полную ширину). Это вместе с остальной частью этой строки будет превышать размер буфера 512 char outbuf. Это также заставит его попытаться прочитать целочисленный аргумент, который фактически не передается функции (2nd sprintf()).


Проблема заключается в том, что если input содержит маркеры %, то buffer будет содержать те метки % (после первого sprintf()), а затем используя вторую sprintf(), строку формата 'buffer, а маркеры % в нем будут интерпретироваться, даже если нет аргументов для интерполяции в outbuf. Чтобы избежать проблемы:

snprintf(outbuf, sizeof(outbuf), "%s", buffer);

или

strcpy(outbuf, buffer);

В этом контексте snprintf() является излишним, но он отделяет механизм до основ.

licensed under cc by-sa 3.0 with attribution.