1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/wizardforcel-kali-linux-network-scanning-cookbook-zh

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
ch2.md 100 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 27.11.2024 20:48 483ccac

Вторая глава: исследование и сканирование

Автор: Justin Hutchens

Переводчик: Летучий дракон

Протокол: CC BY-NC-SA 4.0

2.1 Использование Scapy для исследования второго уровня

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

Подготовка

Чтобы использовать Scapy для ARP-поиска, вам потребуется по крайней мере одна система, которая отвечает на ARP-запросы в вашей локальной сети. Приведённый пример использует комбинацию Linux и Windows систем. Для получения дополнительной информации о настройке системы в локальной экспериментальной среде см. «Установка Metasploitable2» и «Установка Windows Server» в первой главе.

Кроме того, для этого раздела требуется текстовый редактор (например, VIM или Nano) для ввода сценария в файловую систему. Дополнительную информацию о написании сценариев см. в «Использование текстового редактора (VIM и Nano)» в первой главе.

Порядок действий

Для понимания принципа работы ARP-сканирования мы используем Scapy для разработки пользовательских пакетов данных, которые позволяют нам идентифицировать хосты в нашей локальной сети с помощью ARP. Чтобы начать использовать Scapy в Kali Linux, введите команду scapy в терминале. Затем вы можете использовать функцию display(), чтобы просмотреть конфигурацию по умолчанию для любого объекта ARP в Scapy следующим образом:

root@KaliLinux:~# scapy Welcome to Scapy (2.2.0) 
>>> ARP().display() 
###[ ARP ]###
  hwtype= 0x1
  ptype= 0x800
  hwlen= 6
  plen= 4
  op= who-has
  hwsrc= 00:0c:29:fd:01:05
  psrc= 172.16.36.232
  hwdst= 00:00:00:00:00:00
  pdst= 0.0.0.0 

Обратите внимание, что IP-адрес и MAC-адрес источника всегда будут автоматически настроены на значения, связанные с системой, на которой работает Scapy. Вам не нужно изменять эти значения, если только вы не хотите подделать исходный адрес. Значение операции по умолчанию для ARP установлено на who-has, что указывает на то, что пакет предназначен для запроса ассоциации IP и MAC. В этом случае единственным значением, которое необходимо предоставить, является целевой IP-адрес. Для этого мы можем использовать функцию ARP для создания объекта и присвоения его переменной. Имя переменной не имеет значения (в приведённом примере используется переменная arp_request). Посмотрите на следующую команду:

>>> arp_request = ARP() 
>>> arp_request.pdst = "172.16.36.135" 
>>> arp_request.display() 
###[ ARP ]###
  hwtype= 0x1
  ptype= 0x800
  hwlen= 6
  plen= 4
  op= who-has
  hwsrc= 00:0c:29:65:fc:d2
  psrc= 172.16.36.132
  hwdst= 00:00:00:00:00:00
  pdst= 172.16.36.135

Обратите внимание, что функция display() может быть вызвана на вновь созданном объекте ARP, чтобы проверить, были ли обновлены значения конфигурации. Для этой практики используйте целевой IP-адрес, соответствующий активному компьютеру в экспериментальной сетевой среде. Затем функция sr1() может использоваться для отправки запроса и возврата первого ответа:

>>> sr1(arp_request) 
Begin emission: 
......................................*
Finished to send 1 packets.

Received 39 packets, got 1 answers, remaining 0 packets 
<ARP  hwtype=0x1 ptype=0x800 hwlen=6 plen=4 op=is-at hwsrc=00:0c:29:3d:84:32 psrc=172.16.36.135 hwdst=00:0c:29:65:fc:d2 pdst=172.16.36.132 |<Padding  load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\ x00\x00\x00\x00\x00\x00\x00\x00\x00' |>> 

Или же скрипт можно выполнить напрямую, вызвав эту функцию и передав любые специальные настройки в качестве параметров, чтобы выполнить ту же задачу, как показано в следующей команде. Это позволяет избежать путаницы с ненужными переменными и позволяет завершить всю задачу в одной строке кода:

>>> sr1(ARP(pdst="172.16.36.135")) 
Begin emission: .........................*
Finished to send 1 packets.

Received 26 packets, got 1 answers, remaining 0 packets 
<ARP  hwtype=0x1 ptype=0x800 hwlen=6 plen=4 op=is-at hwsrc=00:0c:29:3d:84:32 psrc=172.16.36.135 hwdst=00:0c:29:65:fc:d2 pdst=172.16.36.132 |<Padding  load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\ x00\x00\x00\x00\x00\x00\x00\x00\x00' |>> 

Обратите внимание, что в каждом из этих случаев ответ показывает, что MAC-адрес IP-адреса 172.16.36.135 равен 00:0C:29:3D:84:32. Если вы выполните ту же задачу, но целевой IP-адрес не соответствует активному хосту в экспериментальной сети, вы не получите никакого ответа, и эта функция будет продолжать анализировать входящий трафик на локальном интерфейсе бесконечно.

Вы можете остановить эту функцию, используя Ctrl + C. Или вы можете указать параметр timeout, чтобы избежать этой проблемы. Когда Scapy используется в сценарии Python, использование тайм-аута станет очень важным. Чтобы использовать тайм-аут, предоставьте дополнительный параметр функции отправки/получения, указав количество секунд ожидания входящего ответа:

>>> arp_request.pdst = "172.16.36.134" 
>>> sr1(arp_request, timeout=1) 
Begin emission: 
......................................................................... ............
Finished to send 1 packets. 
................................. ......................................................................... ........................................ 
Received 3285 packets, got 0 answers, remaining 1 packets 
>>>

Используя функцию тайм-аута, запрос, отправленный на хост без ответа, вернётся после указанного времени и покажет, что получено 0 ответов. Кроме того, ответ, полученный этой функцией, также можно присвоить переменной и обработать дальше, обратившись к этой переменной:

>>> response = sr1(arp_request, timeout=1) 
Begin emission: 
....................................*
Finished to send 1 packets.

Received 37 packets, got 1 answers, remaining 0 packets 
>>> response.display() 
###[ ARP ]###  
  hwtype= 0x1
  ptype= 0x800
  hwlen= 6
  plen= 4
  op= is-at
  hwsrc= 00:0c:29:3d:84:32
  psrc= 172.16.36.135
  hwdst= 00:0c:29:65:fc:d2
  pdst= 172.16.36.132 
###[ Padding ]###
     load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ x00\x00\x00'

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

#!/usr/bin/python

import logging 
import subprocess
``` Скрипт на Python начинает работу с определения местоположения интерпретатора Python, чтобы скрипт мог выполняться без передачи в интерпретатор. Затем скрипт импортирует все функции Scapy и устанавливает уровень логирования Scapy для исключения ненужного вывода из скрипта. Также импортируется библиотека подпроцессов для облегчения извлечения информации из системных вызовов.

Следующий блок кода представляет собой условное выражение, которое проверяет, были ли предоставлены необходимые параметры при выполнении скрипта. Если при выполнении не было предоставлено необходимых параметров, скрипт выведет описание использования инструмента, включая примеры и объяснение выполняемой задачи.

После этого блока кода есть отдельная строка кода, которая присваивает предоставленный параметр переменной interface. Следующий блок кода использует функцию check_output() библиотеки подпроцессов для выполнения системного вызова ifconfig, который также использует grep и cut для извлечения IP-адреса из указанного интерфейса. Затем этот вывод присваивается переменной ip. После этого используется функция split для извлечения префикса сети /24 из строки IP-адреса. Например, если переменная ip содержит строку 192.168.11.4, значение будет 192.168.11.

Последний блок кода является циклом for, который выполняет фактическое сканирование. Цикл for перебирает все значения от 0 до 254, и для каждой итерации это значение добавляется к сетевому префиксу. В приведённом примере каждый IP-адрес в диапазоне от 192.168.11.0 до 192.168.11.254 будет широковещательно передавать ARP-запрос. Затем для каждого активного хоста соответствующий IP-адрес будет выведен на экран, указывая, что хост активен в локальной сети.

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

root@KaliLinux:~# ./arp_disc.py Usage - ./arp_disc.py [interface] Example - ./arp_disc.py eth0 Example will perform an ARP scan of the local subnet to which eth0 is assigned


Если скрипт выполняется без предоставления каких-либо параметров, использование будет выведено на экран. Использование указывает, что этому скрипту требуется один параметр, определяющий, какой интерфейс использовать для сканирования. В следующем примере скрипт выполняется с использованием интерфейса eth0:

root@KaliLinux:~# ./arp_disc.py eth0 172.16.36.1 172.16.36.2 172.16.36.132 172.16.36.135 172.16.36.254


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

Скрипт также можно легко перенаправить на текстовый файл, который затем можно использовать для последующего анализа. Это можно сделать, используя угловые скобки для перенаправления вывода, за которыми следует имя текстового файла. Пример этого следующий:

root@KaliLinux:# ./arp_disc.py eth0 > output.txt root@KaliLinux:# ls output.txt output.txt root@KaliLinux:~# cat output.txt 172.16.36.1 172.16.36.2 172.16.36.132 172.16.36.135 172.16.36.254


После перенаправления вывода в текстовый файл можно использовать команду ls для проверки того, был ли файл записан в файловую систему, или использовать команду cat для просмотра содержимого файла. Этот скрипт также можно легко модифицировать, чтобы он выполнял ARP-запросы только для определённых IP-адресов, содержащихся в текстовом файле. Для этого сначала необходимо создать список IP-адресов, которые мы хотим просканировать. Это можно сделать с помощью Nano или VIM. Чтобы оценить функциональность скрипта, включите некоторые из ранее обнаруженных активных адресов, а также несколько других случайных адресов в том же диапазоне, где нет активных хостов. Чтобы создать входной файл в VIM или Nano, используйте одну из следующих команд:

root@KaliLinux:# vim iplist.txt root@KaliLinux:# nano iplist.txt


Создав входной файл, можно использовать команду cat, чтобы убедиться, что содержимое файла соответствует ожидаемому. Предполагая, что файл был создан правильно, вы должны увидеть IP-адреса, которые вы ввели в текстовом редакторе:

root@KaliLinux:~# cat iplist.txt 172.16.36.1 172.16.36.2 172.16.36.232 172.16.36.135 172.16.36.180 172.16.36.203 172.16.36.205 172.16.36.254


Чтобы создать скрипт, который принимает текстовый файл в качестве входных данных, мы можем изменить существующий скрипт или создать новый файл скрипта. Чтобы использовать этот список IP-адресов в нашем скрипте, нам нужно выполнить некоторую обработку файлов в Python. Пример рабочего скрипта следующий:
```py
#!/usr/bin/python

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *

if len(sys.argv) != 2:   
    print "Usage - ./arp_disc.py [filename]"   
    print "Example - ./arp_disc.py iplist.txt"   
    print "Example will perform an ARP scan of the IP addresses listed in iplist.txt"   
    sys.exit()

filename = str(sys.argv[1]) 
file = open(filename,'r')

for addr in file:   
    answer = sr1(ARP(pdst=addr.strip()),timeout=1,verbose=0)   
    if answer == None:      
        pass   
    else:      
        print addr.strip() 

Этот скрипт отличается от предыдущего только тем, что вместо создания переменной с именем interface создаётся переменная с именем file. Затем используется функция open() для создания объекта путём открытия файла iplist.txt в том же каталоге. Значение 'r' также передаётся функции для указания только на чтение доступа к файлу. Цикл for проходит по каждому IP-адресу в файле и выводит ответ на ARP-запрос на широковещательный адрес. Этот скрипт можно запустить таким же образом, как и раньше:

root@KaliLinux:~# ./arp_disc.py 
Usage - ./arp_disc.py [filename]
Example - ./arp_disc.py iplist.txt
Example will perform an ARP scan of the IP addresses listed in iplist.txt

Если скрипт запускается без предоставления каких-либо параметров, на экран выводится сообщение об использовании. Сообщение об использовании указывает, что скрипту нужен один параметр для определения входного списка IP-адресов. В следующем примере используется файл iplist.txt, расположенный в каталоге выполнения:

root@KaliLinux:~# ./arp_disc.py
``` **Можно легко перенаправить вывод скрипта в текстовый файл, который затем можно использовать для последующего анализа.**

Для этого можно использовать угловые скобки (>) для перенаправления вывода, за которыми следует имя текстового файла. Пример:

root@KaliLinux:# ./arping.sh eth0 > output.txt root@KaliLinux:# ls output.txt output.txt root@KaliLinux:~# cat output.txt 172.16.36.1 172.16.36.2 172.16.36.132 172.16.36.135 172.16.36.254


После того как вывод перенаправлен в выходной файл, вы можете использовать команду `ls` для проверки того, что файл был записан в файловую систему, или использовать команду `cat` для просмотра содержимого файла.

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

```sh
#!/bin/bash
if [ "$#" -ne 1 ]; then 
    echo "Usage - ./arping.sh [input file]" 
    echo "Example - ./arping.sh iplist.txt" 
    echo "Example will perform an ARP scan of all IP addresses defined in iplist.txt" 
    exit 
fi

file=$1

for addr in $(cat $file); do 
    arping -c 1 $addr | grep "bytes from" | cut -d " " -f 5 | cut -d "(" -f 2 | cut -d ")" -f 1 & 
done

Этот скрипт отличается от предыдущего тем, что не предоставляет интерфейс имени, а вместо этого при выполнении скрипта предоставляет имя файла входного списка. Этот параметр передаётся переменной файла. Затем цикл for используется для перебора каждого значения в этом файле и выполнения задачи ARPing.

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

root@KaliLinux:~# ./arping.sh 
Usage - ./arping.sh [input file] 
Example - ./arping.sh iplist.txt 
Example will perform an ARP scan of all IP addresses defined in iplist.txt 
root@KaliLinux:~# ./arping.sh iplist.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135 
172.16.36.254

При выполнении скрипта без предоставления каких-либо параметров будет возвращено использование скрипта, указывающее на необходимость предоставить входной файл в качестве параметра. После завершения этой операции скрипт будет выполнен, и из входного списка IP-адресов будет возвращён список текущих IP-адресов. Как и в случае с предыдущим обсуждением, вывод этого скрипта можно легко перенаправить в выходной файл с помощью угловых скобок. Пример:

root@KaliLinux:~# ./arping.sh iplist.txt > output.txt 
root@KaliLinux:~# ls output.txt 
output.txt 
root@KaliLinux:~# cat output.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135 
172.16.36.254 

Как только вывод перенаправляется в выходной файл, вы можете использовать ls, чтобы проверить, был ли файл записан в файловую систему, или cat, чтобы просмотреть содержимое файла. Перевод текста:

Отчет о сканировании Nmap для 172.16.36.132 Хост активен (задержка 0,00031 с). MAC-адрес: 00:0C:29:65:FC:D2 (VMware)

Nmap отчет о сканировании для 172.16.36.135 Хост активен (задержка 0,00014 с). MAC-адрес: 00:0C:29:3D:84:32 (VMware)

Отчёт о сканировании Nmap для 172.16.36.180 Хост активен.

Отчёт о сканировании Nmap для 172.16.36.254 Хост активен (задержка 0,00024 с). MAC-адрес: 00:50:56:EF:B9:9C (VMware).

Nmap завершён: просканировано 8 IP-адресов (6 хостов активны) за 0,41 секунды.


При использовании опции `-sn` Nmap сначала попытается использовать ARP-запрос второго уровня для определения местоположения хоста, и если хост не находится в локальной сети, он будет использовать только ICMP-запросы третьего уровня. Обратите внимание, что для выполнения Nmap ping-сканирования хостов в локальной сети (в диапазоне 172.16.36.0/24) возвращается MAC-адрес, поскольку MAC-адреса возвращаются из ARP-ответа хоста. Однако, если такое же сканирование Nmap выполняется для удалённых хостов в разных локальных сетях, ответ не будет включать MAC-адрес системы.

root@KaliLinux:~# nmap -sn 74.125.21.0-255
Запуск Nmap 6.25 (http://nmap.org) в 2013-12-11 05:42 EST
Отчёт о сканировании Nmap для 74.125.21.0
Хост активен (задержка 0.0024s).
Отчёт о сканировании Nmap для 74.125.21.1
Хост активен (задержка 0.00017s).
Отчёт о сканировании Nmap для 74.125.21.2
Хост активен (задержка 0.00028s).
Отчёт о сканировании Nmap для 74.125.21.3
Хост активен (задержка 0.00017s).

Когда сканирование выполняется для удалённого диапазона сети (общедоступный диапазон 74.125.21.0/24), можно увидеть, что используется обнаружение третьего уровня, так как MAC-адрес не возвращается. Это указывает на то, что Nmap будет пытаться использовать обнаружение второго уровня как можно быстрее, но при необходимости будет использовать маршрутизируемые ICMP-запросы для обнаружения удалённых хостов на третьем уровне. Если вы используете Wireshark для мониторинга трафика, а Nmap выполняет ping-сканирование хостов в локальной сети. На следующем скриншоте вы можете видеть, что Nmap использует ARP-запросы для идентификации хостов в диапазоне локальной сети:


### Принцип работы

Nmap уже хорошо функционален, и требуется очень мало или даже не нужно настраивать для запуска требуемого сканирования. Базовый принцип остаётся тем же. Nmap отправляет ARP-запросы на серию IP-адресов широковещательного адреса, и через маркировку ответов идентифицирует активные хосты. Однако, поскольку эта функция интегрирована в Nmap, её можно выполнить, предоставив соответствующие параметры.

## 2.4 Использование NetDiscover для исследования второго уровня

NetDiscover — это инструмент, используемый для активного и пассивного анализа ARP для выявления сетевых хостов. Он в основном используется в беспроводных интерфейсах; однако, он также имеет функции в других средах. В этом конкретном секрете мы обсудим, как использовать NetDiscover для активного и пассивного сканирования.

### Подготовка

Чтобы использовать NetDiscover для ARP-обнаружения, вам необходимо иметь по крайней мере одну систему, которая отвечает на ARP-запросы в вашей локальной сети. Приведённый пример использует комбинацию Linux и Windows систем. Для получения дополнительной информации о настройке систем в локальной экспериментальной среде см. главу 1 «Установка Metasploitable2» и «Установка Windows Server».

### Шаги операции

NetDiscover специально разработан для выполнения обнаружения второго уровня. NetDiscover можно использовать для сканирования серии IP-адресов, используя опцию `-r` с CIDR-нотацией сетевого диапазона в качестве параметра. Вывод создаст таблицу, в которой перечислены активные IP-адреса, соответствующие MAC-адреса, количество ответов, длина ответа и производитель MAC:

root@KaliLinux:~# netdiscover -r 172.16.36.0/24 В настоящее время сканирование: Завершено! | Просмотр экрана: Уникальные хосты Захвачено 5 пакетов ARP Req/Rep, от 5 хостов. Общий размер: 300


IP At MAC Address Count Len MAC Vendor

172.16.36.1 00:50:56:c0:00:08 01 060 VMWare, Inc. 172.16.36.2 00:50:56:ff:2a:8e 01 060 VMWare, Inc. 172.16.36.132 00:0c:29:65:fc:d2 01 060 VMware, Inc. 172.16.36.135 00:0c:29:3d:84:32 01 060 VMware, Inc. 172.16.36.254 00:50:56:ef:b9:9c 01 060 VMWare, Inc.


NetDiscover также можно использовать для сканирования IP-адресов из входного текстового файла. Вместо передачи CIDR-диапазона в качестве параметра, опция `-l` может использоваться в сочетании с именем или путём входного файла:

root@KaliLinux:~# netdiscover -l iplist.txt В настоящее время сканирование: 172.16.36.0/24 | Просмотр экрана: Уникальные хосты Захвачено 39 пакетов ARP Req/Rep, от 5 хостов. Общий размер: 2340


IP At MAC Address Count Len MAC Vendor ---------------------------------------------------------------------------- 172.16.36.1 00:50:56:c0:00:08 08 480 VMWare, Inc. 172.16.36.2 00:50:56:ff:2a:8e 08 480 VMWare, Inc. 172.16.36.132 00:0c:29:65:fc:d2 08 480 VMware, Inc. 172.16.36.135 00:0c:29:3d:84:32 08 480 VMware, Inc. 172.16.36.254 00:50:56:ef:b9:9c 07 420 VMWare, Inc.


Ещё одна уникальная функция, отличающая этот инструмент от других инструментов, — это возможность выполнять пассивное обнаружение. ARP-широковещательные запросы ко всем IP-адресам в подсети иногда могут вызывать срабатывание тревоги или ответа от устройств безопасности (например, системы обнаружения вторжений (IDS) или системы предотвращения вторжений (IPS)). Более скрытым методом является прослушивание ARP-трафика, поскольку система сканирования естественным образом взаимодействует с другими системами в сети, а затем записывает данные, собранные из ответов ARP. Этот метод пассивного сканирования можно выполнить с помощью опции `-p`:

root@KaliLinux:~# netdiscover -p В настоящее время сканирование: (пассивное) | Просмотр экрана: Уникальные хосты Захвачено 4 пакета ARP Req/Rep, от 2 хостов. Общий размер: 240


IP At MAC Address Count Len MAC Vendor

172.16.36.132 00:0c:29:65:fc:d2 02 120 VMware, Inc. 172.16.36.135 Настройка сканирования с помощью Metasploit Framework

После настройки конфигурации можно использовать команду run для запуска сканирования. Этот конкретный модуль будет печатать любые активные хосты, обнаруженные с использованием ARP. Он также будет определять поставщика сетевой карты (NIC), который определяется по первым трём байтам MAC-адреса обнаруженных хостов:

msf  auxiliary(arp_sweep) > run
[*] 172.16.36.1 appears to be up (VMware, Inc.).
[*] 172.16.36.2 appears to be up (VMware, Inc.).
[*] 172.16.36.132 appears to be up (VMware, Inc.).
[*] 172.16.36.135 appears to be up (VMware, Inc.).
[*] 172.16.36.254 appears to be up (VMware, Inc.).
[*] Scanned 256 of 256 hosts (100% complete)
[*] Auxiliary module execution completed

Принцип работы

Основной принцип работы Metasploit при выполнении ARP-сканирования заключается в широковещании серии ARP-запросов, записи и выводе ARP-ответов. Выходные данные вспомогательного модуля Metasploit предоставляют IP-адрес всех активных систем, а затем он также предоставляет название производителя MAC в скобках.

Использование ICMP для исследования третьего уровня

Исследование третьего уровня может быть одним из наиболее часто используемых инструментов среди сетевых администраторов и технических специалистов. Исследование третьего уровня использует известный инструмент ping для идентификации активных хостов. В этом руководстве демонстрируется, как использовать инструмент ping для выполнения исследования третьего уровня на удалённых хостах.

Для выполнения исследования третьего уровня с помощью инструмента ping не требуется экспериментальная среда, так как многие системы в Интернете будут отвечать на ICMP-запросы. Однако настоятельно рекомендуется выполнять любое сетевое сканирование только в вашей собственной экспериментальной среде, если вы полностью не знакомы с законами и правилами, применяемыми вашим местным органом управления. Если вы хотите выполнить это исследование в экспериментальной среде, вам потребуется как минимум одна система, которая отвечает на ICMP-запросы. В приведённом примере используется комбинация Linux и Windows систем. Для получения дополнительной информации о настройке систем в локальной экспериментальной среде см. «Установка Metasploitable2» и «Установка Windows Server» в первой главе. Кроме того, для этого раздела также потребуется текстовый редактор (например, VIM или Nano) для записи сценария в файловую систему. Для получения дополнительных сведений о написании сценариев см. «Использование текстового редактора (VIM и Nano)» в первой главе.

Большинство людей, работающих в IT-индустрии, хорошо знакомы с инструментом ping. Чтобы использовать ping для определения, активен ли хост, вам нужно просто передать параметр команде, определяющий IP-адрес хоста для тестирования:

root@KaliLinux:~# ping 172.16.36.135
PING 172.16.36.135 (172.16.36.135) 56(84) bytes of data.
64 bytes from 172.16.36.135: icmp_req=1 ttl=64 time=1.35 ms
64 bytes from 172.16.36.135: icmp_req=2 ttl=64 time=0.707 ms
64 bytes from 172.16.36.135: icmp_req=3 ttl=64 time=0.369 ms
^C
--- 172.16.36.135 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.369/0.809/1.353/0.409 ms

При отправке этой команды ICMP-запрос будет отправлен непосредственно на предоставленный IP-адрес. Для приёма ответа на этот ICMP-запрос необходимо выполнить несколько условий. Эти условия включают:

  • Тестируемый IP-адрес должен быть назначен системе.
  • Система должна быть активной и подключённой к сети.
  • Должен существовать доступный маршрут от сканирующей системы до целевого IP.
  • Система должна быть настроена на ответ на ICMP-трафик.
  • Между сканирующей системой и целевой системой, настроенной на отбрасывание ICMP-трафика, не должно быть межсетевых экранов или брандмауэров, основанных на хосте или сети.

Вы можете видеть, что существует множество переменных, которые могут повлиять на успешность ICMP-исследования. Именно по этой причине ICMP может быть немного ненадёжным, но, в отличие от ARP, он является маршрутизируемым протоколом, который можно использовать для обнаружения хостов за пределами локальной сети. Обратите внимание, что в приведённом выше примере в выходных данных команды ping отображается ^C. Это указывает на то, что был использован escape-последовательность (в данном случае Ctrl + C) для остановки процесса. По умолчанию интегрированный инструмент ping в операционной системе Linux будет бесконечно пинговать целевой хост. Однако опция -c может использоваться для указания количества ICMP-запросов, которые должны быть отправлены. После достижения тайм-аута или после получения ответов на каждый отправленный пакет данных процесс завершится нормально. Посмотрите на следующую команду:

root@KaliLinux:~# ping 172.16.36.135 -c 2
PING 172.16.36.135 (172.16.36.135) 56(84) bytes of data.
64 bytes from 172.16.36.135: icmp_req=1 ttl=64 time=0.611 ms
64 bytes from 172.16.36.135: icmp_req=2 ttl=64 time=0.395 ms
--- 172.16.36.135 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.395/0.503/0.611/0.108 ms

Подобно ARPing, его можно использовать в сценарии bash, выполняя ping нескольких IP-адресов параллельно, чтобы выполнить исследование третьего уровня в нескольких хостах одновременно. Для написания сценария нам нужно определить различные ответы, связанные с успешными и неудачными запросами ping. Для этого мы должны сначала пропинговать хост, который, как мы знаем, активен и отвечает на ICMP, а затем использовать запрос ping для отслеживания адреса без ответа. Следующая команда демонстрирует это:

root@KaliLinux:~# ping 74.125.137.147 -c 1
PING 74.125.137.147 (74.125.137.147) 56(84) bytes of data.
64 bytes from 74.125.137.147: icmp_seq=1 ttl=128 time=31.3 ms
--- 74.125.137.147 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev =
``` **Перевод текста на русский язык:**

Как только стеку присваивается уровень вложенности и передаётся переменной, функция display() может отобразить весь стек. Процесс добавления уровней в стек обычно называют «обёртыванием данных». Теперь, когда уровни были добавлены и запрос готов к отправке, его можно отправить с помощью функции sr1() в Scapy:

ping_reply = sr1(ping_request) ..Begin emission: ......... Finished to send 1 packets. ...* Received 15 packets, got 1 answers, remaining 0 packets ping_reply.display() ###[ IP ]### version= 4L ihl= 5L tos= 0x0 len= 28 id= 62577 flags= frag= 0L ttl= 64 proto= icmp chksum= 0xe513 src= 172.16.36.135 dst= 172.16.36.180 \options\ ###[ ICMP ]### type= echo-reply code= 0 chksum= 0xffff id= 0x0 seq= 0x0 ###[ Padding ]### load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ x00\x00\x00\x00'

В этом примере функция sr1() присваивает значение переменной ping_reply. Это выполняет функцию и передаёт результат этой переменной. После получения ответа вызывается функция display(), чтобы просмотреть содержимое ответа на переменной ping_reply. Обратите внимание, что этот пакет данных был отправлен с хоста, с которого мы отправили первоначальный запрос, а целевой адрес — это IP-адрес системы Kali. Кроме того, обратите внимание, что тип ICMP в ответе — эхо-ответ.

На основе этого примера использование Scapy для отправки и получения ICMP выглядит полезным, но если вы попытаетесь использовать те же шаги для не отвечающего целевого адреса, вы быстро заметите проблему:

>>> ip.dst = "172.16.36.136" 
>>> ping_request = (ip/ping) 
>>> ping_reply = sr1(ping_request) 
.Begin emission: 
......................................................................... ......................................................................... ........... 
Finished to send 1 packets 
.................................. .................................................................... 
                        *** {TRUNCATED} ***

Пример вывода усечён, но этот вывод должен продолжаться бесконечно, пока вы не используете Ctrl + C для принудительного завершения. Без указания значения тайм-аута функция sr1() будет продолжать прослушивание до тех пор, пока не получит ответ. Если хост не активен или если IP-адрес не связан ни с каким хостом, ответ не будет отправлен, и функция также не завершится. Чтобы эффективно использовать эту функцию в скрипте, следует определить значение тайм-аута:

ping_reply = sr1(ping_request, timeout=1) .Begin emission: ....................................................................... ....................................................................... Finished to send 1 packets. .................................... Received 3982 packets, got 0 answers, remaining 1 packets

Предоставляя значение тайм-аута в качестве второго параметра, передаваемого функции sr1(), процесс завершится через указанное количество секунд, если ответ не получен. В приведённом примере функция sr1() используется для отправки ICMP-запроса на адрес без ответа, поскольку ответ не был получен, процесс завершается через 1 секунду.

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

>>> answer = sr1(IP(dst="172.16.36.135")/ICMP(),timeout=1) 
.Begin emission:
...*
Finished to send 1 packets.
Received 5 packets, got 1 answers, remaining 0 packets 
>>> response.display() 
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 28
  id= 62578
  flags=
  frag= 0L
  ttl= 64
  proto= icmp
  chksum= 0xe512
  src= 172.16.36.135
  dst= 172.16.36.180
  \options\ 
###[ ICMP ]###
     type= echo-reply
     code= 0
     chksum= 0xffff
     id= 0x0
     seq= 0x0 
###[ Padding ]###
        load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ x00\x00\x00\x00' 

Здесь в приведённом примере все действия, которые ранее выполнялись четырьмя отдельными командами, фактически могут быть выполнены с помощью одного вызова функции. Обратите внимание: если в течение указанного времени ожидания ICMP-запрос не получает ответа от IP-адреса, вызов объекта вызовет исключение. Поскольку ответ не был получен, переменная, назначенная для ответа в этом примере, не инициализируется:

answer = sr1(IP(dst="83.166.169.231")/ICMP(),timeout=1) Begin emission: .......................................... Finished to send 1 packets. ......................................................................... .......................... Received 1180 packets, got 0 answers, remaining 1 packets answer.display() Traceback (most recent call last): File "", line 1, in AttributeError: 'NoneType' object has no attribute 'display'

Эти знания о различных ответах можно использовать для создания сценария, который последовательно выполняет ICMP-запросы на нескольких IP-адресах. Сценарий будет перебирать все возможные значения последнего восьмого байта целевого IP-адреса и отправлять ICMP-запрос для каждого значения. Когда каждая функция sr1() возвращает значение, будет оцениваться ответ, чтобы определить, был ли получен ответ:

#!/usr/bin/python

import logging 
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) 
from scapy.all import *

if len(sys.argv) != 2:   
    print "Usage - ./pinger.py [/24 network address]"   
    print "Example - ./pinger.py 172.16.36.0"   
    print "Example will perform an ICMP scan of the 172.16.36.0/24 range"   
    sys.exit()

address = str(sys.argv[1]) 
prefix = address.split('.')[0] + '.' + address.split('.')[1] + '.'
``` **Перевод текста на русский язык:**

**Скрипт**

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

Второй блок кода представляет собой условное тестирование, которое оценивает, были ли предоставлены необходимые параметры скрипту. Если при выполнении не было предоставлено необходимых параметров, скрипт выведет описание использования инструмента, примеры и объяснение выполняемой задачи.

После этого блока кода отдельная строка присваивает значение параметра `interface`. Следующий блок кода использует функцию `check_output()` подпроцесса для выполнения системного вызова `ifconfig`, который также использует `grep` и `cut` для извлечения IP-адреса из предоставленного локального интерфейса. Затем этот вывод присваивается переменной `ip`. Затем функция `split` используется для извлечения префикса сети `/ 24` из строки IP-адреса. Например, если переменная `ip` содержит строку `192.168.11.4`, значением будет `192.168.11`. Оно присваивается переменной `prefix`.

Последний блок кода является циклом `for`, который выполняет фактическое сканирование. Цикл `for` перебирает значения от 0 до 254, и для каждой итерации значение добавляется к сетевому префиксу. В приведённом примере для каждого IP-адреса в диапазоне `192.168.11.0` и `192.168.11.254` отправляется ICMP-запрос эхо-ответа. Затем для каждого активного хоста соответствующий IP-адрес выводится на экран, указывая, что хост активен в локальной сети.

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

root@KaliLinux:# ./pinger.py Usage - ./pinger.py [/24 network address] Example - ./pinger.py 172.16.36.0 Example will perform an ICMP scan of the 172.16.36.0/24 range root@KaliLinux:# ./pinger.py 172.16.36.0 172.16.36.2 172.16.36.1 172.16.36.132 172.16.36.135


Если скрипт выполняется без предоставления каких-либо параметров, метод использования выводится на экран. Вывод метода использования указывает, что этому скрипту требуется один параметр для определения сети `/ 24`, которую нужно сканировать. Приведённый пример использует сетевой адрес `172.16.36.0` для запуска скрипта. Скрипт затем выводит список активных IP-адресов в диапазоне `/ 24`. Этот вывод также может быть перенаправлен в текстовый файл с использованием угловых скобок, за которыми следует имя выходного файла. Пример:

root@KaliLinux:# ./pinger.py 172.16.36.0 > output.txt root@KaliLinux:# ls output.txt output.txt root@KaliLinux:~# cat output.txt 172.16.36.1 172.16.36.2 172.16.36.132 172.16.36.135


Затем можно использовать команду `ls` для проверки того, был ли выходной файл записан в файловую систему, или использовать команду `cat` для просмотра его содержимого. Можно также изменить этот скрипт, чтобы он принимал список IP-адресов в качестве входных данных. Для этого необходимо изменить цикл `for`, чтобы перебирать строки, считываемые из указанного текстового файла. Пример:

```py
#!/usr/bin/python

import logging 
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) 
from scapy.all import *

if len(sys.argv) != 2:   
    print "Usage - ./pinger.py [filename]"   
    print "Example - ./pinger.py iplist.txt"   
    print "Example will perform an ICMP ping scan of the IP addresses listed in iplist.txt"   
    sys.exit()

filename = str(sys.argv[1]) 
file = open(filename,'r')

for addr in file:   
    ans=sr1(IP(dst=addr.strip())/ICMP(),timeout=1,verbose=0)   
    if ans == None:      
        pass   
    else:      
        print addr.strip()

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

root@KaliLinux:~# ./pinger.py 
Usage - ./pinger.py [filename] 
Example - ./pinger.py iplist.txt 
Example will perform an 
ICMP ping scan of the IP addresses listed in iplist.txt 
root@KaliLinux:~# ./pinger.py iplist.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135

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

root@KaliLinux:~# ./pinger.py iplist.txt > output.txt 
root@KaliLinux:~# ls output.txt 
output.txt 
root@KaliLinux:~# cat output.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135

Этот скрипт также можно модифицировать для приёма списка IP-адресов и выполнения сканирования по ним. Анализ данных сканирования Nmap

Nmap используется для сканирования всего диапазона /24 сети. Для удобства просмотра вывод этой команды был усечён. Используя анализ трафика через интерфейс с помощью Wireshark, можно заметить, что эти адреса не сканируются в порядке следования. Это видно на скриншоте ниже. Это является дополнительным доказательством многопоточности Nmap и демонстрирует, как процесс запускается из очереди при завершении других процессов:

  • Рисунок 1. Скриншот анализа трафика через интерфейс.

Также Nmap может использоваться для сканирования IP-адресов, указанных в текстовом файле. Это можно сделать с помощью опции -iL, за которой следует имя файла или путь к файлу:

root@KaliLinux:~# cat iplist.txt
74.125.228.13 74.125.228.28
74.125.228.47 74.125.228.144
74.125.228.162 74.125.228.211
root@KaliLinux:~# nmap -iL iplist.txt -sn
Starting Nmap 6.25 (http://nmap.org) at 2013-12-16 23:14 EST
Nmap scan report for iad23s05-in-f13.1e100.net (74.125.228.13)
Host is up (0.00010s latency).
Nmap scan report for iad23s05-in-f28.1e100.net (74.125.228.28)
Host is up (0.0069s latency).
...
Nmap done: 6 IP addresses (6 hosts up) scanned in 0.04 seconds

В приведённом примере выполняется сканирование списка из шести IP-адресов в текущем каталоге. Затем этот список вводится в Nmap, и каждый указанный адрес сканируется для попытки обнаружения активных хостов.

Принцип работы

Nmap выполняет сканирование третьего уровня, отправляя ICMP эхо-запросы каждому IP-адресу в предоставленном диапазоне или текстовом файле. Поскольку Nmap является многопоточным инструментом, он отправляет несколько запросов параллельно, что приводит к быстрому возврату результатов пользователю.

Поскольку функция обнаружения Nmap адаптивна, она будет использовать только ICMP обнаружение, если ARP обнаружение не сможет эффективно определить локальные подсети хостов. В противном случае, если ни ARP, ни ICMP обнаружение не смогут эффективно идентифицировать активные хосты на заданном IP-адресе, будет использоваться технология обнаружения четвёртого уровня.

2.9 Использование fping для исследования третьего уровня

Инструмент fping похож на известный инструмент ping. Однако он также включает в себя множество дополнительных функций, которые позволяют использовать его в качестве инструмента функционального сканирования без дополнительной модификации. Этот секрет показывает, как использовать fping для выполнения сканирования третьего уровня на удалённых хостах.

Подготовка

Для выполнения сканирования третьего уровня с использованием fping не требуется экспериментальная среда, поскольку многие системы в Интернете будут отвечать на ICMP эхо-запросы. Тем не менее, рекомендуется выполнять любое сетевое сканирование только в вашей собственной экспериментальной среде, если вы полностью не знакомы с законами и правилами, применяемыми любым управляющим органом. Если вы хотите выполнить эту технику в экспериментальной среде, вам потребуется по крайней мере одна система, которая отвечает на ICMP запросы. В приведённом примере используются комбинации Linux и Windows систем. Для получения дополнительной информации о настройке систем в локальной экспериментальной среде см. «Установка Metasploitable2» и «Установка Windows Server» в первой главе.

Шаги операции

fping очень похож на ping с добавлением некоторых дополнительных функций. Он может отправлять ICMP эхо-запросы на отдельные цели, чтобы определить, активны ли они. Это достигается путём передачи IP-адреса в качестве параметра в утилиту fping:

root@KaliLinux:~# fping 172.16.36.135
172.16.36.135 is alive

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

root@KaliLinux:~# fping 172.16.36.136
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.136
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.136
...
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to
172.16.36.136 172.16.36.136 is unreachable

Можно использовать опцию -c count для изменения количества попыток подключения по умолчанию и предоставить ей целое число, определяющее количество попыток:

root@KaliLinux:~# fping 172.16.36.135 -c 1
172.16.36.135 : [0], 84 bytes, 0.67 ms (0.67 avg, 0% loss)

172.16.36.135 : xmt/rcv/%loss = 1/1/0%, min/avg/max = 0.67/0.67/0.67
root@KaliLinux:~# fping 172.16.36.136 -c 1

172.16.36.136 : xmt/rcv/%loss = 1/0/100%

При выполнении таким образом вывод становится более скрытым, но его можно легко понять при тщательном анализе. Вывод для любого хоста включает IP-адрес, количество попыток (xmt), количество полученных ответов (rcv) и процент потерь (%loss). В приведённом примере fping обнаруживает, что первый адрес находится в сети. Это подтверждается количеством полученных байтов и временем ожидания ответа. Вы также можете легко определить, существует ли активный хост, связанный с предоставленным IP-адресом, проверив процент потерь. Если процент потерь равен 100, то ответ не был получен.

В отличие от ping, который чаще всего используется в качестве инструмента устранения неполадок, fping имеет встроенные функции для сканирования нескольких хостов. Перевод текста с английского языка на русский:

В диапазоне 24каждый адрес выполняет операциюhping3, и результаты каждой задачи выводятся в файл handle.txt`.

После завершения, grep используется для извлечения строк, связанных с ответами активных хостов, из файла handle, а затем IP-адреса извлекаются из этих строк. Затем сгенерированные IP-адреса передаются в файл output.txt, а временный файл handle.txt удаляется из каталога. Этот скрипт можно выполнить, используя точку с запятой и косую черту, за которыми следует имя исполняемого скрипта:

root@KaliLinux:~# ./ping_sweep.sh 
Usage - ./ping_sweep.sh [/24 network address] 
Example - ./ping_sweep.sh 172.16.36.0 
Пример выполнит ICMP-пинг-запрос сети 172.16.36.0/24 и выведет результат в файл output.txt
root@KaliLinux:~# ./ping_sweep.sh 172.16.36.0
--- 172.16.36.1 статистика hping --
1 пакет передан, 1 пакет получен, потеря пакетов 0%
минимальное, среднее и максимальное время кругового обхода равно 0,4/0,4/0,4 мс
--- 172.16.36.2 статистика hping --
1 пакет передан, 1 пакет получен, потеря пакетов 0%
минимальное, среднее и максимальное время кругового обхода равно 0,5/0,5/0,5 мс
--- 172.16.36.3 статистика hping --
1 пакет передан, 0 пакетов получено, потеря пакетов 100%
минимальное, среднее и максимальное время кругового обхода равно 0,0/0,0/0,0 мс
                        *** {УСЕЧЁННЫЙ} ***

По завершении скрипт должен вернуть файл output.txt в каталог выполнения. Это можно проверить с помощью команды ls, и содержимое этого файла можно просмотреть с помощью команды cat:

root@KaliLinux:~# ls output.txt 
output.txt 
root@KaliLinux:~# cat output.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135 
172.16.36.253

При выполнении скрипта вы всё ещё будете видеть большое количество вывода во время начальной итерации задачи. К счастью, список хостов, который вы обнаружили, не исчезнет в этом выводе, поскольку он будет записываться в ваш выходной файл при каждом запуске.

### Принцип работы

Нам нужно внести некоторые изменения, чтобы использовать `hping3` для обнаружения хостов в нескольких диапазонах адресов. Предоставленный секрет использует bash-скрипт для последовательного выполнения запросов ICMP-ответа. Это возможно, потому что успешные и неудачные запросы могут генерировать уникальные ответы. Передавая функцию в цикл и передавая уникальный ответ в `grep`, мы можем эффективно разработать скрипт, который последовательно выполняет обнаружение хостов для нескольких систем, а затем выводит список активных хостов.

## 2.11 Использование Scapy для исследования четвёртого уровня

Существует множество способов выполнения обнаружения целей на четвёртом уровне. Можно использовать пользовательские протоколы дейтаграмм (UDP) или протоколы управления передачей (TCP) для сканирования. Scapy можно использовать для создания настраиваемых запросов с использованием этих двух транспортных протоколов и объединить их с Python-скриптами для разработки практичного инструмента обнаружения. В этом секрете показано, как использовать Scapy для выполнения обнаружения на основе TCP и UDP на четвёртом уровне.

### Подготовка

Для выполнения обнаружения на четвёртом уровне с помощью Scapy не требуется экспериментальная среда, так как многие системы в Интернете будут отвечать на запросы TCP и UDP. Однако настоятельно рекомендуется выполнять любое сканирование сети только в вашей собственной экспериментальной среде, если вы полностью не знакомы с законами и правилами, установленными любым органом управления, под юрисдикцией которого вы находитесь. Если вы хотите выполнить эту технику в экспериментальной среде, вам потребуется по крайней мере одна система, которая отвечает на запросы TCP/UDP. В приведённом примере используются комбинации Linux и Windows. Для получения дополнительной информации о настройке систем в локальной экспериментальной среде см. секреты «Установка Metasploitable2» и «Установка Windows Server» в первой главе. Кроме того, для этого раздела также требуется текстовый редактор (например, VIM или Nano) для записи скрипта в файловую систему. Дополнительную информацию о написании скриптов см. в секретах «Использование текстового редактора (VIM и Nano)» в первой главе.

### Порядок действий

Чтобы подтвердить получение RST-ответов от активных хостов, мы можем использовать Scapy для отправки TCP ACK-пакетов известным активным хостам. В приведённом примере ACK-пакет будет отправлен на целевой порт TCP 80. Обычно этот порт используется для запуска HTTP-веб-сервисов. Демонстрация использует сервер Apache, работающий на этом порту на целевом хосте. Для этого нам нужно построить запрос на каждом уровне. Первый уровень, который нужно построить, — это уровень IP. Посмотрите на команду ниже:

root@KaliLinux:~# scapy Welcome to Scapy (2.2.0)

i = IP() i.display() ###[ IP ]### version= 4 ihl= None tos= 0x0 len= None id= 1 flags= frag= 0 ttl= 64 proto= ip chksum= None src= 127.0.0.1 dst= 127.0.0.1 \options\ i.dst="172.16.36.135" i.display() ###[ IP ]### version= 4 ihl= None tos= 0x0 len= None id= 1 flags= frag= 0 ttl= 64 proto= ip chksum= None src= 172.16.36.180 dst= 172.16.36.135 \options\

Здесь мы инициализируем переменную `i` объектом `IP`, а затем перенастраиваем стандартную конфигурацию, устанавливая целевой адрес равным IP-адресу целевого сервера. Обратите внимание, что исходный IP-адрес автоматически обновляется, когда предоставляется любой IP-адрес, кроме обратного адреса. Нам нужно построить следующий уровень — наш TCP-уровень. Это видно в следующей команде:

t = TCP() t.display() ###[ TCP ]### sport= ftp_data dport= http seq= 0 ack= 0 dataofs= None reserved= 0 flags= S window= 8192 chksum= None urgptr= 0 options= {} t.flags='A' t.display() ###[ TCP ]### sport= ftp_data dport= http seq= 0 ack= 0 dataofs= None reserved= 0 flags= A window= 8192 chksum= None urgptr= 0 options= {}

Здесь мы инициализировали переменную `t` объектом `TCP`. Обратите внимание, что конфигурация объекта уже установила целевой порт равным HTTP или порту 80. Здесь нам просто нужно изменить флаги TCP с `S` (SYN) на `A` (ACK). Теперь мы можем построить стек, используя косую черту для разделения каждого уровня, как показано в следующей команде:

request = (i/t) request.display() ###[ IP ]### version= 4 ihl= None tos= 0x0 len= None id= 1 flags= frag= 0 ttl= 64 proto= tcp chksum= None src= 172.16.36.180 dst= 172.16.36.135 \options\ ###[ TCP ]### sport= ftp_data dport= http seq= 0 ack= 0 dataofs= None reserved= 0 flags= A window= 8192 chksum= None urgptr= 0 options= {}

Здесь мы присваиваем весь стек запросов переменной request. Теперь мы можем использовать функции send и recieve для передачи запроса по линии связи, а затем оценить ответ, чтобы определить состояние целевого адреса:

>>> response = sr1(request) 
Begin emission: 
.......Finished to send 1 packets. 
....* 
Received 12 packets, got 1 answers, remaining 0 packets 
>>> response.display() 
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 40
  id= 0
  flags= DF
  frag= 0L
  ttl= 64
  proto= tcp
  chksum= 0x9974 ###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 20
  id= 0
  flags= DF
  frag= 0L
  ttl= 64
  proto= tcp
  chksum= 0x9974
  src= 172.16.36.135
  dst= 172.16.36.180
###[ TCP ]###
     sport= http
     dport= ftp_data
     seq= 0
     ack= 0
     dataofs= 5L
     reserved= 0L
     flags= R
     window= 0
     chksum= 0xe21
     urgptr= 0
     options= {} 
###[ Padding ]###
        load= '\x00\x00\x00\x00\x00\x00'

В этом запросе описывается использование программы Scapy для отправки пакетов данных с определёнными параметрами на удалённый компьютер и анализа полученных ответов. Основной язык текста запроса — английский.

Запрос содержит информацию о параметрах отправляемых пакетов, включая номера портов отправителя и получателя, флаги TCP-соединения и другие параметры. Также в запросе приводится анализ полученных ответов и делается вывод о том, что при отправке пакетов с определёнными параметрами на закрытый порт удалённого компьютера возвращается пакет с флагом RST, который указывает на то, что соединение было закрыто.

Также в запросе содержится пример кода на языке Python, который использует программу Scapy для сканирования диапазона IP-адресов и поиска активных компьютеров. В результате выполнения этого кода формируется список активных IP-адресов. ```
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags=
  frag= 0
  ttl= 64
  proto= udp
  chksum= None
  src= 172.16.36.180
  dst= 172.16.36.135
  \options\ 
###[ UDP ]###
     sport= domain
     dport= domain
     len= None
     chksum= None

Примечание: объект UDP по умолчанию использует порт источника и порт назначения, которые являются номерами портов службы доменных имён (DNS). Это широко используемый сервис, который можно использовать для преобразования доменного имени в IP-адрес. Запрос отправляется, поскольку он помогает определить, связан ли IP-адрес с активным хостом. Пример отправки запроса можно увидеть в следующей команде:

>>> reply = sr1(request,timeout=1,verbose=1) 
Begin emission: 
Finished to send 1 packets.
Received 7 packets, got 0 answers, remaining 1 packets

Несмотря на то, что хост, связанный с целевым IP-адресом, активен, ответа не получено. Ирония заключается в том, что отсутствие ответа фактически связано с тем, что служба DNS используется на целевой системе. Это связано с тем, что активные службы обычно настроены так, чтобы отвечать только на запросы, содержащие определённый контент. Можно было бы подумать, что иногда можно попытаться эффективно идентифицировать хост путём зондирования неиспользуемого порта UDP, предполагая, что трафик ICMP не блокируется брандмауэром. Теперь мы пытаемся отправить тот же запрос на другой неиспользуемый порт UDP:

>>> u.dport = 123 
>>> request = (i/u)
>>> reply = sr1(request,timeout=1,verbose=1) 
Begin emission: Finished to send 1 packets.
Received 5 packets, got 1 answers, remaining 0 packets 
>>> reply.display() 
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0xc0
  len= 56
  id= 62614
  flags=
  frag= 0L
  ttl= 64
  proto= icmp
  chksum= 0xe412
  src= 172.16.36.135
  dst= 172.16.36.180
  \options\ 
###[ ICMP ]###
     type= dest-unreach
     code= port-unreachable
     chksum= 0x9e72
     unused= 0 
###[ IP in ICMP ]###
        version= 4L
        ihl= 5L
        tos= 0x0
        len= 28
        id= 1
        flags=
        frag= 0L
        ttl= 64
        proto= udp
        chksum= 0xd974
        src= 172.16.36.180
        dst= 172.16.36.135
        \options\
###[ UDP in ICMP ]###
           sport= domain       
           dport= ntp        
           len= 8          
           chksum= 0x5dd2 

После изменения цели запроса на порт 123 и повторной отправки, теперь мы получаем ответ, указывающий на недоступность порта. Если вы проверите исходный IP-адрес этого ответа, вы увидите, что он был отправлен с хоста, отправившего первоначальный запрос. Этот ответ затем указывает на то, что хост в месте назначения находится в активном состоянии. К сожалению, ответы не всегда возвращаются в таких случаях. Эффективность этой техники во многом зависит от системы и её конфигурации, которую вы исследуете. Именно поэтому обнаружение UDP обычно сложнее, чем обнаружение TCP. Оно никогда не бывает таким простым, как отправка одного пакета данных с установленным флагом TCP. В случае, когда служба действительно существует, часто требуется специфическое для службы зондирование. К счастью, существуют различные довольно сложные инструменты сканирования UDP, которые можно использовать с различными запросами UDP и специфическими для служб зондами, чтобы определить, связан ли активный хост с заданным IP-адресом.

Принцип работы

Приведённый здесь пример демонстрирует использование методов обнаружения UDP и TCP. Мы можем использовать Scapy для создания пользовательских запросов, использующих эти протоколы для идентификации активных хостов. В случае TCP мы создаём пользовательский пакет ACK и отправляем его на любой порт на каждом целевом компьютере. Если получен ответ RST, система считается активной. Или пустой запрос UDP отправляется на произвольный порт, пытаясь запросить ответ ICMP о недоступности порта. Ответ можно использовать в качестве идентификатора активного хоста. Затем каждый из этих методов можно использовать в скрипте Python для выполнения обнаружения на нескольких хостах или диапазонах адресов.

2.12 Использование Nmap для исследования четвёртого уровня

Помимо многих других функций сканирования, встроенных в инструмент Nmap, есть опция для выполнения обнаружения четвёртого уровня. Эта конкретная хитрость показывает, как использовать Nmap для выполнения обнаружения TCP и UDP на четвёртом уровне.

Подготовка

Для выполнения обнаружения четвёртого уровня с помощью инструмента Nmap не требуется экспериментальная среда, потому что многие системы в Интернете будут отвечать на запросы TCP и UDP. Однако настоятельно рекомендуется выполнять любое сканирование сети только в вашей собственной экспериментальной среде, если вы полностью не знакомы с законами и правилами, установленными любым органом управления, которому вы подчиняетесь. Если вы хотите выполнить эту технику в экспериментальной среде, вам потребуется хотя бы одна система, которая отвечает на запросы TCP/UDP. Приведённый пример использует комбинацию Linux и Windows систем. Для получения дополнительной информации о настройке систем в локальной экспериментальной среде см. раздел «Установка Metasploitable2» и «Установка Windows Server» в главе 1. Кроме того, этот раздел также требует использования текстового редактора (например, VIM или Nano) для записи сценария в файловую систему. Дополнительную информацию о написании сценариев см. в разделе «Использование текстового редактора (VIM и Nano)» в главе 1.

Шаги операции

В Nmap есть несколько опций для обнаружения хостов, на которых запущены службы TCP и UDP. Обнаружение UDP в Nmap настроено так, что оно использует необходимый уникальный груз для запуска служб, которые не отвечают. Чтобы использовать UDP для выполнения сканирования обнаружения, используйте опцию -PU и порт для тестирования:

root@KaliLinux:~# nmap 172.16.36.135 -PU53 -sn

Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-11 20:11 EST 
Nmap scan report for 172.16.36.135 Host is up (0.00042s latency). 
MAC Address: 00:0C:29:3D:84:32 (VMware) 
Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds 
Этот вид сканирования UDP также можно изменить, чтобы выполнить сканирование последовательного диапазона, используя обозначение тире. В приведённом примере мы просканируем весь диапазон адресов 172.16.36.0/24:
root@KaliLinux:~# nmap 172.16.36.0-255 -PU53 -sn

Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 06:33 EST 
Nmap scan report for 172.16.36.1 
Host is up (0.00020s latency). 
MAC Address: 00:50:56:C0:00:08 (VMware) 
Nmap scan report for 172.16.36.2 
Host is up (0.00018s latency). 
MAC Address: 00:50:56:FF:2A:8E (VMware) 
Nmap scan report for 172.16.36.132 
Host is up (0.00037s latency). 
MAC Address: 00:0C:29:65:FC:D2 (VMware) 
Nmap scan report for 172.16.36.135 
Host is up (0.00041s latency).
MAC Address: 00:0C:29:3D:84:32 (VMware) 
Nmap scan report for 172.16.36.180 
Host is up. 
Nmap scan report for 172.16.36.254 
Host is up (0.00015s latency). 
MAC Address: 00:50:56:EB:E1:8A (VMware)
``` **Nmap: сканирование IP-адресов и обнаружение активных хостов**

Nmap используется для сканирования IP-адресов с целью обнаружения активных хостов. В примере выполняется сканирование списка IP-адресов, определённого в файле iplist.txt, с использованием команды nmap -iL iplist.txt -sn -PU53.

Пример показывает результаты сканирования нескольких хостов в сети 172.16.36.0/24. Nmap обнаруживает шесть хостов, но это не обязательно означает, что все они были обнаружены через UDP-запросы.

Также в примере показано, как использовать Nmap для выполнения TCP ACK ping-запросов. Это позволяет обнаружить активные хосты, даже если они не отвечают на стандартные запросы.

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

**Использование hping3 для исследования четвёртого уровня модели OSI**

hping3 — это инструмент для тестирования сетей и анализа трафика. Он может использоваться для отправки различных типов пакетов и получения ответов от целевых систем.

В примере показано, как использовать hping3 для обнаружения активных хостов через TCP и UDP. Для этого используется команда hping3 --udp с указанием целевого IP-адреса.

Если целевой хост отвечает на UDP-пакеты, hping3 будет получать ICMP Port Unreachable сообщения. Если хост активен, он может ответить на запрос, и hping3 получит другой тип ответа. **ICMP Port Unreachable from ip=172.16.36.135**

HPING 172.166.36.136 (eth1 172.16.36.136): udp mode set, 28 headers + 0 data bytes

root@KaliLinux:~# grep Unreachable handle.txt | cut -d " " -f 5
ip=172.16.36.132
ip=172.16.36.135

**Пример скрипта для сканирования нескольких хостов и лёгкого определения результатов**

В данном примере кода используется серия команд cut для извлечения IP-адресов из вывода. В результате определяется метод сканирования множества хостов с последующим лёгким определением результатов. Этот метод рекомендуется интегрировать в один скрипт.

```sh
#!/bin/bash
if [ "$#" -ne 1 ]; then 
    echo "Usage - ./udp_sweep.sh [/24 network address]" 
    echo "Example - ./udp_sweep.sh 172.16.36.0" 
    echo "Example will perform a UDP ping sweep of the 172.16.36.0/24 network and output to an output.txt file" 
    exit 
fi

prefix=$(echo $1 | cut -d '.' -f 1-3)

for addr in $(seq 1 254); do 
    hping3 $prefix.$addr --udp -c 1 >> handle.txt; 
done

grep Unreachable handle.txt | cut -d " " -f 5 | cut -d "=" -f 2 >> output.txt 
rm handle.txt

Первая строка определяет местоположение интерпретатора bash. Затем выполняется проверка на наличие ожидаемого параметра. Если параметр не предоставлен, выводится информация об использовании скрипта и происходит выход.

Из предоставленного сетевого адреса извлекается сетевой префикс. Например, если предоставленный адрес — 192.168.11.0, то переменная prefix будет равна 192.168.11. Затем для каждого адреса в диапазоне /24 выполняется команда hping3, а результаты каждой задачи помещаются в файл handle.txt.

При запуске скрипта без параметров выводится сообщение об ошибке и пример использования. При запуске с параметром 172.16.36.0 скрипт выполняет сканирование и выводит информацию о недоступности портов для каждого хоста. Список хостов сохраняется в файле output.txt.

Также в тексте упоминается возможность использования команды hping3 для TCP-сканирования. Для этого необходимо передать IP-адрес хоста в команду hping3.

Для TCP-обнаружения можно создать аналогичный скрипт, определив фразу, которая присутствует в выводе активных хостов, но отсутствует в выводе неактивных хостов. В этом случае также используется команда grep для фильтрации вывода и сохранения списка активных хостов в файле. Способ выполнения этого скрипта похож на способ работы UDP-скрипта обнаружения. Единственное отличие заключается в командах, выполняемых в цикле последовательности, процессе grep и извлечения IP-адресов. После выполнения этот скрипт создаст файл output.txt, который будет содержать список IP-адресов хостов, обнаруженных с помощью метода обнаружения TCP.

root@KaliLinux:~# ./tcp_sweep.sh 
Usage - ./tcp_sweep.sh [/24 network address] 
Пример - ./tcp_sweep.sh 172.16.36.0 
В примере выполняется сканирование сети 172.16.36.0/24 методом TCP ping и вывод результатов в файл output.txt 
root@KaliLinux:~# ./tcp_sweep.sh 172.16.36.0
--- Статистика hping для 172.16.36.1 --
Передано 1 пакетов, получено 1 пакетов, потеря пакетов 0% 
минимальное время кругового обхода / среднее / максимальное = 0,4 / 0,4 / 0,4 мс
--- Статистика hping для 172.16.36.2 --
Передано 1 пакетов, получено 1 пакетов, потеря пакетов 0% 
минимальное время кругового обхода / среднее / максимальное = 0,6 / 0,6 / 0,6 мс
--- Статистика hping для 172.16.36.3 --
Передано 1 пакетов, не получено ни одного пакета, потеря пакетов 100% 
минимальное время кругового обхода / среднее / максимальное = 0,0 / 0,0 / 0,0 мс
                    *** {УСЕЧЁННЫЙ} *** 

Вы можете использовать команду ls, чтобы убедиться, что выходной файл был записан в каталог выполнения, и использовать команду cat, чтобы прочитать его содержимое. Это можно увидеть в следующем примере:

root@KaliLinux:~# ls output.txt 
output.txt 
root@KaliLinux:~# cat output.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135 
172.16.36.253

Принцип работы

В приведённом примере hping3 использует ICMP-ответ «хост недоступен» для идентификации активных хостов с запросами UDP и использует сканирование с пустым флагом для идентификации активных хостов с запросами TCP. Для обнаружения UDP серия пустых запросов UDP отправляется на произвольный целевой порт, пытаясь запросить ответ. Для обнаружения TCP серия запросов TCP отправляется на целевой порт 0 без активации флага. В приведённом примере запрашивается активация ответа ACK + RST. Каждая из этих задач передаётся в цикл в bash для выполнения сканирования на нескольких хостах или в серии адресов.

1
https://api.gitlife.ru/oschina-mirror/wizardforcel-kali-linux-network-scanning-cookbook-zh.git
git@api.gitlife.ru:oschina-mirror/wizardforcel-kali-linux-network-scanning-cookbook-zh.git
oschina-mirror
wizardforcel-kali-linux-network-scanning-cookbook-zh
wizardforcel-kali-linux-network-scanning-cookbook-zh
master