✍️ Статья Уязвимость форматирующей строки

The 146X Project Dublikat Web Studio Avram Lincoln AL Service Navigator Knyaz

Tartuga

💰 Проверенный продавец
Регистрация
19.12.2019
Сообщения
93
Ошибка форматирования строки стала известна еще в далеком 1989 году при работе по fuzz testing в Университете Висконсина. Но только лишь спустя 10 лет в 1999 году было обнаружено использование данной уязвимости в качестве вектора атака в ходе конференции по безопасности ProFTPD-демона Вашингтонского университета. Это привело к первой публикации данной уязвимости в сентябре 1999 года в списке Bugtraq. Но по настоящему массово данная уязвимость стала эксплуатироваться лишь в 2000 году. Было написано множество эксплоитов на базе форматирования строки. Ошибки обнаруживались как в больших популярных серверных приложениях, так и в простых утилитах.



*(Все примеры далее буду приводить на С)

Итак, форматирующая строка - простое представление строки ASCII контролируемым образом с использованием спецификаторов формата. Чтобы преобразовать типы данных в строке в представление String, используются такие функции, как printf , vprintf , scanf. Уязвимость форматирующих строк появляется несколькими способами. Вызов * printf () без спецификатора формата является опасным и может быть использован. Например, printf (input) можно использовать. Результат данного вызова позволяет злоумышленнику заглянуть в стек, тк входная строка будет использоваться в качестве спецификатора формата. Злоумышленник может заполнить входную строку спецификаторами формата и начать считывать значения стека, поскольку остальные параметры будут удалены из стека. В худшем случае эта уязвимость позволит злоумышленнику записать произвольное значение в память запущенной программы.



Проведение атаки:

Выводимое функцией количество символов будет храниться в адресе аргумента, следующего за самой строкой формата. Но в коде, имеющем уязвимость, злоумышленник может предоставить только одну строку (опустив второй аргумент функции printf). Функция printf возьмет очередное значение в стеке и использует его в качестве второго аргумента. Взломщик может также заставить функцию printf воспользоваться следующим значением в стеке, предоставив в качестве ввода, к примеру, такую форматирующую строку: %08x

Это означает, что printf выведет следующий аргумент в виде 8-разрядного шестнадцатеричного числа.

Рассмотрим далее на примере данного кода:

#include<stdio.h>

int main(int argc, char** argv)
{
char buffer[100];
strncpy(buffer, argv[1], 100);

// We are passing command line
// argument to printf
printf(buffer);

return 0;
}



ТК printf имеет использует строку формата для определения количества аргументов, то злоумышленник может передать строку: %p%p%p%p%p%p%p%p%p%p%p%p%p%p%p

%p - внешнее представление указателя на недействительность printf будет печатать следующие 15 адресов в стеке, думая, что они являются его аргументами
Вот что получится:

$ ./a.out "%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p"
0xffffdddd 0x64 0xf7ec1289 0xffffdbdf 0xffffdbde (nil) 0xffffdcc4 0xffffdc64 (nil) 0x25207025 0x70252070 0x20702520 0x25207025 0x70252070 0x20702520

C 10 аргумента идет чередование - это введенные наши %p в стеке. Теперь мы можем передать наше значение. Передадим наше значение, добавив AAAA

$ ./a.out "AAAA%p%p%p%p%p%p%p%p%p%p%p"
AAAA0xffffdde8 0x64 0xf7ec1289 0xffffdbef 0xffffdbee (nil) 0xffffdcd4 0xffffdc74 (nil) 0x41414141

Итак, мы передали 0x41414141 - 16-ю запись AAAA



Безопасность:

Во избежание подобных уязвимостей необходимо указывать строку формата как часть программы, а не как вход и сделать строку формата константой, если будет такая возможность.
 

📌 Золотая реклама

AnonPaste

Верх