Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги хакеры / Защита_от_взлома_сокеты,_эксплойты,_shell_код_Фостер_Дж_

.pdf
Скачиваний:
14
Добавлен:
19.04.2024
Размер:
3.68 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

Разработка эксплойтов с помощью каркаса Metasploit 601

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

w Click

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

-xcha

 

 

 

 

 

p

 

-x cha

 

 

 

 

 

 

 

 

 

В строках 1–65 переменной $pattern присваивается строка из 4000 символов,

 

 

e

 

 

 

 

df

 

 

n

e

 

 

 

 

df

 

 

n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

сгенерированная методом PattetnCreate(). В строке 68 эта переменная используется вместо строки из 4000 букв ‘A’. Все остальное не изменилось. Если мы теперь выполним этот сценарий, то в регистре EIP должны оказаться однозначно идентифицируемые четыре байта (см. рис. 12.14).

Рис. 12.14. Перезапись EIP известной последовательностью

На рис. 12.14 регистр EIP содержит значение 0x74413674 или в ASCII-виде строку «tA6t». Чтобы получить исходную строку, байты нужно переставить местами, получится «t6At». Дело в том, что отладчик OllyDbg знает, что на платформе x86 словахранятся в порядке байтов little endian, но для удобства чтения представляет их и, в частности, значение регистра EIP в порядке big endian. Последовательность «t6At» находится в строке 11 примера 12.2, равно как и ASCII-строка, оказавшаяся в регистре ESI.

Найдя интересующие нас четыре байта, мы можем определить смещение адреса возврата от вершины стека. Для этого можно вручную подсчитать, сколько символов предшествует строке «t6At», но это скучно и долго. Проще воспользоваться сценарием patternOffset.pl, который находится в каталоге ~/framework/sdk. Хотя он и не документирован, но, заглянув в исходный текст, можно понять, что первый аргумент – это адрес, оказавшийся в EIP, в формате big endian, как его показывает OllyDbg, а второй – длина исходного буфера. В примере 12.3 сценарию patternOffset.pl переданы аргументы 0x74413674 и 4000.

Пример 12.3. Результат работы сценария patternOffset.pl

Administrator@nothingbutfat ~/framework/sdk $ ./patternOffset.pl 0x74413674 4000

589

Сценарий определил, что смещение подстроки «t6At» от начала строки равно 589. Значит, перед теми четырьмя байтами, которые окажутся в стеке на месте адреса возврата, должно быть 589 байтов. Второй вариант строки для

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

602 Глава 12. Написание эксплойтов III

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

 

 

 

 

 

 

m

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

-xcha

 

 

 

 

 

p

 

 

 

 

 

 

 

 

 

 

 

 

 

атаки показан на рис. 12.15. Начиная с этого места, мы забудем про поля, дик--x cha

 

e

 

 

 

 

df

 

 

n

e

 

 

 

 

df

 

 

n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

туемые протоколом HTTP, и про расширение файла, чтобы упростить диаграммы, но в текст окончательного эксплойта, конечно, добавим их.

Рис. 12.15. Второй вариант строки для атаки

Байты с 1 по 589 взяты из последовательности, сгенерированной методом PatternCreate(). Следующие 4 байта должны будут перезаписать хранящийся в стеке адрес возврата, они соответствуют подстроке «t6At». И, наконец, байты с 594 по 4000 снова взяты из сгенерированной последовательности.

Итак, мы знаем, что можем записать вместо адреса возврата произвольное значение и, стало быть, получить контроль над регистром EIP. А это позволит нам передать управление полезной нагрузке, то есть выполнить на удаленной системе произвольный код.

Выбор вектора управления

Если вектор атаки – это средства проведения, то вектор управления – это путь, по которому поток выполняемых команд достигает нашего кода. Наша цель – каким-то образом передать управление от исходной программе той полезной нагрузке, которую мы отправим в составе атакующего запроса.

