Как можно защититься от атаки MITM ARP-spoofing? С одной стороны, если ваши маршрутизаторы не имеют защиты от данного вида атак, то практически никак. Потому, что даже обнаружение данного вида атаки довольно сложно с той точки зрения, что атакованная машина, а равно как и ее пользователь не будут даже подозревать о том, что что-то происходит. Но, обнаружить данную атаку вполне возможно. И в этом нам снова поможет Python и библиотека scapy.
Что понадобится?
Данный скрипт должен работать как в Windows, так и в Linux. Для установки необходимых библиотек для Linux, а в данном случае нужна библиотека scapy, воспользуемся командой:
Для Windows понадобиться выполнить немного больше установок. Для начала установим scapy, точно такой же командой как и в Linux. Затем, для отображения всплывающего уведомления нужно будет установить библиотеку win10toast. Для этого в командной строке выполните команду:
Теперь, чтобы была возможность работать с библиотекой scapy, нужно установить Npcap, который можно загрузить
Все остальное будет импортироваться по мере необходимости, непосредственно в функциях.
Создаем обработчик
Для начала создадим словарь, в который будем помещать нашу собственную ARP-таблицу. Это необходимо для того, чтобы выполнять сравнение данных, которые получены в пакете со значениями таблицы.
Давайте создадим функцию packet_sniff(packet), которая на входе будет принимать пакеты переданные сниффером, сравнивать с ARP-таблицей, которую мы создали в словаре ip_mac_dict.
Получаем ip и mac адреса из пакета.
Прогоняем по ключам словаря. И если полученное значение не совпадает, значит начинаем бить тревогу. Также получим ip адрес, откуда и пришел поддельный пакет.
А теперь бьем тревогу. Для начала проверяем, какая ОС у нас установлена. Так как вывод всплывающего сообщения в разных ОС отличается. Потому, если у нас Windows, импортируем библиотеку win10toast и создаем объект ToastNotifier. А затем выводим сообщение на экран. Параметры, которые нужно указать в выводе сообщения: Заголовок, Тело сообщения, и в данном случае duration, время в секундах, которое будет показываться данное сообщение. Тут надо больше поэкспериментировать. Но я пока остановился на 4 секундах. Так как если поставить меньше, то сообщения начинают сыпаться с интервалом секунды в две. Больше — есть вероятность пропустить сообщения. Но, тем не менее, этого достаточно для того, чтобы обнаружить атаку.
Так же и для Linux. Только тут с выводом сообщения попроще.
Перехватываем пакеты
А теперь нужно запустить перехватчик пакетов, который мы импортировали из библиотеки scapy, sniff. Сделаем мы это в функции main(). А также проведем еще несколько необходимых проверок.
Итак, при старте скрипта, для начала проверяем, является ли рабочая операционная система Linux. Если да, проверяем с какими правами запущен скрипт. Если это не суперпользователь, то выводим сообщение и прерываем работу скрипта. Если же суперпользователь на месте, то выводим сообщение о том, что анализ пакетов запущен и запускаем функцию sniff.
Полный код функции main() будет чуть ниже. А пока немного пояснений по параметрам, с которыми запущена функция. count в значении 0 указывает на то, что нужно анализировать пакеты непрерывно. Данный параметр указывает функции на то, сколько пакетов подлежат анализу. А значит, если мы укажем число отличное от 0, то работа данной функции в ключе обнаружения атак не будет иметь смысла. filter — здесь указывается тип пакета для перехвата. В данном случае нас интересуют именно arp-пакеты. store указывает на количество пакетов, которое нам нужно сохранять. Здесь же указан 0, что означает, что память на сохранение пакетов мы тратить не будем. Так как они будут просто анализироваться. И наконец параметр prn указывает на функцию, которая будет вызываться при получении пакета, для последующей его передачи и обработки в этой функции.
Вот и все. Теперь можно потестировать данную заготовку. Итак, запустим для начала Windows-машину. На ней установим все то, о чем писалось в начале, после чего запустим сниффер, а на атакующей машине спуфер. И вот, посыпались сообщения:
Теперь перенесем скрипт в Kali, для примера и запустим там. А также запустим спуфер на машину с ней. И вот также посыпались сообщения:
Как только атака прекращается, поток сообщений так же не выводиться на экран. Для чего я добавил сюда всплывающие сообщения? Дело в том, что окно с терминалом или командной строкой перед глазами у вас постоянно не будут. Да и проверять вы атаки тоже не будете. Потому, лучше вывести сообщение, чтобы пользователь точно заметил происходящее событие.
Спасибо за внимание. Надеюсь, что данная информация будет кому-нибудь полезна
Что понадобится?
Данный скрипт должен работать как в Windows, так и в Linux. Для установки необходимых библиотек для Linux, а в данном случае нужна библиотека scapy, воспользуемся командой:
pip install --pre scapy[basic]
Для Windows понадобиться выполнить немного больше установок. Для начала установим scapy, точно такой же командой как и в Linux. Затем, для отображения всплывающего уведомления нужно будет установить библиотеку win10toast. Для этого в командной строке выполните команду:
pip install win10toast
Теперь, чтобы была возможность работать с библиотекой scapy, нужно установить Npcap, который можно загрузить
Ссылка скрыта от гостей
. После того, как все будет установлено, можно импортировать нужные библиотеки и приступать к написанию кода. Вот что нужно будет импортировать в основном блоке импорта:
Python:
from os import system
from platform import system as psys
from scapy.all import sniff
Все остальное будет импортироваться по мере необходимости, непосредственно в функциях.
Создаем обработчик
Для начала создадим словарь, в который будем помещать нашу собственную ARP-таблицу. Это необходимо для того, чтобы выполнять сравнение данных, которые получены в пакете со значениями таблицы.
Давайте создадим функцию packet_sniff(packet), которая на входе будет принимать пакеты переданные сниффером, сравнивать с ARP-таблицей, которую мы создали в словаре ip_mac_dict.
Получаем ip и mac адреса из пакета.
Python:
ip_sourse = packet['ARP'].psrc
mac_source = packet['Ether'].src
Прогоняем по ключам словаря. И если полученное значение не совпадает, значит начинаем бить тревогу. Также получим ip адрес, откуда и пришел поддельный пакет.
Python:
if mac_source in ip_mac_dict.keys():
if ip_mac_dict[mac_source] != ip_sourse:
try:
ip_reference = ip_mac_dict[mac_source]
except:
ip_reference = "unknown"
А теперь бьем тревогу. Для начала проверяем, какая ОС у нас установлена. Так как вывод всплывающего сообщения в разных ОС отличается. Потому, если у нас Windows, импортируем библиотеку win10toast и создаем объект ToastNotifier. А затем выводим сообщение на экран. Параметры, которые нужно указать в выводе сообщения: Заголовок, Тело сообщения, и в данном случае duration, время в секундах, которое будет показываться данное сообщение. Тут надо больше поэкспериментировать. Но я пока остановился на 4 секундах. Так как если поставить меньше, то сообщения начинают сыпаться с интервалом секунды в две. Больше — есть вероятность пропустить сообщения. Но, тем не менее, этого достаточно для того, чтобы обнаружить атаку.
Python:
if psys() == "Windows":
print(f'\n[+] Обнаружена возможная ARP-атака\n- Возможно, что машина с адресом\n- {ip_reference} '
f'притворяется {ip_sourse}\n')
from win10toast import ToastNotifier
toast = ToastNotifier()
toast.show_toast('Обнаружена возможная ARP-атака', f'Машина {ip_reference} притворяется {ip_sourse}',
duration=4)
Так же и для Linux. Только тут с выводом сообщения попроще.
Python:
elif psys() == "Linux":
print(f'\n[+] Обнаружена возможная ARP-атака\n- Возможно, что машина с адресом\n- {ip_reference} '
f'притворяется {ip_sourse}\n')
command = f'''notify-send "Обнаружена возможная ARP-атака" "Машина {ip_reference} притворяется {ip_sourse}"'''
system(command)
Python:
def packet_sniff(packet):
ip_sourse = packet['ARP'].psrc
mac_source = packet['Ether'].src
if mac_source in ip_mac_dict.keys():
if ip_mac_dict[mac_source] != ip_sourse:
try:
ip_reference = ip_mac_dict[mac_source]
except:
ip_reference = "unknown"
if psys() == "Windows":
print(f'\n[+] Обнаружена возможная ARP-атака\n- Возможно, что машина с адресом\n- {ip_reference} '
f'притворяется {ip_sourse}\n')
from win10toast import ToastNotifier
toast = ToastNotifier()
toast.show_toast('Обнаружена возможная ARP-атака', f'Машина {ip_reference} притворяется {ip_sourse}',
duration=4)
elif psys() == "Linux":
print(f'\n[+] Обнаружена возможная ARP-атака\n- Возможно, что машина с адресом\n- {ip_reference} '
f'притворяется {ip_sourse}\n')
command = f'''notify-send "Обнаружена возможная ARP-атака" "Машина {ip_reference} притворяется {ip_sourse}"'''
system(command)
else:
ip_mac_dict[mac_source] = ip_sourse
Перехватываем пакеты
А теперь нужно запустить перехватчик пакетов, который мы импортировали из библиотеки scapy, sniff. Сделаем мы это в функции main(). А также проведем еще несколько необходимых проверок.
Итак, при старте скрипта, для начала проверяем, является ли рабочая операционная система Linux. Если да, проверяем с какими правами запущен скрипт. Если это не суперпользователь, то выводим сообщение и прерываем работу скрипта. Если же суперпользователь на месте, то выводим сообщение о том, что анализ пакетов запущен и запускаем функцию sniff.
sniff(count=0, filter="arp", store=0, prn=packet_sniff)
Полный код функции main() будет чуть ниже. А пока немного пояснений по параметрам, с которыми запущена функция. count в значении 0 указывает на то, что нужно анализировать пакеты непрерывно. Данный параметр указывает функции на то, сколько пакетов подлежат анализу. А значит, если мы укажем число отличное от 0, то работа данной функции в ключе обнаружения атак не будет иметь смысла. filter — здесь указывается тип пакета для перехвата. В данном случае нас интересуют именно arp-пакеты. store указывает на количество пакетов, которое нам нужно сохранять. Здесь же указан 0, что означает, что память на сохранение пакетов мы тратить не будем. Так как они будут просто анализироваться. И наконец параметр prn указывает на функцию, которая будет вызываться при получении пакета, для последующей его передачи и обработки в этой функции.
Python:
def main():
if psys() == "Linux":
from os import getuid
if not getuid() == 0:
print('\n[+] Запустите скрипт с правами суперпользователя!\n')
return
else:
print(f'[+] Анализ ARP-пакетов... \n')
sniff(count=0, filter="arp", store=0, prn=packet_sniff)
elif psys() == "Windows":
print(f'[+] Анализ ARP-пакетов... \n')
sniff(count=0, filter="arp", store=0, prn=packet_sniff)
Вот и все. Теперь можно потестировать данную заготовку. Итак, запустим для начала Windows-машину. На ней установим все то, о чем писалось в начале, после чего запустим сниффер, а на атакующей машине спуфер. И вот, посыпались сообщения:
Теперь перенесем скрипт в Kali, для примера и запустим там. А также запустим спуфер на машину с ней. И вот также посыпались сообщения:
Как только атака прекращается, поток сообщений так же не выводиться на экран. Для чего я добавил сюда всплывающие сообщения? Дело в том, что окно с терминалом или командной строкой перед глазами у вас постоянно не будут. Да и проверять вы атаки тоже не будете. Потому, лучше вывести сообщение, чтобы пользователь точно заметил происходящее событие.
Python:
from os import system
from platform import system as psys
from scapy.all import sniff
ip_mac_dict = {}
def packet_sniff(packet):
ip_sourse = packet['ARP'].psrc
mac_source = packet['Ether'].src
if mac_source in ip_mac_dict.keys():
if ip_mac_dict[mac_source] != ip_sourse:
try:
ip_reference = ip_mac_dict[mac_source]
except:
ip_reference = "unknown"
if psys() == "Windows":
print(f'\n[+] Обнаружена возможная ARP-атака\n- Возможно, что машина с адресом\n- {ip_reference} '
f'притворяется {ip_sourse}\n')
from win10toast import ToastNotifier
toast = ToastNotifier()
toast.show_toast('Обнаружена возможная ARP-атака', f'Машина {ip_reference} притворяется {ip_sourse}',
duration=4)
elif psys() == "Linux":
print(f'\n[+] Обнаружена возможная ARP-атака\n- Возможно, что машина с адресом\n- {ip_reference} '
f'притворяется {ip_sourse}\n')
command = f'''notify-send "Обнаружена возможная ARP-атака" "Машина {ip_reference} притворяется {ip_sourse}"'''
system(command)
else:
ip_mac_dict[mac_source] = ip_sourse
def main():
if psys() == "Linux":
from os import getuid
if not getuid() == 0:
print('\n[+] Запустите скрипт с правами суперпользователя!\n')
return
else:
print(f'[+] Анализ ARP-пакетов... \n')
sniff(count=0, filter="arp", store=0, prn=packet_sniff)
elif psys() == "Windows":
print(f'[+] Анализ ARP-пакетов... \n')
sniff(count=0, filter="arp", store=0, prn=packet_sniff)
if __name__ == "__main__":
main()
Спасибо за внимание. Надеюсь, что данная информация будет кому-нибудь полезна