книги хакеры / Защита_от_взлома_сокеты,_эксплойты,_shell_код_Фостер_Дж_
.pdf
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
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. Поиск по метатипу возвращает все команды, отве-