Введение
Scapy — это мощная интерактивная программа и библиотека для манипуляции сетевыми пакетами, написанная на языке Python. Она позволяет создавать или декодировать пакеты множества протоколов, отправлять их в сеть, перехватывать и сопоставлять запросы с ответами.
Особенность Scapy заключается в том, что она позволяет работать на уровне формирования пакетов, а не только на уровне сокетов или приложений. Это означает, что вы можете явно управлять заголовками, флагами, полями и комбинациями протоколов так, как это обычно скрыто в стандартных клиентских библиотеках.
В этой лабораторной работе вы изучите основы создания пакетов с помощью Scapy. Вы начнете с импорта необходимых модулей, затем перейдете к послойному формированию ICMP (ping) и TCP-пакетов. В завершение вы отправите эти пользовательские пакеты и проанализируете сетевые ответы. Этот практический опыт даст вам более глубокое понимание того, как работают сетевые протоколы «под капотом» и как специалисты по безопасности тестируют сетевую защиту.
Импорт модулей Scapy
На этом этапе вы настроите среду Python и импортируете необходимые модули Scapy. Хотя Scapy можно использовать как интерактивную консоль, написание скриптов позволяет легко сохранять, изменять и повторно использовать логику создания пакетов.
Это переход от использования протоколов к их конструированию. Вместо того чтобы просто просить существующее приложение отправить трафик за вас, вы сами определяете, как этот трафик должен выглядеть.
Сначала убедитесь, что вы находитесь в своей рабочей директории по умолчанию. Вы можете использовать команду pwd для проверки, но вы уже должны находиться в ~/project.
Создайте новый файл Python с именем packet_crafter.py, используя текстовый редактор nano.
nano packet_crafter.py
Внутри этого файла вам нужно импортировать библиотеку Scapy. Стандартный способ использования Scapy в скриптах — импорт всех функций из модуля scapy.all. Добавьте следующие строки в свой скрипт:
from scapy.all import *
print("Scapy modules imported successfully.")
Сохраните файл с помощью Ctrl+O и Enter. Если вы хотите продолжить работу над скриптом перед его тестированием, вы можете остаться в nano. Используйте Ctrl+X, когда будете готовы вернуться в терминал.
Теперь запустите свой скрипт с помощью Python, чтобы убедиться в отсутствии синтаксических ошибок и правильной загрузке библиотеки Scapy. Поскольку создание необработанных сетевых пакетов требует повышенных привилегий, вы должны запускать скрипт с помощью sudo.
sudo python3 packet_crafter.py
Вы должны увидеть вывод, аналогичный следующему, подтверждающий успех:
Scapy modules imported successfully.
В некоторых лабораторных средах Scapy может выводить дополнительное предупреждение от необязательных пакетов Python, таких как matplotlib, перед сообщением об успехе. Если вы все равно видите Scapy modules imported successfully., вы можете переходить к следующему шагу.
Формирование ICMP Echo Request
На этом этапе вы сформируете пакет ICMP Echo Request, более известный как «ping». Сетевые пакеты строятся по слоям в соответствии с моделью OSI. В Scapy вы можете объединять эти слои с помощью оператора /.
Послойная структура — одна из самых важных концепций для усвоения. Каждый слой добавляет свои поля и обязанности. Scapy напрямую отражает эту модель, поэтому ее синтаксис упрощает понимание структуры пакета.
Для ICMP-пинга требуется IP-слой (сетевой уровень) для указания адресов источника и назначения, а также ICMP-слой для определения типа сообщения.
Если packet_crafter.py все еще открыт в nano, продолжайте редактирование. В противном случае откройте его снова:
nano packet_crafter.py
Добавьте следующий код в конец вашего скрипта. Этот код создает IP-объект, нацеленный на публичный DNS-сервер Google (8.8.8.8), создает ICMP-объект и объединяет их. Метод show() выведет подробную структуру пакета.
## Create an IP layer targeting Google's DNS
ip_layer = IP(dst="8.8.8.8")
## Create an ICMP layer (Echo Request)
icmp_layer = ICMP()
## Stack the layers to form the final packet
icmp_packet = ip_layer / icmp_layer
print("\n--- ICMP Packet Structure ---")
icmp_packet.show()
Сохраните файл с помощью Ctrl+O и Enter. Вы можете остаться в nano и перейти к следующему шагу, если хотите дописать скрипт перед его запуском.
Запустите обновленный скрипт, чтобы увидеть структуру только что сформированного пакета.
sudo python3 packet_crafter.py
Вы увидите подробный вывод, показывающий значения по умолчанию, которые Scapy автоматически заполнил за вас, такие как версия протокола, TTL (Time To Live) и тип ICMP.
--- ICMP Packet Structure ---
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = icmp
chksum = None
src = 10.0.2.15
dst = 8.8.8.8
\options \
###[ ICMP ]###
type = echo-request
code = 0
chksum = None
id = 0x0
seq = 0x0
unused = ''
Создание пользовательского TCP SYN пакета
На этом этапе вы создадите TCP SYN пакет. Этот специфический тип пакета часто используется при сканировании сети (например, скрытое сканирование Nmap), чтобы проверить, открыт ли определенный порт на целевой машине, не устанавливая полноценное соединение.
Это отличный пример того, как небольшие изменения в заголовке приводят к совершенно разному сетевому поведению. Вы не меняете целевой хост или порт, только флаги и поля протокола, но именно эти детали определяют смысл пакета и то, как цель будет его интерпретировать.
Как и в случае с ICMP-пакетом, для TCP-пакета требуется базовый IP-слой. Поверх него вы добавите TCP-слой, где можно указать порт назначения и TCP-флаги. Флаг S означает SYN (Synchronize).
Если вы все еще находитесь в той же сессии nano, продолжайте редактировать packet_crafter.py. В противном случае откройте его снова:
nano packet_crafter.py
Добавьте следующий код в свой скрипт. Мы повторно используем ip_layer, созданный на предыдущем шаге, и добавим поверх него новый TCP-слой, нацеленный на порт 80 (HTTP).
## Create a TCP layer targeting port 80 with the SYN flag
tcp_layer = TCP(dport=80, flags="S")
## Stack the IP and TCP layers
tcp_packet = ip_layer / tcp_layer
print("\n--- TCP SYN Packet Structure ---")
tcp_packet.show()
Сохраните файл с помощью Ctrl+O и Enter. Выходите через Ctrl+X только тогда, когда захотите запустить скрипт из терминала, либо продолжайте редактирование для перехода к финальному шагу.
Запустите скрипт снова, чтобы проверить структуру вашего нового TCP SYN пакета.
sudo python3 packet_crafter.py
Теперь вывод будет включать детали TCP-слоя, показывая порт назначения http (порт 80) и флаги, установленные в S.
--- TCP SYN Packet Structure ---
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = tcp
chksum = None
src = 10.0.2.15
dst = 8.8.8.8
\options \
###[ TCP ]###
sport = ftp_data
dport = http
seq = 0
ack = 0
dataofs = None
reserved = 0
flags = S
window = 8192
chksum = None
urgptr = 0
options = []
Отправка и анализ сетевого ответа
На этом заключительном этапе вы отправите созданный ICMP-пакет по сети и перехватите ответ.
Отправка пакета завершает логическую цепочку: определение слоев, сборка пакета, передача и интерпретация ответа. Это тот же высокоуровневый цикл, который лежит в основе многих инструментов для тестирования сети.
Scapy предоставляет несколько функций для отправки пакетов. Функция sr1() особенно полезна, так как она отправляет пакет и ожидает получения первого же ответа. Буква «s» означает send (отправить), «r» — receive (получить), а «1» — один пакет.
Если файл остался открытым, продолжайте редактирование. В противном случае откройте packet_crafter.py снова:
nano packet_crafter.py
Добавьте следующий код для отправки icmp_packet и анализа ответа. Мы добавим параметр timeout, чтобы скрипт не завис бесконечно, если пакет будет отброшен или заблокирован.
print("\n--- Sending ICMP Packet ---")
## Send the packet and wait for 1 response, with a timeout of 2 seconds
## verbose=0 hides the default Scapy sending output for cleaner results
response = sr1(icmp_packet, timeout=2, verbose=0)
if response:
print(f"Response received from: {response[IP].src}")
print("\n--- Response Packet Structure ---")
response.show()
else:
print("No response received. The packet might have been dropped.")
Сохраните файл и закройте редактор.
Запустите скрипт, чтобы отправить пакет в интернет и дождаться ответа от DNS-сервера Google.
sudo python3 packet_crafter.py
Если сеть разрешает ICMP-запросы, вы увидите структуру ответного пакета. Обратите внимание, что тип ICMP в ответе — echo-reply.
--- Sending ICMP Packet ---
Response received from: 8.8.8.8
--- Response Packet Structure ---
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 28
id = 0
flags =
frag = 0
ttl = 114
proto = icmp
chksum = 0x67d8
src = 8.8.8.8
dst = 10.0.2.15
\options \
###[ ICMP ]###
type = echo-reply
code = 0
chksum = 0xffff
id = 0x0
seq = 0x0
unused = ''
###[ Padding ]###
load = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Резюме
Вы научились настраивать Python-скрипт с использованием Scapy, вручную формировать ICMP- и TCP-пакеты слой за слоем с помощью оператора /, а также отправлять эти пакеты по сети для анализа необработанных ответов. Эти фундаментальные знания критически важны для понимания работы сетевых протоколов, проведения оценки безопасности и разработки собственных инструментов сетевого анализа.



