Коллектив авторов - Защита от хакеров корпоративных сетей
- Название:Защита от хакеров корпоративных сетей
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Коллектив авторов - Защита от хакеров корпоративных сетей краткое содержание
В книге рассматривается современный взгляд на хакерство, реинжиниринг и защиту информации. Авторы предлагают читателям список законов, которые определяют работу систем компьютерной безопасности, рассказывают, как можно применять эти законы в хакерских технологиях. Описываются типы атак и возможный ущерб, который они могут нанести компьютерным системам. В книге широко представлены различные методы хакинга, такие, как поиск различий, методы распознавания шифров, основы их вскрытия и схемы кодирования. Освещаются проблемы безопасности, возникающие в результате непредсказуемого ввода данных пользователем, методы использования машинно-ориентированного языка, возможности применения мониторинга сетевых коммуникаций, механизмы туннелирования для перехвата сетевого трафика. В книге представлены основные сведения о хакерстве аппаратных средств, вирусах, троянских конях и червях. В этой книге читатель узнает о методах, которые в случае неправильного их применения приведут к нарушению законодательства и связанным с этим последствиям.
Лучшая защита – это нападение. Другими словами, единственный способ остановить хакера заключается в том, чтобы думать, как он. Эти фразы олицетворяют подход, который, по мнению авторов, позволит наилучшим образом обеспечить безопасность информационной системы.
Перевод: Александр Петренко
Защита от хакеров корпоративных сетей - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Пример программы переполнения буфера для Linux
В последнее время феноменально выросла популярность Linux. Несмотря на доступные исходные тексты и армию разработчиков открытого программного обеспечения, до сих пор нельзя сказать, что в Linux исправлены все ошибки. Часто по вине пользователя переполнение буфера происходит в программах, которые непосредственно не связаны с безопасностью системы. Далее особое внимание будет обращено на способы, которые могут быть использованы в многочисленных ситуациях, в том числе и связанных с безопасностью.
На примере программного кода записи строки на экран будет продемонстрировано последовательное расширение функциональных возможностей программы переполнения буфера. Пример подобен простой программе на языке C, использующей функцию write().
Сначала создадим простую программу, выводящую строку на экран:
–write.c–
int main()
{
write(1,»EXAMPLE\n»,10);
}
–write.c–Сохраним исходный текст в файле write.c, откомпилируем его компилятором GCC и выполним.
bash$ gcc write.c -o example —static
bash$ ./example
EXAMPLE
bash$Все достаточно просто. Для того чтобы окончательно понять работу программы, воспользуемся утилитой gdb. У утилиты gdb больше возможностей, чем читатель может себе представить. Если он знает их все, то ему нужно сменить хобби. Для изучения примера достаточно основных возможностей утилиты gdb. Для начала откроем пример программы:
–
bash$ gdb ./example
GNU gdb 5.1
Copyright 2001 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public
License, and you are welcome to change it and/or distribute
copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show
warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”...
(gdb)
–Может оказаться, что версия утилиты gdb читателя отличается от используемой в книге. Но это не имеет большого значения. Без всякого сомнения, используемые возможности утилиты gdb реализованы в версии утилиты читателя. Введем в ответ на приглашение утилиты команду disassemble main и исследуем выполняемый код программы в функции main(), обратив особое внимание на участок кода, который вызывает функцию write(). Команда disassemble выводит код функции на языке ассемблера используемого компьютера. Для нашего примера это Intel x86.
(gdb) disas main
Dump of assembler code for function main:
0x80481e0
: push %EBP0x80481e1
: mov %ESP,%EBP0x80481e3
: sub $0x8,%ESP0x80481e6
: sub $0x4,%ESP0x80481e9
: push $0x90x80481eb
: push $0x808e2480x80481f0
: push $0x10x80481f2
: call 0x804cc60 <__libc_write>0x80481f7
: add $0x10,%ESP0x80481fa
: leave0x80481fb
: retEnd of assembler dump.
(gdb)Далее будет исследован выполняемый код функции write(). Параметры функции write() записываются в стек в обратном порядке. Сначала командой push $0x9 в стек проталкивается величина 0x9 (символ $0x указывает на представление утилитой gdb выводимых величин в шестнадцатеричном виде), где 9 – длина строки «EXAMPLE\n». Далее в стек командой push $0x808e248 проталкивается адрес строки «EXAMPLE\n». Для просмотра содержимого области по этому адресу достаточно в ответ на приглашение gdb ввести команду утилиты: x/s 0x808e248. Заключительный шаг перед вызовом функции write() состоит в записи в стек дескриптора файла. В данном случае это 1 – дескриптор стандартного вывода. После перечисленных действий вызывается функция write().
0x80481e9
: push $0x90x80481eb
: push $0x808e2480x80481f0
: push $0x10x80481f2 : call 0x804cc60 <__libc_write>Для просмотра кода функции write() в ответ на приглашение утилиты введем команду disas__libc_write . Получим следующее.
(gdb) disas __libc_write
Dump of assembler code for function __libc_write:
0x804cc60 <__libc_write>: push %EBX
0x804cc61 <__libc_write+1>: mov 0x10(%ESP,1),%EDX
0x804cc65 <__libc_write+5>: mov 0xc(%ESP,1),%ECX
0x804cc69 <__libc_write+9>: mov 0x8(%ESP,1),%EBX
0x804cc6d <__libc_write+13>: mov $0x4,%EAX
0x804cc72 <__libc_write+18>: int $0x80
0x804cc74 <__libc_write+20>: pop %EBX
0x804cc75 <__libc_write+21>: cmp $0xfffff001,%EAX
0x804cc7a <__libc_write+26>: jae 0x8052bb0 <__syscall_error>
0x804cc80 <__libc_write+32>: ret
End of assembler dump.Начальная команда push %EBX не так важна. Она сохраняет в стеке старое значение регистра EBX. В программе значение регистра изменяется, а затем восстанавливается командой pop %EBX. Еораздо интереснее последующие команды mov и int $0x80. Первые три команды mov переписывают данные, ранее сохраненные в стеке функцией main (), в рабочие регистры. Четвертая команда mov подготавливает вызов функции write(), помещая номер системного вызова в регистр EAX. При выполнении команды int $0x80 операционная система передает управление программе системного вызова по номеру, записанному в регистре EAX. Номер системного вызова функции write() – 4. В файле «/usr/include/asm/unistd.h» перечислены все номера доступных системных вызовов.
0x804cc6d <__libc_write+13>: mov $0x4,%EAX 0x804cc72 <__libc_write+18>: int $0x80
Подведем итоги. Теперь известно, что функции write() передается три параметра: длина записываемых данных, адрес строки источника, из которой переписываются данные, и адресат записи – дескриптор файла. Также теперь известно, что длина строки, в данном случае 9 байт, передается через регистр EDX, адрес строки записываемых данных через регистр ECX и дескриптор файла должен быть передан через регистр EBX. Таким образом, простой код вызова функции write() без обработки ошибок выглядит следующим образом:
mov $0x9,%EDX
mov 0x808e248,%ECX
mov $0x1,%EBX
mov $0x4,%EAX
int $0x80Зная ассемблерный вид вызова функции write(), можно приступить к написанию управляющего кода (shellcode). Единственная сложность заключается во второй команде mov 0x808e248,%ECX с явно заданным адресом памяти. Проблема состоит в том, что нельзя прочитать из строки данные, не зная ее адрес, но нельзя узнать адрес строки, пока она не будет загружена в память. Для ее разрешения применима последовательность команд jmp/call. Найденное решение основано на алгоритме работы команды call: по команде call в стек записывается адрес следующей команды. Поэтому выход из трудного положения может быть следующим:
jump
code:
pop %ECX
string:
call
“our string\n”
По команде call в стек записывается адрес следующей команды и выполняется переход по указанной метке. На самом деле в стек загружается адрес строки, но для выполнения команды это безразлично. В результате на вершине стека оказывается адрес строки string\n. После перехода на метку code выполняется команда pop %ECX. Команда pop переписывает в заданный регистр данные с вершины стека. В данном случае в регистр ECX записывается адрес строки string\n. Осталось только для правильной работы программы очистить (обнулить) регистры от посторонних данных. Очистка регистров выполняется командами операция исключающее ИЛИxor или вычитания sub. Лучше использовать команду xor, потому что команда xor всегда обнуляет регистр и транслируется в быстрый компактный код. В системных вызовах для передачи параметров используются младшие байты регистров, поэтому обнуление регистров гарантирует правильную передачу параметров. В итоге фрагмент программы приобрел следующий вид:
Интервал:
Закладка: