При вызове функции print_error()
ей передается параметр argv[i], который является не чем иным, как форматирующей строкой. В конечном счете эта форматирующая строка будет передана функции vprintf() для обработки, как об этом уже предварительно говорилось. Средствам контроля исходного текста программ это место должно показаться очень подозрительным и подходящим для организации атаки. Для безопасной передачи параметров следовало бы вызвать функцию print_error() следующим способом:print_error(INVALID_AUTH_AREA, «%s», argv[i]);
При этом способе вызова i-й аргумент программы argv[i]
передается функции print_error() как переменная, соответствующая спецификации преобразования %s. При этом исключается всякая возможность передачи функции print_error() злонамеренной спецификации преобразования, которая могла бы непредусмотренным образом обработаться функцией vprintf(), вызванной print_error(). Строка argv[i] — это не что иное, как аргумент команды – soa, передаваемой клиентом серверу. Подводя итог, следует сказать, что когда клиент соединяется с сервером rwhoisd
и передает неверную команду – soa, функция print_error() выводит сообщение об ошибке. При этом выполняется следующая последовательность действий.1. Сервер получает аргумент команды – soa
и вызывает для ее обработки функцию soa_directive(). 2. Функция soa_directive()
передает команду функции soa_parse_args() для обработки.3. При обнаружении ошибки функция soa_parse_args()
передает код ошибки и командную строку функции print_error() в качестве аргументов форматирующей строки.4. Функция print_error()
передает форматирующую строку с содержащимися в ней данными клиента функции vprintf(), о которой уже говорилось, и вызывает ее.Теперь ясно, что удаленные клиенты могут передать функции vprintf() форматирующую строку, которая является аргументом команды – soa. При подключении к серверу и передаче ему злонамеренной форматирующей строки злоумышленник может записать нужные ему данные в память программы сервера.Тестирование программ способом случайной форматирующей строки
Поместив в исходный текст программы потенциально уязвимую форматирующую строку, продемонстрируем способы ее использования злоумышленником при помощи входных данных программы и изучим реакцию сервера на них.
В большинстве случаев можно создать такие условия работы программы, когда о наличии в программе уязвимости форматирующей строки можно будет судить по ее поведению. Если уязвимая программа выводит отформатированную строку, то наличие в ней уязвимости форматирующей строки очевидно. При отсутствии вывода о присутствии в программе уязвимости форматирующей строки можно судить по реакции программы на различные спецификации форматов.
Если при вводе входных данных со спецификациями преобразования %n%n
процесс аварийно завершается, то, вероятнее всего, это происходит из-за нарушения доступа к памяти при попытке записи по неверным адресам памяти, прочитанным из стека. Передав программе, в которой не предусмотрен вывод отформатированной строки, через ее входные данные спецификации форматов %n%n, можно определить, уязвима она или нет. Если процесс аварийно завершается, не возвращает управления или неожиданно завершается, то вполне вероятно, что причиной этого является уязвимость форматирующей строки.В рассматриваемом примере сервер возвращает клиенту сообщение об ошибке в виде отформатированной строки. Это облегчает действия злоумышленника, который ищет способ проникнуть на хост. В следующем примере приведен образец вызова программы rwhoisd, которая демонстрирует ошибку в форматирующей строке:
[dma@victim server]$ nc localhost 4321
%rwhois V-1.5:003fff:00 victim (by Network Solutions, Inc.
V-1.5.7.1)
-soa am_%i_vulnerable
%error 340 Invalid Authority Area: am_-1073743563_vulnerable