2012-04-09 2 views
1

Почему этот код не защищен?Зачем нужен этот код?

#include <stdio.h> 
int main(int argc, char *argv[]) 
    { 
     printf(argv[1]); 
     printf("\n"); 
     return 0; 
    } 
+12

Зачем нам делать домашнее задание для вас? –

+3

http://en.wikipedia.org/wiki/Uncontrolled_format_string –

ответ

5

printf будет обрабатывать свой первый параметр, глядя на вещи, как %d и %s.

Исходя из этих значений, он получит больше данных из стека и распечатает его.

Так что, если кто-то назвали свою программу:

a.out "%d %d %d %d %d %d %d %d %d %d %d %d" 

Они могут просмотреть раздел стека вызовов вашего компьютера.

Если они получили еще более творческий характер с помощью спецификатора формата, возможно, они могли бы сбросить что-то важное, например, номер кредитной карты или пароль.

+1

с '% n' вы даже можете писать где угодно в памяти – ouah

+0

Да, что я думал, но он печатает только%, потому что он печатает argv [1], вот и все. – 0x90

+0

Это относительно мягкий; '% n' может привести к активному повреждению (например, изменить поток управления). –

4

Рассмотрим, что первый аргумент printf управления (подсказка: printf не просто читать свои входные аргументы).

1

Поскольку плакат спросил для примера, что %n делает:

Путь Строка формата printf может изменение памяти с помощью опции %n; конкретное значение, которое нужно записать, может быть получено с использованием спецификаторов ширины формата «мудро». В качестве теста:

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    int *q = (int *)argv[0]; 
    printf("%1$300000d%5$n", 
     123,   // %1 - 1st param (formatted as '300000d') 
     0,   // %2 - 2nd param (unused) 
     0,   // %3 - 3rd param (unused) 
     0,   // %4 - 4th param (unused) 
     argv[0]); // %5 - 5th param (written to via 'n') 

    printf("\nNow *q == %d\n", *q); 

    return 0; 
} 

Если запустить это и смотреть последнюю строку вывода, он будет печатать Now *q == 300000 (протестировано на Linux).

Я использую довольно неизвестный позиционного синтаксис формата (% < пос > $ <FMT>) для printf() здесь для того, чтобы показать, как можно пропустить аргументы выбрать один модифицировать без необходимости использовать какой-либо «неинтересных».

Я оставлю это для экспериментов с читателями, чтобы выяснить, что printf() рассматривает как «аргументы» для вызова типа printf(argv[1]). Ответ на этот вопрос зависит от calling conventions (или связанного с ним, ABI для вашей системы) и отличается для 32/64-разрядных Windows/Linux/MacOSX и т. Д.

Смежные вопросы