Пишем сниффер scapy python windows

Обновлено: 02.07.2024

Python и SCAPY

-------------------------
В scapy можно собирать пакеты изначально пропустив низкие уровни, начав сразу с прикладного.
Уровни разделяются косой чертой - "/"
>>> Ether()/IP()/TCP()/”TEST”

Соберем пакет и посомтрим его содержимое методами summary() и show():
>>> p=IP(dst="192.168.255.11")/ICMP()/"Test"

Примеры сборки пакетов с указанием диапазона(в круглых скобках) или списка(в квадратных скобках) портов:
>>> p=IP(dst="192.168.255.11")/TCP(dport=(1,60))
>>> p
<IP frag=0 proto=tcp dst=192.168.255.11 |<TCP dport=(1, 60) |>>

Посмотреть все пакеты, которые будут посланы при множестве целей портов с помощью for:
>>> [a for a in p]
[<IP frag=0 proto=tcp dst=192.168.255.11 |<TCP dport=tcpmux |>>,
<IP frag=0 proto=tcp dst=192.168.255.11 |<TCP dport=smtp |>>,
<IP frag=0 proto=tcp dst=192.168.255.11 |<TCP dport=nicname |>>,
<IP frag=0 proto=tcp dst=192.168.255.11 |<TCP dport=60 |>>]

-------------------------
Базовые действия с полями пакета:

Создадим IP пакет и зададим поле ttl:
>>> a=IP(ttl=10)
>>> a
< IP ttl=10 |>

Посмотрим поле пакета
>>> a.src
’127.0.0.1’

Удалим поле из пакета:
>>> del(a.ttl)
>>> a
< IP dst=192.168.1.1 |>
>>> a.ttl
64

-------------------------
Посомтреть основные возможности scapy можно с помощью lsc():
>>> lsc()

Получить информацию по функциям из lsc() можно так:
>>> help(traceroute)

Пример отправки ICMP на определенный адрес:
>>> send(IP(dst="192.168.255.11")/ICMP())

Из приведенного выше вывода, мы можем видеть, вернулись флаги "SA" или SYN-ACK, указывающие на открытый порт.

Приведенный выше пример будет даже печатать тип ошибки ICMP, если пакет ICMP был получен в ответ вместо ожидаемого TCP.

Для более крупных сканирований мы можем построить таблицу открытых портов:
ans.filter(lambda (s,r):TCP in r and r[TCP].flags&2).make_table(lambda (s,r):
. (s.dst, s.dport, "X"))
77.88.55.55
80 X

-------------------------
Теперь рассмотрим снифер - функция sniff():
Информация:
help(sniff)

"Ctrl+C" прерывает процесс захвата трафика и выведет результат, результат попадет в "_".

Метод summary() выводит статистику по принятым пакетам:
>>> sniff()
^C<Sniffed: TCP:2 UDP:12 ICMP:6 Other:0>

>>> _.summary()
Ether / IP / TCP 192.168.45.63:49296 > 192.168.255.82:ssh A / Padding
Ether / IPv6 / UDP fe80::10:74ff:fe96:33a:dhcpv6_client > ff02::1:2:dhcpv6_server / DHCP6_Solicit / DHCP6OptElapsedTime / DHCP6OptClientId / DHCP6OptIA_NA / DHCP6OptOptReq
Ether / IP / ICMP 192.168.45.63 > 192.168.255.82 echo-request 0 / Raw
Ether / IP / ICMP 192.168.255.82 > 192.168.45.63 echo-reply 0 / Raw
Ether / IP / ICMP 192.168.45.63 > 192.168.255.82 echo-request 0 / Raw
Ether / IP / ICMP 192.168.255.82 > 192.168.45.63 echo-reply 0 / Raw
Ether / IP / ICMP 192.168.45.63 > 192.168.255.82 echo-request 0 / Raw
Ether / IP / ICMP 192.168.255.82 > 192.168.45.63 echo-reply 0 / Raw
Ether / IPv6 / UDP fe80::10:74ff:fe96:33a:dhcpv6_client > ff02::1:2:dhcpv6_server / DHCP6_Solicit / DHCP6OptElapsedTime / DHCP6OptClientId / DHCP6OptIA_NA / DHCP6OptOptReq
Ether / IP / TCP 192.168.45.63:49296 > 192.168.255.82:ssh PA / Raw

>>> p=sniff()
^C>>> p.summary()
Ether / IP / TCP 192.168.45.63:49296 > 192.168.255.82:ssh A / Padding
Ether / IP / ICMP 192.168.45.63 > 192.168.255.82 echo-request 0 / Raw
Ether / IP / ICMP 192.168.255.82 > 192.168.45.63 echo-reply 0 / Raw
Ether / IPv6 / UDP fe80::10:74ff:fe96:33a:dhcpv6_client > ff02::1:2:dhcpv6_server / DHCP6_Solicit / DHCP6OptElapsedTime / DHCP6OptClientId / DHCP6OptIA_NA / DHCP6OptOptReq
Ether / IP / ICMP 192.168.45.63 > 192.168.255.82 echo-request 0 / Raw
Ether / IP / ICMP 192.168.255.82 > 192.168.45.63 echo-reply 0 / Raw
Ether / IPv6 / UDP fe80::10:74ff:fe96:33a:dhcpv6_client > ff02::1:2:dhcpv6_server / DHCP6_Solicit / DHCP6OptElapsedTime / DHCP6OptClientId / DHCP6OptIA_NA / DHCP6OptOptReq
Ether / IP / TCP 192.168.45.63:49296 > 192.168.255.82:ssh PA / Raw

Запись дампа в файл и его чтение:
>>> wrpcap("test.pcap",p)

>>> _.summary()
Ether / IP / TCP 192.168.45.63:49296 > 192.168.255.82:ssh A / Padding
Ether / IP / ICMP 192.168.45.63 > 192.168.255.82 echo-request 0 / Raw
Ether / IP / ICMP 192.168.255.82 > 192.168.45.63 echo-reply 0 / Raw
Ether / IPv6 / UDP fe80::10:74ff:fe96:33a:dhcpv6_client > ff02::1:2:dhcpv6_server / DHCP6_Solicit / DHCP6OptElapsedTime / DHCP6OptClientId / DHCP6OptIA_NA / DHCP6OptOptReq
Ether / IP / ICMP 192.168.45.63 > 192.168.255.82 echo-request 0 / Raw
Ether / IP / ICMP 192.168.255.82 > 192.168.45.63 echo-reply 0 / Raw
Ether / IPv6 / UDP fe80::10:74ff:fe96:33a:dhcpv6_client > ff02::1:2:dhcpv6_server / DHCP6_Solicit / DHCP6OptElapsedTime / DHCP6OptClientId / DHCP6OptIA_NA / DHCP6OptOptReq
Ether / IP / TCP 192.168.45.63:49296 > 192.168.255.82:ssh PA / Raw

-------------------------
Работа с таблицей маршрутизации:

Вывод таблицы маршрутизации:
>>> conf.route
Network Netmask Gateway Iface Output IP
0.0.0.0 0.0.0.0 192.168.255.11 hn0 192.168.255.82
127.0.0.1 255.255.255.255 0.0.0.0 lo0 127.0.0.1
192.168.255.0 255.255.255.0 0.0.0.0 hn0 192.168.255.82
192.168.255.82 255.255.255.255 0.0.0.0 lo0 127.0.0.1
192.168.255.83 255.255.255.255 0.0.0.0 lo0 127.0.0.1

Добавление записей:
>>> conf.route.add(net="1.1.1.0/24",gw="192.168.1.1")
>>> conf.route.add(host="2.2.2.2",gw="192.168.1.1")
>>> conf.route
Network Netmask Gateway Iface Output IP
0.0.0.0 0.0.0.0 192.168.255.11 hn0 192.168.255.82
127.0.0.1 255.255.255.255 0.0.0.0 lo0 127.0.0.1
192.168.255.0 255.255.255.0 0.0.0.0 hn0 192.168.255.82
192.168.255.82 255.255.255.255 0.0.0.0 lo0 127.0.0.1
192.168.255.83 255.255.255.255 0.0.0.0 lo0 127.0.0.1
1.1.1.0 255.255.255.0 192.168.1.1 hn0 192.168.255.82
2.2.2.2 255.255.255.255 192.168.1.1 hn0 192.168.255.82

Удаление записи:
>>> conf.route.delt(host="2.2.2.2",gw="192.168.1.1")
>>> conf.route
Network Netmask Gateway Iface Output IP
0.0.0.0 0.0.0.0 192.168.255.11 hn0 192.168.255.82
127.0.0.1 255.255.255.255 0.0.0.0 lo0 127.0.0.1
192.168.255.0 255.255.255.0 0.0.0.0 hn0 192.168.255.82
192.168.255.82 255.255.255.255 0.0.0.0 lo0 127.0.0.1
192.168.255.83 255.255.255.255 0.0.0.0 lo0 127.0.0.1
1.1.1.0 255.255.255.0 192.168.1.1 hn0 192.168.255.82

Сброс:
>>> conf.route.resync()
>>> conf.route
Network Netmask Gateway Iface Output IP
0.0.0.0 0.0.0.0 192.168.255.11 hn0 192.168.255.82
127.0.0.1 255.255.255.255 0.0.0.0 lo0 127.0.0.1
192.168.255.0 255.255.255.0 0.0.0.0 hn0 192.168.255.82
192.168.255.82 255.255.255.255 0.0.0.0 lo0 127.0.0.1
192.168.255.83 255.255.255.255 0.0.0.0 lo0 127.0.0.1

-------------------------
TCP-Traceroute
В отличие от других программ, которые ждут TraceRoute для каждого узла, чтобы ответить, прежде чем переходить к следующему,
scapy отправляет все пакеты в то же время.
Недостаток: он не может знать, когда остановиться (при этом параметр maxttl), но большое преимущество, что он взял менее 3 секунд.

Scapy — инструмент создания и работы с сетевыми пакетами. Программа написана на языке python, автор Philippe Biondi. Познакомиться с основным функционалам можно здесь. Scapy — универсальный, поистине мощный инструмент для работы с сетью и проведения исследований в области информационной безопасности. В статье я попытаюсь заинтересовать Вас использовать scapy в своей работе/проектах. Думаю, что лучше всего этого можно добиться, показав на примерах основные преимущества scapy.
В качестве примеров я возьму простые и наглядные задачи, которые можно решить средствами scapy. Основным направлением будет формирование пакетов для реализации того или иного вида атак.

ARP-spoofing

Сформированный таким образом пакет «отравит» arp кэш targetIP. Одна из сильных черт scapy — наглядность, то есть Вам необходимо понимать, что Вы хотите сделать, конечно это может создать некоторые трудности, но зато поможет сформировать целостную картину и защитит от «выстрела в ногу». Например, взглянув на сформированный таким образом пакет, становится понятно, что ARP-spoofing не вылечить с помощью port security потому, что MAC адрес отправителя не меняется, в таком случае нас спасет только arp инспекция. Хотя, давайте попробуем реализовать защиту с использованием scapy. Предположим, что весь трафик коммутатора мы зеркалируем на порт, где у нас будет происходить анализ. Выявлять атаку предлагаю по принципу, если компьютер не отправлял arp запрос, то и arp ответа он получать не должен.

Скрипт отрабатывает заложенную логику и такие программы, как например «cain & abel» не смогут бесшумно провести ARP-spoofing. Но мы с Вами знаем, что есть особенности реализации arp в некоторых операционных системах, а именно если компьютеру приходит arp запрос с просьбой сообщить информацию о себе, он автоматически доверяет ему и заносит соответствие ip-mac отправителя к себе в таблицу. Т.е. следующий пакет так же «отравит» arp кэш.

В этом случае наш скрипт не будет эффективен. Получается, что работая со scapy Вы изучаете не только программу, но и сами протоколы, их логику.

VLAN Hooping

Следующим достоинством scapy, считаю — гибкость. Классическим примером(гибкости) является ситуация, когда нам необходимо произвести arp-spoofing в соседнем vlan, нам не придется писать новую программу, надо правильно собрать пакет.

К сожалению, даже в случае успешной реализации, мы получим одностороннюю связь и для организации MITM внутри соседнего vlan нам будет нужен «свой агент».

CAM Table Overflow

RandMAC() — функция возвращает произвольное значение, в формате MAC адреса; параметр loop — зацикливает отправку, что в итоге приводит к исчерпанию буфера таблицы коммутатора. Наверное, это пример простоты реализации некоторых атак.

Больше примеров

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

HSRP spoofing
src mac – HSRP virtual MAC (возможный диапазон 00:00:0C:9F:F0:00 — 00:00:0C:9F:FF:FF); dst mac – IP v4 multicast MAC (возможный диапазон 01:00:5E:00:00:00 — 01:00:5E:00:00:FF); ip dst – ipv4 multicast address (224.0.0.0/24); priority – приоритет маршрута, значения от 0 до 255; inter=3 — в соответствии с интервалом по умолчанию на оборудовании cisco; все остальные настройки, аналогичны настройкам по умолчанию оборудования cisco. Такой пакет сделает attacerIP активным HSRP маршрутом.
Различные способы сканирование портов.
Посмотреть результат можно таким образом.
Или так.

Следующая положительная особенность scapy — возможность создавать протоколы самостоятельно.Протокол DTP не реализован в рамках штатного набора, зато его можно загрузить как модуль.

Опасность DTP состоит в том, что мы самостоятельно можем перевести порт коммутатора в режим trunk и получить расширенный доступ. Если взглянуть в исходники модуля, то увидим там функцию которая нам поможет включить режим trunk на интерфейсе.

Вместе с загрузкой протокола DTP, мы загружаем и функцию negotiate_trunk, можем её выполнить прямо из консоли интерпретатора и результат не заставит себя долго ждать.

802.11

Scapy может успешно работать с беспроводными сетями, в большинстве функционала способен заменить Aircrack-ng. Например, посмотреть список доступных сетей можно так.

Довольно просто, давайте что-нибудь посложнее. Предположим, что Вам поставлена задача не допустить работы беспроводных устройств на контролируемой территории. Каким образом это организовать, если не прибегать к радиочастотным глушителям? Одним из вариантов может являться подавление работы устройств пользователей. Организовать это можно путем отправки клиентам Deauth пакета.

Скрипт широковещательной отправки Deauth пакетов

Начинающие исследователи могут упростить подход к задачам фаззинга протоколов, в scapy реализован простейший функционал. Например, простейший фаззинг Beacon пакетов может выглядеть так.

Нагрузочное тестирование

Последним в списке примеров, но далеко не последним по значению, у меня будет использование scapy для проведения нагрузочного тестирования на каналы связи. Я в этом вопросе не специалист и возможно объём генерируемого трафика не самый важный параметр, но все же. В scapy это делается просто, как и многое другое.

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



На стороне приема трафика замер wireshark'ом подтверждает цифры отправителя.


Итоги

Итак, перечислим достоинства.
1) Наглядность (понимание того, что будет происходить)
2) Гибкость (пакеты можно собирать как угодно)
3) Расширяемость (создание собственных протоколов)
4) Python
Надеюсь, мне удалось достичь поставленных целей и в случае необходимости Вы вспомните о существовании такого инструмента, как scapy. Если будет интерес к статье, я постараюсь написать(перевести и адаптировать) материал по созданию собственных протоколов в scapy.

Scapy - это мощный инструмент, написанный на Python, и многие отличные инструменты для атак сетевого сканирования в настоящее время используют этот модуль. Вы также можете использовать этот модуль в своих собственных программах для отправки, отслеживания и анализа сетевых пакетов данных. Этот модуль более низкоуровневый, чем Nmap. Вы можете более интуитивно понимать все виды сканирующих атак в сети.

По сравнению с Nmap, модуль Scapy покажет вам только полученный пакет данных и не скажет вам, что этот пакет означает.

Например, когда вы пойдете в больницу, чтобы проверить свое тело, в больнице вам выдадут результаты проверки по различным показателям вашего тела, а врач также скажет вам, какое у вас заболевание или нет. Тогда Nmap похож на врача, он сделает это за вас и предоставит вам результаты на основе своего опыта. Scapy похож на прибор для физического осмотра. Он расскажет вам только результаты различных обследований. Если вы опытный врач, очевидно, что результаты обследования заслуживают большего внимания, чем предложения ваших коллег.

Основное использование


Scapy уже интегрирован в Kali, и мы можем запустить его, набрав Scapy в терминале.

Scapy предоставляет ту же интерактивную командную строку, что и Python. Мне нужно поговорить об этом здесь. Я выполню следующие примеры в этой командной строке.

Основные операции Scapy

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

Наиболее важными атрибутами пакета данных IP являются адрес источника и адрес назначения. Эти два атрибута можно установить с помощью src и dst. Например, вы можете написать это для создания пакета данных, отправленного на адрес «192.168.1.107».


Целевым значением dst может быть IP-адрес или сегмент сети, например 192.168.1.0/24. В настоящее время вместо пакета данных создается 256 пакетов данных. .

Если вы хотите просмотреть каждый пакет, вы можете использовать[p for p in ip] 。

Scapy использует многоуровневую форму для создания пакетов данных, обычно нижним протоколом является Ether, затем IP, а затем TCP или UDP. Функцию IP () нельзя использовать для создания пакетов запроса и ответа ARP, поэтому в настоящее время можно использовать Ether () .Эта функция может устанавливать MAC-адреса отправителя и получателя. Итак, теперь для генерации широковещательного пакета выполняется следующая команда.

В настоящее время Scapy использует наиболее часто используемые категорииEther, IP, TCP и UDP, Но какие атрибуты у этих классов? Очевидно, что в классе Ether требуются исходный адрес, адрес назначения и тип. Атрибуты класса IP намного сложнее: помимо наиболее важных адресов источника и назначения, существуют также версия, длина, тип протокола, контрольная сумма и т. Д. Класс TCP требует порта источника и порта назначения. Здесь можно использоватьls() Функция, чтобы узнать, какие свойства имеет класс.


Например, используйте ls (Ether ()) для просмотра свойств класса Ether.

Вы также можете посмотреть атрибуты в классе IP ().



Вы можете установить соответствующие атрибуты внутри, например, чтобы установить значение ttl равным 32, вы можете использовать следующие методы.

Функции в модуле Scapy


Результаты.

Примечание: эти две функции только отправляются, но не принимаются


Результаты.

предоставляет три функции для отправки и получения пакетов данных в Scapy: ** sr (), sr1 () и srp () **, где sr () и sr1 ( ) Работает на третьем уровне, например, IP и ARP, а srp () работает на втором уровне.
Здесь мы по-прежнему отправляем пакет ICMP на адрес 192.168.1.107, чтобы сравнить разницу между sr () и send ().

Результаты.

Когда отправляются пакеты данных, сгенерированные Chancheng ==, Scapy будет отслеживать количество полученных пакетов данных, и в ответах будут указаны соответствующие пакеты данных ответа.
Функция sr () является ядром Scapy. Ее возвращаемое значение - два списка. Первый список - это пакет, получивший ответ и соответствующий ответ, а список Doylego - Получен ответный пакет. Поэтому используйте два списка, чтобы сохранить возвращаемое значение sr ().

Ans и unans используются здесь для сохранения возвращаемого значения sr (), потому что это пакет запроса ICMP, который отправляется, и пакет ответа также получен, поэтому отправленный пакет и полученный Все полученные ответные пакеты сохраняются в списке ans. Используйте ans.summary () для просмотра содержимого двух пакетов данных, и список unans пуст.


Функция sr1 () в основном такая же, как функция sr (), но значение возвращает пакет ответа. Только нужно использовать список, чтобы сохранить возвращаемое значение этой функции. Например, используйте p, чтобы сохранить возвращаемое значение sr1 (IP (dst = "192.168.1.107") / ICMP ()).

Вы можете использовать функцию sr1 (), чтобы проверить, открыт ли определенный порт цели, используя метод полуоткрытого сканирования (SYN).


Результат выполнения показан на рисунке.

Из значения p выше видно, что 192.168.1.107 ответил TCP-пакетом с установленным битом флага SYN, что указывает на открытие порта 80.


Еще одна очень важная функция - sniff (). Если вы использовали Tcpdump, вы наверняка знакомы с использованием этой функции. С помощью этой функции вы можете захватывать пакеты данных, проходящие через локальную сетевую карту, в вашей собственной программе.

Здесь есть небольшая ловушка, то есть он не может отвечать в реальном времени, вы должны перестать обнюхивать его, чтобы повторить пакеты, которые он обнюхал.

Сила этой функции заключается в том, что вы можете использовать фильтр сладкого картофеля для фильтрации пакетов данных. Например, чтобы указать захват пакетов данных, относящихся к 192.168.1.107, вы можете использовать "host 192.168.1.107":

Точно так же вы также можете использовать фильтр для фильтрации указанного протокола, например пакетов данных типа ICMP.

Если вы хотите выполнить несколько условий одновременно, вы можете использовать реляционные операторы, такие как «и» и «или», чтобы выразить:

Два других очень важных параметра:iface、count. iface можно использовать для указания отслеживаемой сетевой карты, например, чтобы указать eth0 в качестве сетевой карты мониторинга, вы можете использовать:

Счетчик используется для указания количества отслеживаемых пакетов, и мониторинг остановится, когда будет достигнуто указанное количество. Например, отслеживаются только 30 пакетов:

Теперь разработайте комплексный приемник, который будет прослушивать пакеты ICMP с адресом источника или назначения 192.168.1.107 на сетевой карте eth0 и останавливаться, когда он получит три таких пакета:


результат операции:
Если вы хотите просмотреть содержимое этих трех пакетов, вы можете использовать «_». В Scapy этот символ указывает результат выполнения предыдущего оператора. Например:


результат операции:
Только что использованная функция pkt.summary () используется для отображения содержимого pkt в форме сводки, длина сводки составляет одну строку.


результат операции:
Примечание. Функция pkt.summary такая же, как и у pkt.nsummary (), за исключением того, что объект операции представляет собой отдельный пакет данных.

Общие простые примеры модулей Scapy

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

Используйте scapy для реализации сканирования портов типа ACK, чтобы проверить, заблокированы ли порты 21, 22, 23, 135, 443, 445 из 192.168.1.107,Учтите, что он экранирован, а не закрыт! Используя режим сканирования ACK, вы можете создать следующий командный режим.


результат операции:

Обычно, если открытый порт отвечает пакетом ACK, а закрытый, он отвечает пакетом RST. В сети некоторые устройства безопасности будут фильтровать некоторые порты. Эти порты не будут отвечать на пакеты данных извне. Все пакеты данных, отправленные на эти порты, разваливаются. Состояние этих портов не открыто и не закрыто. Это обычно используется в управлении сетевой безопасностью. метод.

Сначала проверьте нефильтрованные порты:


результат операции:

Напишите сканер портов

Давайте воспользуемся мощной функцией обработки пакетов Scapy, чтобы разработать сканер открытия портов. Обратите внимание, что здесь следует отметить разницу между предыдущим примером и предыдущим примером: если порт находится в экранированном состоянии, он не будет генерировать никаких пакетов ответа. Если порт находится в открытом состоянии, он ответит пакетом подтверждения после получения пакета синхронизации. И наоборот, если порт закрыт, он ответит после получения пакета syn - первого пакета. Сначала запустите терминал в Kali Linux 2 и откройте Python в терминале. Сначала импортируйте файл модуля, который вам нужен

Затем сгенерируйте SYN-пакет с адресом «192.168.1.107» на порту 80 и установите для этого флага значение «S»:

Затем используйте проверку цикла, если r [TCP] .flags == 18, это означает, что целевой порт открыт, если это 20, он закрыт.


результат операции:

Вся информа­ция пре­дос­тавле­на исклю­читель­но в озна­коми­тель­ных целях. Ни редак­ция, ни автор не несут ответс­твен­ности за любой воз­можный вред, при­чинен­ный матери­ала­ми дан­ной статьи.

Вступительное слово

Доб­рого вре­мени суток, дорогой Username, сегод­ня хотелось бы тебе рас­ска­зать об одной мощ­ней­шей биб­лиоте­ке для язы­ка питон, которая так­же позици­они­рует­ся как фрей­мворк. Имя ей Scapy. Дан­ный инс­тру­мент пре­дос­тавля­ет нам прос­то огромные воз­можнос­ти по работе с сетевы­ми тех­нологи­ями. Нап­ример, он может собирать пакеты с пос­леду­ющей отправ­кой их в сеть, зах­ватывать пакеты, а так­же читать их из сох­ранен­ного ранее дам­па, иссле­довать сети и мно­гое дру­гое. Все перечис­ленное мож­но делать «в пря­мом эфи­ре» (то есть из кон­соли питона) или же пос­редс­твом написа­ния скрип­тов. Раз­работ­ка дан­ной ути­литы изна­чаль­но велась под UNIX-подоб­ные сис­темы, одна­ко запус­тить ее воз­можно и на опе­раци­онных сис­темах семей­ства Windows. Так­же она неп­лохо вза­имо­дей­ству­ет с дру­гими биб­лиоте­ками язы­ка питон. Нап­ример, gnuplot поможет нам в пос­тро­ении гра­фиков, визу­али­зируя работу инс­тру­мен­та, — что немало­важ­но, ведь гра­фичес­кого интерфей­са Scapy не име­ет.

Всю тех­ничес­кую докумен­тацию по исполь­зованию Scapy мож­но най­ти на офи­циаль­ном сай­те про­екта

Установка модуля Scapy

Ну что ж, прис­тупим. Начать, я думаю, сто­ит с опи­сания уста­нов­ки дан­ной ути­литы. Для ее работы нам пот­ребу­ется уста­нов­ленный Python 2.6+, а так­же допол­нитель­ные биб­лиоте­ки вро­де pylibpcap . Если уста­нов­ка про­изво­дит­ся на Linux и он осно­ван на Debian, то уста­нов­ка сво­дит­ся к одной коман­де apt-get install python-scapy . Если же сис­тема осно­вана на чем‑либо дру­гом, то поможет сле­дующая оче­ред­ность команд:

Ну что же, с уста­нов­кой на Linux мы разоб­рались, но как же быть обла­дате­лям осталь­ных ОС? Нач­нем, пожалуй, с обла­дате­лей тех­ники, про­изве­ден­ной одной яблочной ком­пани­ей. Для уста­нов­ки на ОС дан­ного семей­ства нам при­дет­ся воору­жить­ся буб­ном. Пер­вым делом уста­новим MacPorts. Это дос­таточ­но мощ­ная ути­лита, которая дает воз­можность уста­нов­ки соф­та, пор­тирован­ного с Linux. Очень под­робную инс­трук­цию по ее уста­нов­ке мож­но най­ти на офи­циаль­ном сай­те про­екта. Далее есть два пути раз­вития событий. Пер­вый пре­дус­матри­вает соз­дание сво­его велоси­педа (что мало прив­лека­ет), а во вто­ром мы вос­поль­зуем­ся скрип­том, уже написан­ным за нас замеча­тель­ным челове­ком с ником 0x90 (при­вет, HardWare Village!). Най­ти его мож­но в репози­тории на гит­хабе. За скрипт авто­ру огромное спа­сибо. Все, что нам необ­ходимо сде­лать далее, — ско­пиро­вать скрипт, выпол­нить его от име­ни поль­зовате­ля root и дож­дать­ся отче­та об успешной уста­нов­ке. В моем слу­чае исполь­зовалась OS Х 10.10 — полет нор­маль­ный :).

Ос­талось у нас еще одно семей­ство ОС, которым, к сожале­нию, поль­зуют­ся очень мно­гие, — Windows. Для уста­нов­ки нам необ­ходимо перей­ти на сайт раз­работ­чика и ска­чать пос­леднюю вер­сию Scapy, далее рас­паковать ее и в коман­дной стро­ке выпол­нить сле­дующую коман­ду:

Пос­ле окон­чания уста­нов­ки, что­бы про­верить работос­пособ­ность мы запус­каем интер­пре­татор питона и пишем коман­ду import scapy . Стан­дар­тное окно Scapy, пред­лага­ющее начать ввод, пред­став­лено на рис. 1.

По­шаго­вый про­цесс уста­нов­ки Scapy под Windows мож­но изу­чить по сле­дующе­му ви­део.

Рис. 1. Окно приветствия Scapy

Рис. 1. Окно при­ветс­твия Scapy

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

Первое знакомство со Scapy

Для начала пред­лагаю озна­комить­ся с основным фун­кци­она­лом это­го чудо‑ком­бай­на. Одной из самых важ­ных для нович­ка фун­кций по пра­ву мож­но счи­тать ls( ) . Выпол­нив ее, мы уви­дим спи­сок из более чем трех­сот про­токо­лов, под­держи­ваемых этой ути­литой. Выг­лядит это при­мер­но так, как изоб­ражено на рис. 2.

Рис. 2. Список поддерживаемых Scapy протоколов

Рис. 2. Спи­сок под­держи­ваемых Scapy про­токо­лов

Од­нако так будет лишь в том слу­чае, если фун­кцию ls выпол­нить без парамет­ров, а вот если в качес­тве парамет­ра ука­зать имя какого‑либо про­токо­ла, то мы получим деталь­ную информа­цию о его струк­туре (см. рис. 3).

Рис. 3. Детальное строение пакета

Рис. 3. Деталь­ное стро­ение пакета

Обыч­но наиболь­ший инте­рес пред­став­ляет спи­сок всех полей, которые мож­но изме­нить в про­цес­се соз­дания пакетов. Основной фун­кци­онал инс­тру­мен­та мож­но пос­мотреть коман­дой lsc( ) — она выведет все име­ющиеся в арсе­нале фун­кции, но нам ведь это­го мало, вер­но? Хотелось бы пос­мотреть ману­ал по фун­кци­ям, и в этом нам поможет коман­да help( ) , парамет­ром которой мож­но ука­зать что‑нибудь из получен­ного спис­ка. Возь­мем, нап­ример, help( sniff) — она выдаст нам под­робную информа­цию по фун­кции sniff (см. рис. 4):

Рис. 4. Справка по функции sniff

Рис. 4. Справ­ка по фун­кции sniff

Ну а теперь поп­робу­ем написать самый прос­той скрипт:

Чис­ло count озна­чает количес­тво пакетов, которые мы будем слу­шать в эфи­ре до окон­чания прог­раммы. В нашем слу­чае это десять, но этот параметр не явля­ется обя­затель­ным, и если его не ука­зать, то сни­фер будет работать до получе­ния завет­ной ком­бинации ctrl + c . Метод nsummary( ) , в свою оче­редь, выводит дос­таточ­но под­робную ста­тис­тику о зах­вачен­ном тра­фике. Я запус­кал получив­ший­ся скрипт с вклю­чен­ным Wi-Fi и вот что получил на выходе:

0003 RadioTap / 802. 11 Management 8L c8 : 64 : c7 : 37 : 48 : fd > ff : ff : ff : ff : ff : ff / Dot11Beacon / SSID = 'byfly WIFI' / Dot11Elt / Dot11Elt / Dot11Elt / Dot11Elt / Dot11Elt / Dot11Elt / Dot11Elt / Dot11Elt

Мы видим наш эфир, какие сети ловят­ся, MAC-адре­са, а так­же SSID. В дан­ном слу­чае мы пой­мали Beacon-пакет от Wi-Fi-сети, имя которой byfly WIFI , а MAC-адрес веща­ющей точ­ки — c8: 64: c7: 37: 48: fd , тип вещания 802. 11 Management . А теперь добавим в наш скрипт фун­кцию wrpcap( ) , которая, как мож­но догадать­ся, дает нам воз­можность записать зах­вачен­ный тра­фик в файл.

Файл с име­нем our_dump. pcap соз­дас­тся в дирек­тории с нашим скрип­том, если не ука­зан пол­ный путь. Поз­же его мож­но будет про­ана­лизи­ровать мощ­ным инс­тру­мен­том под наз­вани­ем Wireshark, который мож­но запус­тить пря­мо из скрип­та коман­дой wireshark( ) . Кста­ти говоря, про Wireshark есть дос­таточ­но кру­тая статья на хаб­ре. Нас­тоятель­но рекомен­дую озна­комить­ся.

ARP spoofing c помощью ScaPy

Все это, конеч­но, инте­рес­но, но давай уже рас­смот­рим реаль­ное при­мене­ние это­го инс­тру­мен­та. Для при­мера я выб­рал одну из моих любимых атак — ARP poisoning, так­же извес­тную под наз­вани­ем ARP spoofing. Перед тем как прис­тупить к реали­зации, хотелось бы рас­ска­зать нем­ного о самой ата­ке. На каж­дой машине в сети име­ется такая вещь, как ARP-таб­лица, — она хра­нит соот­ношения IP-адре­сов машин в сети с их MAC-адре­сами. Суть ата­ки зак­люча­ется в сле­дующем: ког­да ата­куемая машина посыла­ет зап­рос на поиск роуте­ра в сети, дабы отос­лать какую‑либо информа­цию, мы посыла­ем ей лож­ный пакет с дан­ными, в которых говорит­ся «мы и есть роутер», и весь тра­фик, который дол­жен был идти нап­рямую в Сеть, идет туда, но уже через нас, то есть такой вари­ант реали­зации клас­сичес­кой MITM-ата­ки.

Intercepter-NG

Счи­таю прос­то необ­ходимым отме­тить один инс­тру­мент, где ARP spoofing ата­ка реали­зова­на на высочай­шем уров­не, — Intercepter-NG, не раз упо­минав­ший­ся на стра­ницах жур­нала. Пос­мотреть под­робный гайд, а так­же ска­чать сам инс­тру­мент мож­но на офи­циаль­ном сай­те.

Ре­али­зовы­вать ата­ку, как ты понял, мы будем на язы­ке Python с исполь­зовани­ем биб­лиоте­ки Scapy. Для прос­тоты я буду при­водить час­ти прог­рам­мно­го кода, а потом раз­бирать их. Пер­вой частью, конеч­но же, будет


После этого запуск происходит непосредственно командой scapy.
На экране отобразится примерно так:
Мы видим стандартное приглашение для ввода, все действия будут выполняться в интерактивном режиме.
Выход происходит комбинацией Ctrl+D, либо набрав функцию exit().

Можно создавать сразу пакеты высоких уровней (сетевого и прикладного), и Scapy автоматически дополнит низлежащие уровни, а можно вручную собирать, начиная с канального уровня.
Разделяются уровни модели OSI символом прямого слэша (/).
Нужно обратить внимание на то, что Scapy читает пакет от нижнего уровня слева, до более высокого справа. Поначалу это может немного сбивать с толку, но после небольшой практики всё станет вполне привычно.
К слову, в терминологии Scapy сетевой пакет разделяется на слои, и каждый слой представляется как экземпляр объекта.
Собранный пакет в упрощенном виде может выглядеть как:

Мы уже смотрели на вывод функции ls(), но не всегда нужна такая подробная информация о пакете.
Достаточно просто набрать имя переменной и сразу увидеть краткую сводку:
Так же можно использовать метод summary():
Если же нужно чуть больше информации, то есть метод show():
Кроме того, можно просмотреть любое поле, просто указав его:
Разумеется, это работает только в том случае, если такие поля уникальны в пределах пакета.
Если, например, взять поле flags, которое присутствует как в TCP, так и в IP, тут уже нужно конкретизировать, что мы хотим увидеть. В противном случае Scapy выведет значение первого найденного поля (IP flags в нашем примере).
Конкретизация происходит путем указания протокола в квадратных скобках:
К слову, по умолчанию установленные флаги выводятся в цифровом представлении.
Если все управляющие биты будут включены (установлены в 1), то получим значение равное 255. В нашем случае значение 2 говорит о том, что установлен SYN бит.
Но существует возможность отобразить управляющие биты и в символьном отображении:
Как уже говорилось, в любой момент можно достаточно просто поменять значение любого поля:
А в случае, если поле не является уникальным, то нужно указать протокол:
Вторым способом является использование конструкции payload, которая позволяет перепрыгнуть через один уровень (через L3 в нашем случае):
Здесь мы вначале просматриваем вывод слоев над L3, затем просматриваем значение TCP флагов и устанавливаем для них новое значение.
Кстати, можно даже несколько раз вызвать payload, поднимаясь при этом выше и выше:
Можно еще посмотреть на содержимое пакета в шестнадцатеричном виде, для этого есть функция hexdump():

С таким же размахом и широтой происходит и отправка пакетов:

Теперь рассмотрим ситуацию, если пакетов в ответ приходит много.
То, что мы увидели, было по сути, самое что ни есть сканирование портов.
Открытые порты будут с флагами SA (SYN/ACK), например:
Мы смотрим именно на пакет по номеру, счет традиционно начинается нуля.
Можно пойти дальше и распаковать этот результат:
Здесь мы извлекли из результата отправленный пакет (под номером 21) и ответ на него.
Но это только один пакет, а как быть, если нужно обработать все пакеты?
В таком случае придется вновь обращаться к циклу for:
Берем и разбиваем каждый элемент списка res на части a и b. Затем обрезаем часть “a”, заливая это всё в список “allsent”.
Аналогично создаем список allrec, только уже оставляем другую часть.
Всё это, конечно, хорошо, но хотелось бы в более удобном виде получить список открытых и закрытых портов.
Еще раз посмотрим на список res, a точнее на элемент res[0], который состоит из двух частей: пакет, который мы отправили res[0][0], и ответ, который получили res[0][1].
В ответе можно обнаружить три части — заголовок IP (res[0][1][0]), заголовок TCP (res[0][1][1]) и собственно сами данные (res[0][1][2]).
Используем цикл for для извлечения каждого элемента res[N] в переменную «а».
Теперь в переменной «a»содержится результат для каждого пакета. Другими словами «а» представляет собой ans[N].
Нам остается только проверить значения a[1][1], которые будут означать res[N][1][1] в заголовке TCP.
Если быть еще более точным, требуется значение 18, которое означает установленные флаги SYN-ACK.
В тех случаях, когда это условие сработает, мы еще выведем порт отправителя из заголовка TCP:
В итоге, получим результат в виде списка открытых портов.
Все вышеозначенные конструкции набираются за один раз, важно так же уделять внимание отступам (обычно это 4 пробела).
Мы только что вручную написали простой сканер портов, не больше и не меньше.

Всё, что мы рассматривали, происходило непосредственно в интерактивном режиме.
Но, естественно, многие вещи можно автоматизировать, написав скрипты.
Для этого в начале скрипта нужно будет указать:

И перенести модуль в свежесозданный каталог:

Теперь если зайти в Scapy и просмотреть список подключенных сторонних модулей (за это, как вы догадались, отвечает функция list_contrib()):

После этого, уже можно будет создавать пакеты для OSPF.

  • собрать заголовок IP, не забыть про адрес отправителя и получателя;
  • собрать TCP заголовок, в котором нужно будет указать TCP порты отправителя и назначения, установить TCP флаги (SYN бит) и сгенерировать ISN (Initial Sequence Number).

2) Поймать ответный пакет:

  • сохранить ответ;
  • извлечь из него TCP sequence number и увеличить это значение на единицу.

3) Создать подтверждение (ACK) на полученный ответный пакет:

  • собрать заголовок IP, содержащий такие же адреса отправителя и получателя, как в случае SYN пакета;
  • собрать TCP заголовок, с такими же номерами портов, как и в SYN сегменте, но уже установить ACK флаг, увеличить значение ISN на единицу и установить acknowledgement в извлеченный и увеличенный, на втором шаге, sequence number.

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

192.168.10.200 1024 > 192.168.10.50 80 flags=SYN seq=12345
192.168.10.50 80 > 192.168.10.200 1024 flags=SYN, ACK seq=9998 ack=12346
192.168.10.200 1024 > 192.168.10.50 80 flags=ACK seq=12346 ack=9999

  • собрать заголовок IP, в котором указать в качестве отправителя 192.168.10.200 и 192.168.10.50 в качестве получателя;
  • собрать TCP заголовок с портом источника (source) 1024 и портом назначения (destination) 80. Так же установить SYN флаг и сгенерировать ISN равный 12345.

2) Поймать ответный пакет:

  • сохранить ответ;
  • извлечь из него TCP sequence number (9998) и увеличить это значение на единицу, получим 9999.

3) Создать подтверждение (ACK) на полученный ответный пакет:

  • собрать заголовок IP, в котором указать в качестве отправителя 192.168.10.200 и 192.168.10.50 в качестве получателя;
  • собрать TCP заголовок с такими же портами источника и назначения (1024 и 80 соответственно), установить ACK флаг, увеличить ISN на единицу (12346) и установить acknowledgement в увеличенное значение пойманного seq number (9999).


Но здесь есть и несколько подводных камней.
Если посмотреть на этот обмен в Wireshark, можно увидеть, что до того как ушел наш ACK пакет, внезапно был отправлен RST:

Дело в том, что Scapy работает мимо TCP/IP стека ОС. Это означает то, что ОС не подозревает о том, что Scapy отправляет какие-то пакеты.
Соответственно ОС не будет ожидать появления SYN/ACK пакетов. И, следовательно, соединение будет сразу же сброшено.
Очевидно, что это совсем не тот результат, который нам нужен.
Одним из решений такой проблемы будет использование функционала пакетного фильтра, в частности iptables, который сможет блокировать исходящие RST пакеты.
Например, таким образом:


Выполнение такой конструкции приведет к тому, что все исходящие пакеты с адресом назначения 192.168.10.50 и с адресом отправителя 192.168.10.200 на 80-й порт, с установленным RST флагом, будут отбрасываться.
Пакеты будут все так же генерироваться силами ОС, но они просто не будут вылетать за ее пределы.
В итоге уже ничего не будет мешать Scapy делать полноценную TCP-сессию:

Все время мы смотрели на текстовый вывод, местами была псевдографика, но Scapy умеет и выводить некоторые результаты в графическом виде.
Посмотрим, что нам предлагается.
Самое простое — это метод conversations():
При его выполнении, запустится окно ImageMagick, в котором отрисуется схема нашего обмена пакетами, не ахти красиво, но достаточно наглядно.
Это способ, вероятно, лучше всего подойдет, для визуализации дампов с трафиком.
Второй способ заключается в построении 2D графиков, с последующим экспортом их в pdf-файл.
За это уже отвечает функция pdfdump().
Результаты выглядят примерно так:
В данном случае уже вполне неплохо.
Кроме того, функция graph() опять откроет окно ImageMagick, но уже с детальной прорисовкой:
Здесь мы видим результат трассировки, с подробным отображением автономных систем и прочей визуализацией.
И, завершая тему визуализации, а вместе с ней и статью, посмотрим на 3D отображения трассы.
Для этого потребуется VPython и команда trace3D().
Здесь отображена трасса из предыдущего графика.
Но иногда бывают и такие варианты:
В этом примере была проведена трассировка сразу нескольких целей, с использованием нескольких (80, 443) tcp портов.
Левый клик на любом объекте приведет к появлению IP-адреса над ним, а левый клик с зажатой клавишей CTRL – к отображению более подробной информации — портам, как в этом случае.


Итак, мы рассмотрели лишь малую часть утилиты Scapy, но уже это впечатляет.
Возможности, которые предоставляются действительно очень большие.
Статья призвана вызвать у читателя интерес в изучении сетевых протоколов, и не является исчерпывающим руководством по инструменту Scapy.
За использование этой утилиты в каких-либо противоправных целях ни редакция, ни автор ответственности не несут.

В процессе написания статьи использовались материалы Института SANS и официальная документация проекта.

Читайте также: