Читаем Защита от хакеров корпоративных сетей полностью

Классическую удаленную уязвимость форматирующей строки можно найти в версиях программы rwhoisd 1.5.7.1 и более ранних. Она позволяла удаленному злоумышленнику после подключения к серверу выполнить произвольный код. Впервые об уязвимости стало известно благодаря сообщению списка рассылки Bugtraq. Заархивированное сообщение может быть найдено по адресу www.securityfocus.com/archive/1/222756.

Для того чтобы понять уязвимость форматирующей строки программы rwhoisd, следует внимательно изучить ее исходный текст. В главе рассмотрена версия программы 1.5.7.1. На момент написания книги ее можно было загрузить по адресу www.rwhois.net/ftp.

Уязвимость проявляется во время вывода сообщения об ошибке при неверном задании аргумента команды – soa в командной строке.

Сообщение об ошибке формируется и выводится функцией print_error. Эта функция вызывается повсюду в исходном тексте программы сервера для обработки ошибок клиента или пользователя. Входными параметрами функции являются номер ошибки в формате целого числа, форматирующая строка и переменное число аргументов.

Исходный текст этой функции может быть найден в файле common/ client_msgs.c (путь указан относительно директории, созданной во время восстановления из архива исходного текста программы версии 1.5.7.1).

/* prints to stdout the error messages. Format: %error ### message

text, where ### follows rfc 640 */

void

print_error(va_alist)

va_dcl

{

va_list list;

int i;

int err_no;

char *format;

if (printed_error_flag)

{

return;

}

va_start(list);

err_no = va_arg(list, int);

for (i = 0; i < N_ERRS; i++)

{

if (errs[i].err_no == err_no)

{

printf(“%%error %s”, errs[i].msg);

break;

}

}

format = va_arg(list, char*);

if (*format)

{

printf(“: ”);

}

vprintf(format, list);

va_end(list);

printf(“\n”);

printed_error_flag = TRUE;

}

В исходном тексте жирным шрифтом отмечено место передачи входных данных программы функции vprintf. Причиной уязвимости форматирующей строки является не функция vprintf, а то, как ее используют. Функция print_ error полагается на то, что вызвавшая ее функция передаст ей правильные входные данные: форматирующую строку и соответствующие ей переменные.

В примере рассматривается функция print_error, потому что она наглядно демонстрирует причины возникновения уязвимостей форматирующей строки, которые могут быть использованы злоумышленником. Во многих программах есть функции, похожие на print_error. В некотором смысле функция print_error подобно функции syslog служит оболочкой для выдачи диагностики об ошибке. Ее параметрами являются код ошибки и параметры, аналогичные параметрам функции printf. Как уже обсуждалось в начале главы, проблема состоит в том, что программисты могут забыть о возможности передачи злоумышленником форматирующей строки через входные параметры.

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

Те из читателей, которые загрузили исходный текст программы, смогут найти разбираемый фрагмент кода в функции
soa_parse_args из файла с исходным текстом server/soa. Подготовительные действия функции сокращены до минимума. В 53-ей строчке вызывается функция print_error (строка выделена жирным шрифтом), которая может стать источником серьезных ошибок:

..

auth_area = find_auth_area_by_name(argv[i]);

if (!auth_area)

{

print_error(INVALID_AUTH_AREA, argv[i]);

free_arg_list(argv);

dl_list_destroy(soa_arg);

return NULL;

}

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже