Ранее уже обсуждалось использование спецификаций преобразования %n
для записи младших разрядов данных. В последовательные возрастающие адреса памяти, задаваемые символическими константами TARGET, TARGET+1, TARGET+2 и TARGET+3, записываются младшие байты специально подобранных величин, которые совпадают с одним из байтов адреса программного кода. Например, при использовании спецификации преобразования %125x в область памяти, адрес которой равен значению константы TARGET, записывается величина, младший байт которой совпадает с младшим байтом адреса программного кода. Указав в спецификации преобразования %x ширину выводимого поля и применив способ многократной записи, можно сформировать в нужной области памяти адрес программного кода:strncat(str,“%227x”,5); // padding
strncat(str,“%n”,2); // first write
strncat(str,“%92x”,4); // padding
strncat(str,“%n”,2); // second write
strncat(str,“%262x”,5); // padding
strncat(str,“%n”,2); // third write
strncat(str,“%192x”,5); // padding
strncat(str,“%n”,2); // fourth writeСледует отметить, что используемые в спецификации преобразования значения ширины выводимого поля полностью зависят от общего числа символов в отформатированной строке. При выводе отформатированной строки значение ширины поля можно определить автоматически программным способом.
Как только адрес возврата функции будет переписан, функция vfprintf
завершится обычным образом, злонамеренный управляющий программный код будет выполнен, а функция print_error завершена. На рисунке 9.2 показан пример успешного использования уязвимости форматирующей строки.
Рис. 9.2. Использование уязвимости форматирующей строки программы rwhoisd для проникновения на хостНиже приведен исходный текст программы атаки: