unknown il y a 1 mois
Parent
commit
33dc732b49
2 fichiers modifiés avec 64 ajouts et 5 suppressions
  1. 18 4
      books/python_black/scanner.py
  2. 46 1
      books/python_black/sniffer_ip_header_decode.py

+ 18 - 4
books/python_black/scanner.py

@@ -10,7 +10,8 @@ import time
 # сканируем подсеть
 SUBNET = '192.168.31.0/24'
 # волшебная строка, которую мы будем искать в ICMP-ответах
-MESSAGE = 'PYTHONRULES!'
+# MESSAGE = 'PYTHONRULES!'
+MESSAGE = 'asdfaskdflajdskfjalsjdf'
 
 class IP:
     def __init__(self, buff):
@@ -55,14 +56,26 @@ class ICMP:
 def udp_sender():
     with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sender:
         for i in range(10):
-            # sender.sendto(bytes(MESSAGE, 'utf8'), ('192.168.31.100', 65212))
-            sender.sendto(bytes(MESSAGE, 'utf8'), ('8.8.8.8', 65212))
+            sender.sendto(bytes(MESSAGE, 'utf8'), ('77.88.44.242', 5555))
+            print('send icmp')
+            # sender.sendto(bytes(MESSAGE, 'utf8'), ('8.8.8.8', 65212))
             time.sleep(0.3)
         # for ip in ipaddress.ip_network(SUBNET).hosts():
             # print(bytes(MESSAGE, 'utf8'), (str(ip), 65212))
             # sender.sendto(bytes(MESSAGE, 'utf8'), (str(ip), 65212))
 
 
+def icmp_sender():
+    icmp_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
+    icmp_packet = struct.pack('!BBHHH', 8, 0, 0, 0, 1) + b'pingdata'
+
+    crc = 0
+    for i in range(0, len(icmp_packet), 2):
+        crc += (icmp_packet[i] << 8) + icmp_packet[i + 1]
+
+        
+
+
 class Scanner:
     def __init__(self, host):
         self.host = host
@@ -89,8 +102,9 @@ class Scanner:
                 # создаем IP-заголовок из первых 20 байт
                 ip_header = IP(raw_buffer[0:20])
                 # нас интересует ICMP
-                print(raw_buffer)
+                # print(raw_buffer)
                 print(ip_header.src_address, ip_header.dst_address)
+                # print(ip_header.src_address)
                 if ip_header.protocol == 'ICMP':
                     print('ICMP')
                     offset = ip_header.ihl * 4

+ 46 - 1
books/python_black/sniffer_ip_header_decode.py

@@ -4,11 +4,55 @@ import socket
 import struct
 import sys
 
+"""
+Структура IP пакета:
+Заголовок состоит из 5 слов (каждое слово 32 бита)
+
+Слово 1 (слева направо):
+
+    Version (4 бита) - версия IP протоколо, в IPv4 = 4
+    Header size (IHL) (4 бита) - размер заголовка в словах
+    Type of service (8 бит) состоит из полей:
+        DSCP (6 бит) разделяет трафик на классы обслуживания
+        ECN (2 бита) указатель перегрузки
+    Total lenght (16 бит) - полный размер IP пакета (заголовок + данные)
+
+Слово 2
+
+    ID (16 бит) - используется для сборки фрагментированных пакетов
+    Flags (3 бита) - используюся для фрагментации пакетов
+    Fragment Offset (13 бит) - поле смещения фрагмента
+
+Слово 3
+    TTL - time to live (8 бит) - время жизни пакета (число транзитных узлов 
+        которое может пройти пакет перед тем как будет уничтожен). Если пришел
+        пакет с ttl=1, то такой пакет не будет передан следующему узлу. Но если
+        пакет пришел получателю, то такой пакет будет обработан.
+    Protocol (8 бит) - код протокола, помещенного в IP пакет
+    Header Checksum (16 бит) - контрольная сумма заголовка (меняется от 
+        узла к узлу, т.к. меняется TTL). Пакеты с неверной CRC отбрасываются.
+
+Слово 4
+    Source address (32 бита) - IP-адрес отпровителя
+
+Слово 5
+    Distination address (32 бита) - IP-адрес назначения
+
+Поле данных.
+
+Таким образом, максимальная длика IP макета 65535, а максимальная длина поля
+данных 65515. 20 байт уходит на заголовок.
+
+
+"""
+
+# class IP:
+
 
 class IP:
     def __init__(self, buff):
         header = struct.unpack('<BBHHHBBH4s4s', buff)
-        self.ver = header[0] >> 4
+        self.ver = header[0] >> 4   # Вер
         self.ihl = header[0] & 0xF
 
         self.tos = header[1]
@@ -34,6 +78,7 @@ class IP:
             self.protocol = str(self.protocol_num)
 
 
+
 def sniff(host):
     # создаем сырой сокет и привязываем к общедоступному интерфейсу
     if os.name == 'nt':