В атаке на переполнение буфера, когда перезаписывается адрес возврата, есть, вообще говоря, два способа передать управление полезной нагрузке. Первый способ – записать вместо адреса возврата адрес полезной нагрузки, находящейся в стеке. Второй способ – подменить адрес возврата адресом функции из какой-либо разделяемой библиотеки. При этом команда в этой библиотеке, на которую указывает EIP, должна выполнить переход на начало полезной нагрузки в стеке. Прежде чем сделать выбор, надо тщательно исследовать оба метода, чтобы понять, как поток исполнения попадет от кода исходной программы к shell-коду, составляющему полезную нагрузку.

При использовании первого способа в стек вместо сохраненного адреса возврата заносится адрес полезной нагрузки. Когда управление покидает уязвимую функцию, этот адрес загружается в регистр EIP. Многие думают, что EIP содержит следующую подлежащую выполнению команду. Это не так, на самом деле в EIP хранится адрес следующей команды, а не она сама. Иными словами, регистр EIP указывает на то место программы, с которого должно продолжиться исполнение. Загрузив в него адрес полезной нагрузки, мы заставим процессор выполнить ее.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

Примечание

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Разработка эксплойтов с помощью каркаса Metasploit 603

 

to

 

 

 

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Термином «полезная нагрузка» описывается зависящий от архитек туры ассемблерный код, который передается жертве в составе стро ки запроса и исполняется ей. Полезная нагрузка создается для того, чтобы заставить удаленную программу выполнить намеченное дей ствие, например, запустить некоторую программу и привязать обо лочку к прослушиваемому порту.

Раньше любую полезную нагрузку принято было называть shell ко дом, но теперь от этого отказались, так как этот термин слишком ча сто применялся неправильно. Впрочем, в этой книге «полезная на грузка» и «shell код» считаются синонимами. Термин «полезная на грузка» может иметь и другой смысл в зависимости от контекста. Иногда так называют всю строку, передаваемую хосту жертве в про цессе атаки, но мы зарезервируем его для описания лишь той ее ча сти, которая содержит исполняемый shell код.

Хотя тема полезной нагрузки еще далеко не исчерпана, предположим пока, что ее можно разместить в любом месте, которое сейчас занимает сгенерированная строка. Подчеркнем, что она может находиться как до, так и после адреса возврата. На рис. 12.16 показано, как управление передается в область памяти, предшествующую адресу возврата.

Рис. 12.16. Первый способ:

передача управления полезной нагрузке, размещаемой в стеке

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

i

 

 

 

F

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

t

 

 

 

 

 

 

 

 

 

 

t

 

P

D

 

 

 

 

 

 

 

 

o

 

P

D

 

 

 

 

 

 

 

 

o

 

 

 

 

NOW!

r

 

 

 

 

 

NOW!

r

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

604 Глава 12. Написание эксплойтов III

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

 

 

m

w Click

 

 

 

 

 

 

o

 

w Click

 

 

 

 

 

 

o

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

 

.c

 

 

 

.

 

 

 

 

 

 

.c

 

 

 

p

df

 

 

 

 

e

 

 

 

 

p

df

 

 

 

 

e

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

-xcha

 

 

 

 

 

К сожалению, базовый адрес стека в Windows не так предсказуем, как-x cha

 

 

 

 

 

в UNIX. А значит, в Windows нельзя точно сказать, где окажется полезная нагрузка, следовательно, переход прямо на команду, размещенную в стеке, надежно работать не будет. Но ведь shell-код находится в стеке, и до него необходимо как-то добраться. Тут-то и приходит на помощь второй способ, в котором в качестве «трамплина» применяется библиотечная функция.

Идея заключается в том, чтобы воспользоваться сложившимися в исполняемом процессе условиями для записи в EIP адреса полезной нагрузки, где бы она ни находилась. Мы просматриваем содержимое регистров, чтобы понять, указывает ли хотя бы один их них на область внутри размещенной в стеке строки атаки. Если такой регистр будет найден, то мы скопируем его содержимое в EIP, который, следовательно, станет указывать внутрь нашей строки.

Последовательность шагов, необходимая для задействования разделяемой библиотеки, несколько сложнее, чем при прямой передаче управления команде в стеке. Вместо того чтобы перезаписывать адрес возврата адресом в стеке, мы запишем в него адрес команды, которая скопирует значение регистра, указывающего на полезную нагрузку, в EIP. Для этого нужно выполнить следующие действия (рис. 12.17):

1.Предположим, что регистр EAX указывает на полезную нагрузку и запишем вместо сохраненного адреса возврата адрес команды, которая скопирует значение EAX в EIP. (Ниже мы покажем, как найти адрес такой команды.)

2.Когда управление покинет уязвимую функцию, перезаписанный адрес возврата будет загружен в EIP. Теперь EIP указывает на команду копирования.

3.Процессор выполняет команду копирования, в результате чего в EIP оказывается значение EAX. Теперь и EIP, и EAX содержат одно и то же значение, являющееся адресом внутри нашей полезной нагрузки.

4.Следующая выполненная процессором команда будет принадлежать полезной нагрузке, стало быть, мы сумели перенаправить поток управления на себя.

Обычно можно предполагать, что хотя бы один регистр указывает на адрес внутри нашей строки, поэтому следующий шаг – понять, с помощью каких команд можно скопировать значение из этого регистра в EIP.

Примечание

Помните, что регистры, в отличие от других областей памяти, не имеют адресов. Для обращения к ним имеются специальные коман ды. При этом регистр EIP отличается от всех прочих тем, что не мо жет быть явным операндом никакой команды. Изменять его можно только косвенно.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

 

m

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

 

g

 

 

 

 

 

df

-xch

 

n

e

 

 

 

 

 

a

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Разработка эксплойтов с помощью каркаса Metasploit 605

 

to

 

 

 

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Рис. 12.17. Второй способ:

использование разделяемой библиотеки в качестве трамплина

Существует немало команд, модифицирующих значение EIP, в том числе CALL, JMP и некоторые другие. Поскольку команда CALL специально предназначена для изменения EIP, то ее мы и будем рассматривать.

Эта команда изменяет путь исполнения программы, записывая в EIP свой операнд. При этом в качестве операнда может выступать либо адрес в памяти, либо регистр.

Если указан адрес в памяти, то его содержимое и записывается в EIP. Если же указан регистр, то в EIP копируется содержимое этого регистра. Любой способ годится для управления потоком выполнения программы. Мы уже говорили, что не существует надежного способа предсказать адрес стека в Windows, поэтому приходится пользоваться регистрами.

Чтобы применить описанный выше метод, нужно для начала найти какойнибудь регистр, который указывал бы внутрь области, занятой нашей строкой, в тот момент, когда происходит извлечение сохраненного в стеке адреса возврата в EIP. Мы уже знаем, что если в EIP будет загружен недопустимый адрес, произойдет нарушение защиты памяти. Знаем мы и то, что присоединенный к процессу отладчик перехватит такое исключение. Это дает нам возможность исследовать состояние процесса, в том числе регистров, в момент нарушения защиты, то есть сразу после того, как в EIP загружен адрес возврата.

Кстати говоря, именно это состояние мы и наблюдали при вычислении смещения адреса возврата. Взглянув на окно регистров (рис. 12.13), мы увидим, что EAX и ESI содержат адреса в памяти, занятой нашей строкой. Стало быть, есть два потенциальных источника значения для EIP.

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

606 Глава 12. Написание эксплойтов III

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

Примечание

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Один из способов найти адрес подходящей команды CALL (или экви валентной ей) состоит в том, чтобы просмотреть всю виртуальную па мять процесса, пока не будет найдена последовательность байтов, соответствующая этой команде. Такая последовательность называет ся кодом операции (opcode). Предположим, например, что на полез ную нагрузку в стеке указывает регистр EAX. Тогда нам нужно найти в памяти команду CALL EAX, которой соответствует код операции 0xFFD0. Присоединив к процессу отладчик, мы могли бы найти в вир туальной памяти все вхождения цепочки 0xFFD0. Но даже если нам это удастся, то нет никакой гарантии, что при следующем выполнении программы нужная цепочка окажется по тому же адресу. Стало быть, случайный поиск в виртуальной памяти – дело ненадежное.

Наша цель – найти такие адреса, в которых нужные коды операции оказываются всегда. В Windows все разделяемые библиотеки (DLL), загружаемые в адресное пространство процесса, обычно начинаются с одних и тех же базовых адресов. Это объясняется тем, что в каждой DLL есть поле ImageBase, которое содержит адрес, по которому за грузчик должен постараться разместить библиотеку в памяти. Если загрузчик по какой то причине не сможет этого сделать, то DLL при дется динамически перенастроить на другой начальный адрес, а это ресурсоемкая процедура. Поэтому загрузчик по мере сил стремится поместить библиотеку туда, куда сказано. Ограничившись просмот ром только тех областей виртуальной памяти, которые отведены под DLL, мы существенно повысим шансы на то, что адреса нужных нам кодов операций не будут меняться от запуска к запуску.

Интересно отметить, что в UNIX в разделяемых библиотеках пред почтительный начальный адрес не указывается, поэтому «метод трамплина» не так надежен, как прямой переход на команду в стеке.

Чтобы точно выяснить, куда именно указывают регистры, снова обратимся к рис. 12.13. Помимо самих значений регистров, отладчик выводит еще данные, находящиеся в тех областях памяти, на которые они указывают. Так, EAX указывает на строку, начинающуюся с «7At8», а ESI – на строку «At5A». Снова применив сценарий patternOffset.pl, мы найдем, что эти строки соответствуют смещения 593 и 585 байтов от начала.

На рис. 12.18 видно, что ESI указывает на область, где есть место только для 4 байтов, тогда как в области, на которую указывает EAX, можно разместить аж 3407 байтов.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

 

m

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

 

g

 

 

 

 

 

df

-xch

 

n

e

 

 

 

 

 

a

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

Разработка эксплойтов с помощью каркаса Metasploit 607

 

to

 

 

 

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Рис. 12.18. Области памяти, на которые указывают регистры EAX и ESI

Таким образом, мы ставим себе целью скопировать в EIP значение из регистра EAX. Осталось найти адрес команды CALL EAX в памяти, занятой разделяемыми библиотеками.

Примечание

Если бы EAX не указывал внутрь строки, то воспользоваться регист ром ESI и разместить полезную нагрузку всего в четырех байтах, ка залось бы, невозможно. Но мы смогли бы получить в свое распоря жение больше места, если бы поместили по адресу, отстоящему на 585 байтов от начала строки, команду JMP SHORT 6 (код операции 0xEB06). «Оттолкнувшись» от ESI и попав на эту команду, процессор перескочил бы через адрес возврата и оказался бы аккурат в начале обширной свободной памяти со смещением 593. А дальше эксплойт работал бы так же, как если бы на тот же адрес указывал регистр EAX. Заметим для интересующихся, что в команде JMP надо указать сме щение 6 (0xEB06), так как она сама не учитывается при подсчете рас стояния.

Очень хорошее справочное руководство по командам процессоров x86 можно найти на сайте проекта NASM по адресу http://nasm.sourceforge. net/doc/html/ nasmdocb.html.

Вычисление адреса возврата

При передаче управления напрямую команде, находящейся в стеке, для вы- числения адреса возврата нужно всего лишь просмотреть содержимое стека в отладчике. Если же приходится использовать в качестве трамплина DLL, то

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

i

 

 

F

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

t

 

 

 

 

 

 

 

 

 

t

 

P

D

 

 

 

 

 

 

 

 

o

P

D

 

 

 

 

 

 

 

 

o

 

 

 

 

NOW!

r

 

 

 

 

NOW!

r

 

 

 

 

 

BUY

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

608 Глава 12. Написание эксплойтов III

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

m

w Click

 

 

 

 

 

 

o

w Click

 

 

 

 

 

 

o

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

.c

 

 

 

p

df

 

 

 

 

e

 

 

 

p

df

 

 

 

 

e

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

