A атака переполнения кучи аналогична атака переполнения буфера , за исключением того, что вместо перезаписи значений в стеке злоумышленник вытесняет данные в куче.
Обратите внимание, что в вашем коде есть два динамически распределяемых значения:
d = malloc(sizeof(struct data));
f = malloc(sizeof(struct fp));
Итак, d
теперь содержит адрес 128-байтового куска памяти в куче, а f
содержит адрес8-байтовый (при условии 64-битной машины) кусок памяти.Теоретически, эти два адреса могут быть далеко друг от друга, но, поскольку они оба относительно малы, вполне вероятно, что ОС выделяет один большой кусок непрерывной памяти и дает вам указатели, которые находятся рядом друг с другом.
Поэтому после запуска f->fp = printName;
ваша куча выглядит примерно так:
Примечание. Каждая строка имеет ширину 8 байт
| |
+------------------------+
f -> | <Address of printName> |
+------------------------+
| ▲ |
| 11 more rows |
| not shown |
| |
d -> | <Uninitialized data> |
+------------------------+
| |
Ваша первоначальная оценка того, гдеуязвимость исходит от правильно.d
указывает на 128 байтов памяти, но вы позволяете пользователю записать 256 байтов в эту область.В C нет механизма проверки границ, поэтому компилятор с радостью разрешает вам писать за границу памяти d
.Если f
находится рядом с d
, вы упадете за край d
и в f
.Теперь злоумышленник может изменить содержимое f
, просто записав в d
.
Чтобы воспользоваться этой уязвимостью, злоумышленник передает адрес некоторого кода, который был написан для * 1032.* повторяя это для всех 256 байтов ввода.Если злоумышленник сохранил некоторый вредоносный код по адресу 0xbadc0de
, он подает 0xbadc0de
в стандартный ввод 32 раза (256 байт), так что куча перезаписывается.
| 0xbadc0de |
+-------------+
f -> | 0xbadc0de |
+-------------+
| ... |
| 0xbadc0de |
| 0xbadc0de |
d -> | 0xbadc0de |
+-------------+
| |
Затем ваш код достигаетстрока
f->fp();
, которая является вызовом функции с использованием адреса, хранящегося в f
.Машина переходит в область памяти f
и извлекает сохраненное там значение, которое теперь является адресом вредоносного кода злоумышленника.Поскольку мы называем его функцией, машина теперь переходит по этому адресу и начинает выполнять код, хранящийся там, и теперь у вас есть прекрасный произвольный код выполнения вектор атаки в ваших руках.