Изменение пакетов на лету с помощью scapy в качестве MITM

#python #linux #iptables #scapy #man-in-the-middle

#python #linux #iptables #scapy #человек посередине

Вопрос:

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

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

Я думаю, что правильное направление для достижения этой iptables цели — использовать, но не уверен, какие именно аргументы подойдут для этой работы. У меня уже есть следующий простой скрипт:

 hotspotd start #a script that runs dnsmasq as both a DNS and DHCP server, configures and starts a hotspot
iptables -P FORWARD ACCEPT
iptables --append FORWARD --in-interface wlan0 -j ACCEPT
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE 
#wlan0 is the interface on which the hotspot is.
#eth0 is the interface that is connected to the internet
  

Теперь это отлично работает для пассивного MITM — я могу видеть все, что отправляет и получает клиент. Но теперь я хочу активизировать его и перенаправлять каждое сообщение, которое он отправляет и получает через меня.

Моя конечная цель — достичь уровня, на котором я мог бы выполнить следующий сценарий:

 from scapy.all import *
from scapy_http.http import *

def callback(pkt):
   #Process the packet here, see source and destination addresses, ports, data
   send(pkt)

sniff(filter='port 666', prn=callback) #Assuming all relevant packets are redirected to port 666
  

Как мне выполнить перенаправление каждого пакета, который клиент отправляет и собирается получить?

Ответ №1:

Вы можете использовать NFQUEUE, который имеет привязки к python.

NFQUEUE — это очередь пользовательского пространства, которая является допустимой целью iptables. Вы можете перенаправить некоторый трафик на NFQUQUE:

iptables -I INPUT -d 192.168.0.0/24 -j NFQUEUE --queue-num 1

Затем получите доступ к пакетам из вашего кода:

 from netfilterqueue import NetfilterQueue

def print_and_accept(pkt):
    print(pkt)
    pkt.accept()

nfqueue = NetfilterQueue()
nfqueue.bind(1, print_and_accept)
try:
    nfqueue.run()
except KeyboardInterrupt:
    print('')

nfqueue.unbind()
  

Обратите внимание на pkt.accept() вызов. Это возвращает вердикт nfqueue, сообщая ему, что он должен принять пакет, то есть разрешить ему продолжить свой обычный маршрут в ядре. Чтобы изменить пакет, вместо accept его редактирования вам нужно будет скопировать его, вернуть drop вердикт и, наконец, повторно отправить его с включенными изменениями.

Комментарии:

1. Кажется, работает. Но как мне распознать, какие пакеты с устройства, а какие с моей машины?

2. Для этого вы можете использовать либо iptables, либо свое приложение. 1. Используя таблицы IP, вы можете фильтровать пакеты по их источнику и отправлять только соответствующие пакеты в nfqueue (или отправлять их в два отдельных NFQUEUES в зависимости от источника). 2. Поскольку ваше приложение получает весь пакет из NFQUEUE, вы можете просто проверить IP-адрес каждого получаемого пакета.

3. но разве это не определено на более позднем этапе? Я имею в виду, что пакеты, полученные с какого-то локального адреса, я полагаю, в порядке и их легко определить, но как насчет пакетов, предназначенных для этого IP-адреса устройства? Они поступают на мой внешний IP, сработает ли такой подвиг?

4. @JonSnow я не понимаю. Если вы знаете свой IP-адрес, вы можете посмотреть IP-адрес назначения каждого пакета и сравнить с вашим. Если сетевой интерфейс находится за NAT, как IP-адрес интерфейса, так и IP-адрес в пакете будут частными.

5. Моя машина функционирует как точка доступа для моей атаки MITM и выполняет маршрутизацию от интерфейсов ( wlan0 к eth0 и наоборот). Когда пакет отсутствует, я могу обнюхать и посмотреть, какой пакет, например, из . 10.0.0.2 Но когда я получаю ответ, я получаю IP-адрес назначения в качестве своего внешнего IP-адреса, не так ли?