Искусство взлома и защиты систем

Об авторах

От издательства

Благодарности

Часть I. Эксплуатация уязвимостей Linux на процессорах x86

Глава 1. Введение в эксплуатацию уязвимостей

Основные концепции

Управление памятью

Ассемблер

Программные конструкции C++ в ассемблере

Итоги

Глава 2. Переполнение стека

Буферы

Стек

Функции и стек

Переполнение буферов в стеке

Управление значением EIP

Использование уязвимостей для получения root-привилегий

Проблема адресации

Метод NOP

Борьба с неисполняемым стеком

Возврат в libc

Итоги

Глава 3. Внедряемый код

Системные функции

Написание внедряемого кода для вызова exit()

Устранение нуль-символов

Запуск командного процессора

Итоги

Глава 4. Дефекты форматных строк

Понятие форматной строки

Понятие дефекта форматной строки

Использование дефектов форматных строк

Аварийное завершение служб

Утечка информации

Контроль над исполнением

Причины дефектов форматных строк

Обзор приемов эксплуатации дефектов форматных строк

Итоги

Глава 5. Переполнение кучи

Понятие кучи

Функционирование кучи

Переполнение кучи

Основные принципы переполнения кучи

Объекты замены

Итоги

Часть II. Платформа Windows

Глава 6. Дикий мир Windows

Различие Windows и Linux

API и PE-COFF для Win32

Куча

Многопоточность

Гениальность и глупость концепций DCOM и DCE-RPC

Сбор информации

Эксплуатация уязвимостей

Маркеры и заимствование прав

Обработка исключений в Win32

Отладчики для Windows

Дефекты Win32

Написание внедряемого кода для Windows

Win32 API для хакера

Семейство Windows с точки зрения хакера

Итоги

Глава 7. Внедряемый код для Windows

Синтаксис и фильтры

Подготовка

Анализ блока PEB

Файл Heapoverflow.c

Поиск с использованием механизма обработки исключений Windows

Запуск командного процессора

Почему этого делать не следует

Итоги

Глава 8. Переполнение в Windows

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

Стековые обработчики исключений

Манипуляции стековыми обработчиками исключений в Windows 2003 Server

Последнее замечание о перезаписи стековых обработчиков

Защита стека и Windows 2003 Server

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

Куча процесса

Динамическая куча

Работа с кучей

Функционирование кучи

Эксплуатация уязвимостей при переполнении кучи

Перезапись указателя на RtlEnterCriticalSection в PEB

Перезапись указателя на первый векторный обработчик по адресу 77FC3210

Перезапись указателя на фильтр необработанных исключений

Перезапись указателя на обработчик исключения в блоке TEB

Восстановление кучи

Другие аспекты переполнения кучи

Несколько слов в завершение

Другие варианты переполнения

Переполнение секции .data

Переполнение блоков TEB и PEB

Переполнение буфера и неисполняемые стеки

Итоги

Глава 9. Обход фильтров

Код обхода алфавитно-цифровых фильтров

Код обхода Unicode-фильтров

Кодировка Unicode

Преобразование из ASCII в Unicode

Эксплуатация уязвимостей кодировки Unicode

Допустимый набор команд

Венецианский метод

ASCII-реализация венецианского метода

Дешифрирование

Код дешифрирования

Изменение адреса буфера

Итоги

Часть III. Выявление уязвимостей

Глава 10. Формирование рабочей среды

Справочные материалы

Средства разработки

gcc

gdb

NASM

WinDbg

OllyDbg

SoftICE

Visual C++

Python

Средства анализа

Полезные сценарии и утилиты

Все платформы

Unix

Windows

Базовые сведения

Архивы

Оптимизация процесса разработки внедряемого кода

Планирование

Встроенный ассемблер

Библиотеки встроенного кода

Корректное продолжение

Стабильность

Перехват подключения

Итоги

Глава 11. Внесение ошибок

Архитектура

Генератор входных данных

Внесение ошибок

Механизм модификации

Передача ошибок

Алгоритм Нейгла

Временные характеристики

Эвристика

Протоколы с поддержкой и без поддержки состояния

Мониторинг ошибок

Отладчик

Программа FaultMon

Все вместе

Итоги

Глава 12. Искусство фаззинга

Общая теория фаззинга

Статический анализ и фаззинг

Масштабируемость фаззинга

Недостатки фаззеров

Моделирование произвольных сетевых протоколов

Другие возможности фаззинга

Переключение битов

Модификация программ с открытыми исходными текстами

Фаззинг с динамическим анализом

Программа SPIKE

Копилка

Моделирование сетевых протоколов с помощью структуры данных SPIKE

Фаззеры SPIKE

Пример использования фаззера SPIKE

Другие фаззеры

Итоги

Глава 13. Анализ исходных текстов на языках семейства C

Инструменты

Cscope

Ctags

Редакторы

Cbrowser

Средства автоматического анализа исходных текстов

Методология

Нисходящий анализ

Восходящий анализ

Избирательный анализ

Классы уязвимостей

Общие логические ошибки

Пережитки прошлого

Форматные строки

Общие ошибки проверки границ

Циклические конструкции

Уязвимости единичного смещения

Ошибки некорректного завершения строк

Пропуск завершителя

Уязвимости знакового сравнения

Целочисленное переполнение

Преобразование целых чисел с разной разрядностью

Повторное освобождение памяти

Использование памяти вне области видимости

Использование неинициализированных переменных

Использование памяти после освобождения

Проблемы многопоточности и реентерабельности

Дефекты и реальные уязвимости

Итоги

Глава 14. Инструментальный анализ

Философия

Переполнение процесса extproc в Oracle

Типичные архитектурные дефекты

Пограничные проблемы

Проблемы преобразования данных

Проблемы мест дисбаланса

Проблемы различия между аутентификацией и авторизацией

Проблемы в самых очевидных местах

Обход процедур проверки входных данных и обнаружения атак

Удаление недопустимых данных

Использование альтернативных кодировок

Файловые операции

Обход сигнатур обнаружения атак

Борьба с ограничениями длины

Дефект SNMP-демона DOS в Windows 2000

Обнаружение DOS-атак

Дефект SQL-UDP

Итоги

Глава 15. Трассировка уязвимостей

Общие сведения

Уязвимая программа

Основные компоненты

Внедрение в адресное пространство процесса

Анализ машинного кода

Перехватчики

Сбор данных

Разработка VulnTrace

VTInject

Программа VulnTrace

Дополнительные приемы трассировки

Сигнатурный поиск

Другие классы уязвимостей

Итоги

Глава 16. Двоичный анализ

Очевидные различия двух видов анализа

IDA Pro — лучший инструмент

Краткий обзор возможностей IDA Pro

Отладочные символические имена

Введение в двоичный анализ

Стековый кадр

Конвенции вызова

Компиляторные конструкции

Аналоги функции memcpy

Аналоги функции strlen

Конструкции C++

Указатель this

Реконструкция определений классов

Таблицы виртуальных функций

Полезные факты

Ручные методы двоичного анализа

Просмотр библиотечных вызовов

Подозрительные циклы и команды записи

Анализ на более высоком уровне и логические ошибки

Графический анализ двоичных файлов

Ручная декомпиляция

Примеры двоичных уязвимостей

Дефекты Microsoft SQL Server

Уязвимость LSD RPC-DCOM

Уязвимость IIS WebDAV

Итоги

Часть IV. Дополнительные материалы

Глава 17. Альтернативные стратегии

Модификация программы

3-байтовая модификация SQL Server

1-битовая модификация MySQL

Аутентификация OpenSSH RSA

Другие стратегии модификации кода на стадии выполнения

Модификация GPG 1.2.2

Загрузка и запуск (проглет-сервер)

Опосредованный вызов системных функций

Проблемы опосредованного вызова

Итоги

Глава 18. Реальные условия, реальные проблемы

Факторы ненадежности

Волшебные числа

Версии

Проблемы с внедряемым кодом

Контрмеры

Подготовка

Метод “грубой силы”

Локальные решения

Идентификация ОС и приложения

Утечки информации

Итоги

Глава 19. Атаки на СУБД

Атаки сетевого уровня

Атаки прикладного уровня

Выполнение команд операционной системы

Microsoft SQL Server

Oracle

IBM DB2

Атаки на уровне SQL

SQL-функции

Итоги

Глава 20. Переполнение в ядре

Типы уязвимостей ядра

Переполнение буфера в стеке ядра OpenBSD

Перезапись памяти ядра в OpenBSD

Утечка информации из памяти ядра в FreeBSD

Уязвимость priocntl() в Solaris

Новые уязвимости ядра

Переполнение в функции exec_ibcs2_coff_prep_zmagic() ядра OpenBSD

Уязвимость перебора загружаемых модулей ядра vfs_getvfssw() в Solaris

Итоги

Глава 21. Эксплуатация уязвимостей ядра

Уязвимость exec_ibcs2_coff_prep_zmagic()

Вычисление смещений и контрольных точек

Замена адреса возврата и перехват управления

Получение дескриптора процесса

Создание внедряемого кода режима ядра

Возврат из режима ядра

Получение root-привилегий (uid=0)

Уязвимость загрузки модулей ядра vfs_getvfssw()

Разработка кода

Загружаемый модуль ядра

Получение root-привилегий (uid=0)

Итоги

Алфавитный указатель

 

В книге рассмотрены различные типы программного обеспечения: операционные системы, базы данных, интернет-серверы и т. д. На множестве примеров показано, как именно находить уязвимости в программном обеспечении. Тема особенно актуальна, так как в настоящее время в компьютерной индустрии безопасности программного обеспечения уделяется все больше внимания.