Эксплоит под wu-ftpd

kas1e

Xakep, номер #052, стр. 052-054-1

Или format string уязвимости

Сегодня мы продолжим знакомство с различными уязвимостями и рассмотрим ошибку типа format string. Format string появился на свет в июне 1999 года, а уже в июне 2000 количество эксплоитов, основанных на этой уязвимости, достигло критической отметки. Они проявлялись как в маленьких утилитах, так и в огромных серверных приложениях. В течение года производители софта пытались закрывать на это глаза, но в конце концов опомнились. Как ты догадываешься, большинство ошибок в программном обеспечении объясняется кривым программированием или ленью. Format string не исключение, как станет понятно при более близком знакомстве. Итак, поехали.

Работа у программиста довольно напряженная, необходимо следить за каждым байтом, оценивать ситуацию, представлять различные возможности поведения программы и т.д. К примеру, часто приходится использовать в программе 'C' строки, оканчивающиеся нулевым байтом, и не всегда есть возможность уследить за таким кодом. Отсюда возникают разные проблемы. Так и в случае с format string. Скажем, программист решает сэкономить на размере и не указывает дополнительных 'форматных' аргументов:

printf(string); // выводим строку (без указания каким способом выводить)

вместо:

printf(%s, string); // выводим строку (с указанием способа)

Видимо не все программисты знают, что если форматный аргумент не указан, то их поиск будет производиться в любом случае. И если какой-то из них будет найден, то в стеке произойдут соответствующие преобразования (из предыдущих статей по buffer overflow можно представить, чего добиваются люди, имея доступ к стеку). Однако нас больше интересует конкретный символ форматирования. Это %n. Как ни странно, при описании символов форматирования он почти никогда не упоминается. А вот что говорится о нем в манах:

"Число символов, выведенных до этого момента, сохраняется по адресу целого числа, указанному аргументом-указателем типа int * (или variant). Преобразование аргументов не происходит".

Что же это значит? А то, что данный аргумент позволяет производить запись в переменную-указатель, даже если она используется в функции для вывода на экран! Т.е. можно записывать данные по адресу, на который указывает второй аргумент. Кроме этого, он подсчитывает еще каждый символ, появляющийся в самой строке форматирования. Возьмем простейший пример:

#include <stdio.h>

void main()

{

int a; // целая переменная 'a'

char *buff = "1111111111"; // символьный буфер 'buff' с десятью единицами

printf("%s%n\n", buff, &a); // выводим строку "1111111111",

// которая содержит 10 символов

printf("a = %d\n", a); // выводим записанное значение (число символов)

// записанное в целую переменную 'a'

}

Откомпилим и запустим:

# gcc printf_test.c -o printf_test

# ./printf_test

1111111111

a = 10

Да, %n действительно подсчитывает символы. Но есть еще один нюанс - подсчет не всегда бывает таким точным :). Сразу скажу, что %n считает количество символов, которые будут выведены предположительно. Т.е. если ты, скажем, через snprintf ограничишь буфер 100 символами, а потом повторишь строки из предыдущего примера, то переменная 'a' будет показывать вместо 10 - 100. Вот более детальное объяснение: сначала %n подсчитывает количество символов, потом записывает по адресу, указанному во втором аргументе, и только потом строка уменьшается при копировании в буфер. Т.е. сначала строка расширяется, потом считывается, а затем уменьшается ;).

Содержание  Вперед на стр. 052-054-2
Выпуски журнала "Xakep"
Журнал Хакер. Содержание номера #001Журнал Хакер. Содержание номера #002Журнал Хакер. Содержание номера #003Журнал Хакер. Содержание номера #004Журнал Хакер. Содержание номера #005Журнал Хакер. Содержание номера #006Журнал Хакер. Содержание номера #007Журнал Хакер. Содержание номера #008Журнал Хакер. Содержание номера #009Журнал Хакер. Содержание номера #010Журнал Хакер. Содержание номера #011Журнал Хакер. Содержание номера #012Журнал Хакер. Содержание номера #013Журнал Хакер. Содержание номера #014Журнал Хакер. Содержание номера #015Журнал Хакер. Содержание номера #016Журнал Хакер. Содержание номера #017Журнал Хакер. Содержание номера #018Журнал Хакер. Содержание номера #019Журнал Хакер. Содержание номера #020Журнал Хакер. Содержание номера #021Журнал Хакер. Содержание номера #022Журнал Хакер. Содержание номера #023Журнал Хакер. Содержание номера #024Журнал Хакер. Содержание номера #025Журнал Хакер. Содержание номера #026Журнал Хакер. Содержание номера #027Журнал Хакер. Содержание номера #028Журнал Хакер. Содержание номера #029Журнал Хакер. Содержание номера #030Журнал Хакер. Содержание номера #031Журнал Хакер. Содержание номера #032Журнал Хакер. Содержание номера #033Журнал Хакер. Содержание номера #034Журнал Хакер. Содержание номера #035Журнал Хакер. Содержание номера #036Журнал Хакер. Содержание номера #037Журнал Хакер. Содержание номера #038Журнал Хакер. Содержание номера #039Журнал Хакер. Содержание номера #040Журнал Хакер. Содержание номера #041Журнал Хакер. Содержание номера #042Журнал Хакер. Содержание номера #043Журнал Хакер. Содержание номера #044Журнал Хакер. Содержание номера #045Журнал Хакер. Содержание номера #046Журнал Хакер. Содержание номера #047Журнал Хакер. Содержание номера #048Журнал Хакер. Содержание номера #049Журнал Хакер. Содержание номера #050Журнал Хакер. Содержание номера #051Журнал Хакер. Содержание номера #052Журнал Хакер. Содержание номера #053Журнал Хакер. Содержание номера #054Журнал Хакер. Содержание номера #055Журнал Хакер. Содержание номера #056Журнал Хакер. Содержание номера #057Журнал Хакер. Содержание номера #058Журнал Хакер. Содержание номера #059Журнал Хакер. Содержание номера #060Журнал Хакер. Содержание номера #061Журнал Хакер. Содержание номера #062Журнал Хакер. Содержание номера #063Журнал Хакер. Содержание номера #064Журнал Хакер. Содержание номера #065Журнал Хакер. Содержание номера #066Журнал Хакер. Содержание номера #067Журнал Хакер. Содержание номера #068Журнал Хакер. Содержание номера #069Журнал Хакер. Содержание номера #070Журнал Хакер. Содержание номера #071Журнал Хакер. Содержание номера #072Журнал Хакер. Содержание номера #073Журнал Хакер. Содержание номера #074Журнал Хакер. Содержание номера #075Журнал Хакер. Содержание номера #076Журнал Хакер. Содержание номера #077Журнал Хакер. Содержание номера #078Журнал Хакер. Содержание номера #079Журнал Хакер. Содержание номера #080Журнал Хакер. Содержание номера #081Журнал Хакер. Содержание номера #082Журнал Хакер. Содержание номера #083Журнал Хакер. Содержание номера #084Журнал Хакер. Содержание номера #085Журнал Хакер. Содержание номера #086Журнал Хакер. Содержание номера #087Журнал Хакер. Содержание номера #088Журнал Хакер. Содержание номера #089Журнал Хакер. Содержание номера #090Журнал Хакер. Содержание номера #091Журнал Хакер. Содержание номера #092Журнал Хакер. Содержание номера #093Журнал Хакер. Содержание номера #094Журнал Хакер. Содержание номера #095Журнал Хакер. Содержание номера #096Журнал Хакер. Содержание номера #097Журнал Хакер. Содержание номера #098Журнал Хакер. Содержание номера #099Журнал Хакер. Содержание номера #100Журнал Хакер. Содержание номера #101Журнал Хакер. Содержание номера #102Журнал Хакер. Содержание номера #103Журнал Хакер. Содержание номера #104Журнал Хакер. Содержание номера #105Журнал Хакер. Содержание номера #106Журнал Хакер. Содержание номера #107Журнал Хакер. Содержание номера #108Журнал Хакер. Содержание номера #109Журнал Хакер. Содержание номера #110Журнал Хакер. Содержание номера #111Журнал Хакер. Содержание номера #112Журнал Хакер. Содержание номера #113Журнал Хакер. Содержание номера #114