Работа со скальпелем. Разбираемся с утилитой ScapyСтепан "Step" Ильин (step@gameland.ru) Как можно воплотить снифер, фазер и конструктор пакетов в одной утилите? Создатели Scapy доказали, что это возможно. Работа через текстовый интерпретатор, возможно, испугает большинство пользователей. Но мы, освоив простой синтаксис, сможем ей одной заменить ей множество специализированных утилит. Основное назначение Scapy - манипулирование пакетами. Но эти функции реализованы настоль толково, что вкупе с используемым ей интерпретатором Python, можно выполнять ряд самых разнообразных задач: начиная от банального сканирования портов и заканчивая сложными приемами для определения инфраструктуры сети. В итоге получаем одну единственную утилиту, которая может заменить такие известные тулзы, как nmap, arpspoof, arp-sk, arping, tcpdump, tethereal, p0f. И более того - готова подстроиться под самые специфические ситуации. Вообще Scapy сильно отличается от многих других утилит. Она работает в текстовом окружении, однако, взаимодействие с пользователем осуществляется не через ключи в командной строки, а через интерпретатор Python'а. Необычный подход сначала может смутить, но, когда разберешься с простым синтаксисом и осознаешь, что к твоим услугам предоставляешься еще и вся мощь Python'а, вдруг понимаешь: "А ведь удобно, черт подери! И как это другие до этого не додумались!" Совладай с виндой!Чтобы не грузить тебя с теорией предлагаю сразу взять быка за рога и разбираться с программой на конкретных примерах. Сначала мы разберемся, как просто составлять и отправлять пакеты в сеть, а потом посмотрим на реализации известных приемов, способных заменить массу других утилит. Тут надо сказать, что прога изначально написана для никсов, и под тем же Linux'ом запуститься с пол пинка, а вот для использования виндового порта придется чуть попыхтеть. Первое, что потребуется, - это установленный в системе интерпретатор Python. Тут не надо спешить и скачивать самый последний релиз. Во-первых, Scapy написан на второй ветке Python'а, а поэтому можно даже не пробовать запускать ее на последнем 3.х билде. А, во-вторых, для корретной работы программы придется установить несколько дополнительных модулей, некоторые из которых имеют портированные версии только для 2.5 релиза. Если версия будет отличаться, их инсталлятор тупо обломает тебя с установкой, сославшись на отсутствии в системе нужной сборки питона. Небольшие манипуляции в реестре могут помочь это побороть, но никто не гарантирует дальнейшей 100% совместимости. Короче говоря, чтобы все прошло гладко и далее работало без проблем, рекомендую тебе следующий наборчик (весь он, само собой, есть на нашем DVD):
Помимо этого можно установить ряд дополнительных модулей, чтобы открыть пару дополнительных возможностей Scapy. Подробнее о них можно прочитать во врезке. Первый запускПосле установки, в системе будут прописаны ассоциации для запуска Python-скриптов, поэтому можно просто перейти в папку со Scapy и в командной строке набрать: scapy.py (или python scapy.py). Как я уже сказал, не стоить ждать подсказки со списком ключей для запуска - вместо этого ты окажешь внутри текстового окружения. По сути, это интерпретатор Python, сдобренный специальными функциями Scapy. Можешь ввести команду ls(), после чего оболочка должна вернуть список поддерживаемых протоколов, с которыми он поддерживает работу:
Прежде чем, конструировать первый пакет, необходимо понять для себя несколько вещей:
Наш первый сетеваой пакет, как и все остальные, сетевой пакет разделен на слои, и каждый слой представляется в Python/Scapy как экземпляр объекта. Мы можем создать объект для каждого слоя, опционально задать некоторые параметры, и объединить их в один пакет. В качестве примера создадим TCP/IP пакет для 22 порта.
Сначала, (1) действием мы создаем экземпляр IP пакета и сохраняем его в переменную а. Важно, что все значения IP пакета выставляются по умолчанию - это делает сама Scapy. Причем значения по умолчанию не отображаются пользователю далее пользователю, когда он просит интерпретатор вывести его параметры. Посмотреть значение нужного поля, можно обратившись к атрибуту нужного объекта (2). Изменим его на значение 32 (3) и с помощью следующей команды убедимся, что изменение прошло успешно. Далее, создадим TCP слой, присвоив его переменной b и установив значение поля dport (порт назначения) равным 22. Далее слепим вместе переменные a и b, используя оператор /, чтобы получить готовый TCP/IP пакет, к которому можно обратиться через переменную c. Заметь, что некоторые поля IP автоматически поменяли значения, чтобы инкапсулировать TCP слой. Тут стоит сказать, что значения полей вовсе необязательно должны быть корректными - указав заведомо неверное значение для одного или нескольких полей, очень просто получаем готовый фаззер (о фаззинге мы поговорим ниже)! В конце концов, никто не заставляет создавать кучу переменных для каждых слоев, все можно уместить в рамках одной строки: В этом примере мы добавляем еще один слой - канальный, на котором передаются фреймы Ethernet. Создаем последовательности пакетовРовно как и обычный пакет, несложно создать и последовательности пакетов. За примером использования далеко ходить не нужно, ведь создав последовательность TCP-пакетов на различные порты, мы получаем готовый порт-сканнер. И от этого лишь радужнее тот факт, что последовательность пакетов можно создать одной лишь строчкой, указав для конкретного поля не значение, а массив из нескольких значений. Пакеты созданные подобным образом называются неявными.
В итоге получаем 7 TCP/IP пакетов с TTL 1, 3, 5, 7, 8, 9, и 10.
С помощью десяти созданных ICMP-пакетов мы простым пингом сканируем первых десять адресов каждой из подсетей 192.168.
Всего одна строка нужна чтобы выполнить TCP SYN всех привилегированных портов (от 0 до 1024) в подсети 192.168.4.0/24. По сути, для любого сканирования нам надо взять какое-то конкретное поле и пройтись по всем возможным и интересным для нас назначениям. Если пройтись по портам назначения TCP, то получаем различного рода сканнер TCP портов, в зависимости от флагов, которые будем отсылать в пакете. Если отправлять пакеты на удаленный IP-адрес по ICMP, TCP или ARP, получаем соответственно TCP-пинг, ICMP-пинг и ARP-пинг. А если сканировать значения TTL, то получаем утилиту traceroute. Словом, можно сделать очень многое и все практически зависит от твоего воображения. Прием-отправка пакетовКак конструировать пакеты из нескольких уровней мы разобрались. Теперь осталось за малым - отправить пакеты в сеть и, возможно, получить на них ответ. Как я уже сказал выше, Scapy может работать на двух разных уровнях сетевой модели OSI, для каждой из них используется своя функция для отправки. Функция send() отправит пакет на 3 уровне: она сама выберет нужный интерфейс и варианты роутинга. В качестве параметра надо указать пакет или переменную с уже сконструированным пакетом: Функция sendp() работает уже на втором уровне, поэтому выбор правильного интерфейса и протокола будет на тебе.
Тут надо сказать, что на практике гораздо чаще встречаются ситуации, когда нужно не только отправить пакет, но и принять ответ от удаленной стороны. Поэтому в Scapy разумнее использовать специальные функцию для отправки команды для отправки (send) и приема (recieve) пакетов sr(). Эта функция возвращает два набора: первый из отправленных пакетов и полученных на них ответов, второй - набор пакетов, ответы на которые не были получены. Другая функция sr1() является вариацией первой с той лишь разницей, что принимает только один ответный пакет. Надо сказать, что эти функции работают на третьем уровне, поэтому и пакеты должны быть соответствующих протоколов (IP, ARP). Если ты хочешь спуститься до второго уровня и оперировать с напрямую пакетами Ethernet, 802.3, есть функция srp(). Мутим сканнер портовТеперь, когда мы умеем отправлять и принимать пакеты, разберем конкретные варианты использования Scapy. Начнем, со сканнера портов. О том, как сгенерировать пакеты для TCP-сканирования портов, мы уже говорили. Давай посмотрим теперь, как объединить это с обработкой результата. Сканирование с помощью ACK пакетов легко реализуется командой:
Нужный эффект нам дает использование флага A. Далее легко получаем список открытых портов из массива с принятыми ответами:
Если ответ не получен, вероятно, порт закрыт. Поэтому просто отображаем на экран номера портов из запросов, на которые ответа не последовало:
Поиск живых хостов в сетиЕще одна конкретная задача - найти все активные машины в локальной сети. Самый быстрый способ - использовать метод ARP Ping'а (обычно для этого используется уже готовая утилита arping). Напомню, что протокол ARP, используется в сети для определения MAC-адреса по заданному IP-адресу. Смысл ARP Ping'а заключается в том, чтобы спросить все хосты в локальном сегменте их IP-адрес:
Получаем ответы на широковещательный ARP-запрос и выводим результат в удобочитаемой форме: Кстати говоря, в Scapy есть уже реализованная функция arping(), которая реализует тоже самое. В качестве параметра ей необходимо лишь указать сегмент сети: arping("192.168.1.*"). Другой вариант найти активные хосты в сети - банально пропинговать каждый узел в заданном диапазоне, что легко выполняется командой, отправляющей в сеть ICMP-запросы:
Список живых хостов получаем из массива с ответами:
Если протокол ICMP блокируется можно попробовать использовать различные TCP Ping'и, например, с помощью TCP SYN:
Любой ответ будет означать, что узел активен. ARP-спуфингНе составит труда и использовать классический прием ARP cache poisoning, о которым мы вспоминали буквально в предыдущем номере в статье "Вскрываем SSL". Смысл в том, чтобы путем засорения ARP кеша клиента, заставить его в качестве шлюза использовать совершенно другой узел - где мы легко можем установить снифер. Делается это так:
Впрочем, Scapy позволяет не заморачиваться и использовать уже реализованную функцию arpcachepoison (), указав в качестве первого параметра свой MAC-адрес, а в качестве второго - IP жертвы. FuzzingСам прием фаззинга прост как дважды два: "подставить в каком-нибудь месте такое значение, которого быть не может, и посмотреть что будет". Скажем, если флаг в каком-то поле пакета может принимать значения 1,2,3, то можно послать 5 - и отследить реакцию. Как среагирует на такую подставу демон? А как клиент? В принципе некорректные значения можно подставлять и вручную, однако, для большего удобства в Scapy реализована функция fuzz(), которая преобразует любой корректный пакет в пакет, специально заточенный для фаззинга. Фишка в том, что функция автоматически заменяет все поля (кроме случаев, когда значение поля должно быть подсчитано - например, поля с контрольными суммами) случайными значениями, но подходящими по размеру для этого поля. Разберем пример:
В этом случае IP слой будет самым обычным, в то время как для UDP и NTP (это, кстати говоря, протокол сетевой синхронизации времени) будет использовать фаззинг. Причем контрольная сумма в UDP пакете будет корректной, в качестве порта будет использоваться порт 123 (стандартный для NTP), а версия NTP будет установлена на 4 (т.к. она явно задана при создании пакета). Остальные поля будут заполнены случайными значениями. СнифингНе даром мы устанавливали WinPcap и модуль для работы с ним: в Scapy реализованы отличные возможности для снифинга данных. Основная функция sniff (), в качестве параметров которой можно указать интерфейс для прослушки, задать фильтр и количество пакетов для перехвата. Если интерфейс не указан, снифинг производится по всем интерфейсам сразу. Вот так просто можно перехватить ICMP-трафик, связанный с хостом 66.35.250.151:
Раз плюнуть!Самая главная фишка Scapy в том, что она позволяет обойтись без написания новой утилиты. Если дял написания Proof of concept для DoS'а Microsoft'овского стека IP требовалось 115 строчек на C, то в Scapy это можно реализовать всего лишь одной строкой: С помощью Scapy реально сотворить все что угодно. Хочешь сканнер портов с нужной тебе логикой - легко. Добавить возможность fingerprint'а? Раз плюнуть. А, впрочем, почему использовать его только для пентеста? Перехватывая и обрабатывая пакеты, можно легко сварганить уникальную IDS-систему с триггерами на любые события. И самое главное - сделать это очень просто. Скажу больше - никто не обязывает тебя постоянно работать через интерпретатор. Scapy очень просто подключить к своему Python сценарию как модуль и использовать все ее возможности на всю катушку! Дополнительные модулиЕсли в систему дополнительно установить Pyx и MikTex, то Scapy позволит построить 2D-графики и экспортировать их формат PDF:
Процесс передачи пакетов можно отобразить и в виде 3D-диаграммы. Для этого потребуется VPython и следующая команда:
У Scapy нет встроенных функций для определения типа ОС на удаленном хосте, но зато есть возможность использовать всю мощ утилит Nmap и Queso (их предварительно нужно установить в систему:
Шпаргалка по функциям Scapy
WARNINGПри всем функционале, надо признать, что у Scapy есть и ряд недостатков. Прежде всего, стоит помнить, что тулза написана на Python с несколькими уровнями абстракции, и работает это не очень быстро. Скорость передачи пакетов в 6 Мбит/с - пожалуй, верхний предел. Более того, в случае работы с большим количеством пакетов может потребоваться много памяти. DVDВсе, что нужно для работы со Scapy, ты найдешь на нашем DVD. Там же будут примеры сценариев для различных приемов (например, DNS-спуфинг), а также примеры Python-сценариев с использованием Scapy как модуля WWW
|