Первое, что должна сделать программа атаки, – это подключиться к сервису сервера RWHOIS и найти форматирующую строку в стеке. После подключения к сервису функция brute_force() программы атаки отсылает ему форматирующую строку. В начало форматирующей строки записана константа 0x6262626262, которая является признаком ее начала. Функция brute_force() включает в форматирующую строку такие спецификации преобразования, которые увеличивают размер выводимой области стека. Сервис во время обработки переданной форматирующей строки последовательно извлекает из стека слова и возвращает их обратно программе атаки. Получив ответ сервера, программа атаки сравнивает полученные слова с признаком начала форматирующей строки и находит форматирующую строку. Использование константы 0x6262626262 в качестве признака начала форматирующей строки позволяет упростить алгоритм работы, не думая о возможных осложнениях из-за выравнивания данных в памяти.
if((*ptr == “0”) && (*(ptr+1) == “x”))
{
memcpy(segment,ptr,10);
segment[10] = “\0”;
chekit = strtoul(segment,NULL,16);
if(chekit == FINDME)
{
printf(“*b00m*: found address #1: %i words
away.\n”,i);
foundit = i;
return foundit;
}
ptr += 10;
}
Содержимое стека просматривается с помощью спецификаций преобразования %010p. Спецификация формата %010p выводит очередное слово стека в восьмисимвольном шестнадцатеричном представлении с предшествующими символами 0x. С помощью функции библиотеки языка C strtoul() каждая из выведенных строк преобразуется в длинное целое двоичное число без знака.
Главное, что должна сделать программа, – это выполнить произвольный программный код. Для этого ей нужно подменить величины, которые могут указывать на выполнимые команды. Одной из них является адрес точки возврата из функции. Ранее уже отмечалось, что при переполнении буфера часто перезаписываются адреса возврата из функций. Адреса возврата перезаписываются по двум причинам. Во-первых, они находятся в стеке, а во-вторых, при переполнении буфера их можно перезаписать. В рассматриваемой программе адрес возврата из функции подменяется на адрес злонамеренного программного кода, прежде всего из-за легкости, с которой выполняется эта операция.
В программе атаки переписывается адрес возврата функции print_error(), который при вызове функции сохраняется в стеке. Поскольку программа предназначена только для демонстрации возможности подобных действий и на момент тестирования программы атаки адрес возврата из функции print_ error() находился в стеке сервиса по адресу 0xbffff8c8, то адрес перезаписываемой области в программе атаки задан символической константой TARGET.
После определения программой атаки адреса форматирующей строки формируется новая строка со спецификациями преобразования
%n.Для подмены адреса возврата спецификациям
%nдолжны соответствовать параметры, через которые передается адрес перезаписываемой области данных. Для поиска нужных адресов используются спецификации преобразования
%xс указанием ширины поля, которые просматривают нужное число слов в стеке. В программе атаки необходимую последовательность спецификаций преобразования
%xфункция
get_str()формирует автоматически по результатам работы функции
brute_force().
for(i = 0;i
{
strncat(str,“%x”,2); // work our way to where target is
}
В переменной num хранится число просмотренных слов стека, предшествующих форматирующей строке. Число просмотренных слов определяется функцией brute_force(). Осталось определить адрес записи. Адрес возврата перезаписывается ранее обсуждавшимся способом многократной записи. Для формирования четырехбайтного адреса используют четыре операции записи с различным смещением от начала перезаписываемой области данных. Адреса каждого из четырех байтов перезаписываемой области помещаются в отсылаемую строку:
*((long *)(str+8)) = TARGET; // target
*((long *)(str+16)) = TARGET+1;
*((long *)(str+24)) = TARGET+2;
*((long *)(str+32)) = TARGET+3;
str[36] = “\0”;
Следующий шаг состоит в записи правильных величин, определяющих адрес злонамеренного управляющего программного кода в стеке. Поскольку программа атаки только демонстрирует обсуждаемые возможности, то в ней в качестве адреса злонамеренного управляющего программного кода используется постоянный адрес 0xbffff99d. При формировании адреса 0xbffff99d в каждый байт выделенной для записи области помещаются младшие разряды величин, специально подобранных программой атаки:
TARGET – 9d
TARGET+1 – f9
TARGET+2 – ff
TARGET+3 – bf
Ранее уже обсуждалось использование спецификаций преобразования %n для записи младших разрядов данных. В последовательные возрастающие адреса памяти, задаваемые символическими константами TARGET, TARGET+1, TARGET+2 и TARGET+3, записываются младшие байты специально подобранных величин, которые совпадают с одним из байтов адреса программного кода. Например, при использовании спецификации преобразования %125x в область памяти, адрес которой равен значению константы TARGET, записывается величина, младший байт которой совпадает с младшим байтом адреса программного кода. Указав в спецификации преобразования %x ширину выводимого поля и применив способ многократной записи, можно сформировать в нужной области памяти адрес программного кода:
Читать дальше
Конец ознакомительного отрывка
Купить книгу