-xcha

 

 

задача усложняется. Сначала выбирается подлежащая выполнению команда.-x cha

 

 

 

 

 

Затем отыскивается соответствующий ей код операции. После этого надо выяснить, какие DLL загружает приложение. И, наконец, в занятых этими DLL областях памяти предстоит найти подходящий код операции.

Вместо всего этого можно отыскать правильный адрес возврата с помощью Web-интерфейса к базе данных о кодах операций Metasploit (Opcode Databаse) на сайте www.metaspoit.com (рис. 12.19). Она содержит свыше 7.5 миллионов заранее вычисленных адресов для примерно 250 кодов операций и продолжает пополняться с выходом каждой новой версии.

Рис. 12.19. Выбор метода поиска

в базе данных о кодах операций Metasploit

Найдем в этой базе адрес возврата, отвечающий нашим требованиям. Как показано на рис. 12.20, в базе данных можно производить поиск дву-

мя способами. Стандартный метод – выбрать из списка DLL, которую загружает процесс-жертва. Другой вариант скопировать перечень загруженных библиотек, который отладчик WinDbg показывает в окне команд, будучи присоединен к процессу.

Для демонстрации мы воспользуемся первым способом.

На шаге 1 можно провести в базе поиск по классу кода операции, метатипу или конкретной команде. Поиск по классу вернет все команды, дающие желаемый результат; на рис. 12.20 это будут команды, копирующие в EIP содержимое регистра EAX. Поиск по метатипу возвращает все команды, отве-

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

Разработка эксплойтов с помощью каркаса Metasploit 609

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

w Click

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

 

 

p

 

-x cha

 

 

 

 

 

 

 

-xchчающиеa

заданному образцу кода операции; на рис. 12.20 это команды CALL

 

 

e

 

 

 

 

df

 

 

n

e

 

 

 

 

df

 

 

n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

с любым регистром в качестве операнда.

Рис. 12.20. Шаг 1: задание типа кода операции

Так как в выбранном нами векторе управления используется регистр EAX, то мы просим найти команду CALL EAX.

На шаге 2 пользователь задает имя DLL, которую нужно найти в базе. Можно просматривать все модули, один или несколько обычно загружаемых модулей или набор конкретных модулей. Мы решили ограничиться модулями ntdll.dll и kernel32.dll, поскольку точно известно, что эти библиотеки процесс inetinfo.exe загружает в самом начале работы (рис. 12.21).

Рис. 12.21. Шаг 2: выбор DLL

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

610 Глава 12. Написание эксплойтов III

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

Примечание

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Многие эксплойты отдают предпочтение библиотекам ntdll.dll и kernel32.dll в качестве трамплина по ряду причин:

1)начиная с Windows NT, любой процесс обязан загрузить в свое адресное пространство библиотеку ntdll.dll;

2)библиотека kernel32.dll должна присутствовать во всех Win32 приложениях;

3)если библиотеки ntdll.dll и kernel32.dll загружены не по своим пре

допределенным начальным адресам, система выдаст ошибку. Используя в нашем примере эти две библиотеки, мы существенно повышаем шансы найти коды операции для задания нужного нам ад реса возврата.

Из-за добавления новых функций, наложения заплат и выпуска обновлений, выбранная DLL может меняться с выходом каждой новой заплаты, пакета обновлений и версии Windows. Чтобы быть уверенным в правильной работе эксплойта, на шаге 3 можно провести поиск в библиотеках для одной или нескольких версий Windows и пакетов обновлений. В нашем примере мы указали Windows NT 4 с пакетом обновлений Service Pack 5 (рис. 12.22).

Рис. 12.22. Шаг 3: выбор целевой платформы

Буквально через несколько секунд база данных вернет информацию о восьми вхождениях команды CALL EAX в ntdll.dll и kernel32.dll на платформе Windows NT 4 Service Pack 5 (рис. 12.23). Информация о каждом вхождении состоит из четырех полей: адрес, код операции, модуль и версии ОС. В колонке «Opcode» находится команда, найденная по адресу, показанному