На главную | Содержание | Назад | Вперёд
Наши друзья

 

 

Переполнение буфера в куче

Как известно, куча (heap) состоит из больших блоков выделенной памяти. В каждом блоке есть небольшой заголовок, в котором указывается размер блока и другая служебная информация. Если происходит переполнение буфера в куче, то при атаке перезаписывается следующий по порядку блок кучи, включая и заголовок. Если есть возможность перезаписать в памяти заголовок следующего блока, то в память можно записать и подготовленные данные. При применении разных (но похожих) программ атаки на переполнение буфера в куче на конкретное приложение мы часто получаем уникальные результаты, что усложняет проведение атак этого типа. В зависимости от программного кода, будут меняться точки, в которых возможно искажение данных в памяти. Это не так плохо, это лишь означает, что создаваемая программа атаки должна быть уникальной и подготовленной для взлома конкретной цели.
Хотя об атаках на переполнение буфера в куче известно уже достаточно давно, метод их проведения оставался довольно непонятным. В отличие от ошибок переполнения буфера в стеке (которые уже практически полностью устранены в программах), уязвимые места для атак на переполнение буфера в куче остаются широко распространенными.
Как правило, данные кучи размещаются в памяти последовательно. Направление роста буфера показано на 14.
В каждой операционной системе и компиляторе используются различные методы управления кучей. И даже каждое отдельное приложение на одной платформе может использовать различные методы для управления кучей. При создании программы лучше всего восстанавливать исходный код из кучи на. конкретной системе, не забывая о том, что в каждом из атакуемых приложений используются немного различные методы работы с кучей.
На 15 показано, как в системе Windows 2000 организована информация в заголовке кучи.
00142В10 00 00 00 00 .... <- это считывается в ЕАХ
00142В14 00 00 00 00 ____ <- это считывается в ЕСХ
00142В18 05 00 ОТ 00 .... <- здесь может Сыть искажение
0 0142В1С 00 07 1Е 00 .... <- здесь может быть искажение
00142В20 57 6F 72 6С Worl
00142В24 64 21 00 00 d!..
С помощью этого немного загадочного дампа памяти мы попытались показать, что управляем буфером непосредственно выше заголовка кучи для третьего буфера (того, который содержит слово "World!").
Искажая данные в полях заголовка, хакер может заставить программу управления кучей после вызова функции HeapFree прочесть данные из других областей памяти. Уязвимый код из библиотеки ntdl 1 приведен ниже.
001В:
77F5DB30
LEAVE
0004

001В:
77F5D831
RET

001В:
77F5D834
LEA
EAX, [ESI-18]

001B:
:7 7F5D8 37
MOV
[EBP-7C],EAX

0 01B:
:7 7F5D8 3A
MOV
[EBP-80],EAX

001В:
:77F5D83D
MOV
ECX,[EAX]
<- :

001В:
:77F5D83F
MOV
[ЕБР-0084],ECX

001B:
:77F5D845
MOV
EAX,[EAX+04]
<- :

001В:
:77F5D848
MOV
[EBP-0088],EAX

001В:
77F5D84E
MOV
[EAX],ECX
<- :

001В:
:77F5D850
MOV
[ECX+04],EAX

001В:
:77F5D853
CMP
BYTE PTR [EBP-1D],0D

001В:
;77F5D857
JNZ
77F5DS86

загружает наши данные
Функция mall ос и куча
Для функции та 11 ос используется немного другой формат заголовка, но метод остается прежним. Две записи сохраняются одна возле другой в памяти и одна из них способна затереть вторую. Рассмотрим следующий программный код.
int main(int argc, char* argv[]) f
char *c char *d (char (char 4malloc(10) ; •)malloc(32) ;
strcpy(c, "Hello!"); strcpyid, "World!");

00321028
е0
jF
32
00
a.2.

00321о2с
00
00
00
00

00321030
00
00
00
00

00321034
00
00
00
00

00321038
20
00
00
00

0032103с
31
00
00
00

00321040
ЗЪ
00
00
00

00321044
FD
fd
fd
fd
уууу

00321048
57
6f
72
6c
Worl

00э2104с
64
21
00
cl";
d! . 1

00321050
cd
cd
cd
CD
Hit

00321054
CD
cd
cd
cd
tut

00321058
cd
cd
cd
cd
iiii

0032105с
cd
cd
cd
cd
iiii

00321060
cd
cd
cd
CD
iiii

00321064
CD
cd
cd
CD
tat

00321068
:-'d
fd
fd
fd
уууу .<!-•

0032106с
od
fo
ad
ба

00321070
od
fo
ad
ba
.d-*

00321074
od
fo
ad
p. л
.d-°

00321078
als
ab
ab
л в
<(.««.«.

0032107с
ah
AS
ab
а в

это значение используется как адрес
размер
Итак, мы видим буферы в куче. Также учтите заголовки, в которых задается размер блоков кучи. Нам требуется затереть адрес, поскольку он позднее будет использован в операции вызова функции free ().
00401Е6С mov eax,dword ptr [pHead]
00401E6F mov ecx,dword ptr [eax] <-
00401E71 mov edx,dword ptr [pHead]
00401E74 mov eax,dword ptr [edx+4]
00401E77 mov dword ptr [[«cx+4],eax <-
Поскольку значения, которыми мы управляем в заголовке, используются в операции с функцией free (), мы можем переписать любую область памяти. При этой перезаписи используются данные, сохраненные в регистре еах. Мы контролируем это значение, поскольку оно также берется из заголовка кучи. Другими словами, мы полностью контролируем перезапись одного значения 4 EMCRD в любой области памяти.
в есх хранится наше значение
перезапись памяти
<-

 

На главную | Содержание | Назад | Вперёд
 
Яндекс.Метрика