Máy quét mạng Python

Quét cổng có thể được định nghĩa là một kỹ thuật giám sát, được sử dụng để xác định vị trí các cổng mở có sẵn trên một máy chủ cụ thể. Quản trị viên mạng, người kiểm tra thâm nhập hoặc tin tặc có thể sử dụng kỹ thuật này. Chúng tôi có thể cấu hình máy quét cổng theo yêu cầu của chúng tôi để có được thông tin tối đa từ hệ thống đích.

Bây giờ, hãy xem xét thông tin chúng ta có thể nhận được sau khi chạy quét cổng -

  • Thông tin về các cổng đang mở.

  • Thông tin về các dịch vụ đang chạy trên mỗi cổng.

  • Thông tin về hệ điều hành và địa chỉ MAC của máy chủ đích.

Việc quét cổng cũng giống như kẻ trộm muốn vào nhà bằng cách kiểm tra mọi cửa ra vào và cửa sổ để xem cửa nào đang mở. Như đã thảo luận trước đó, bộ giao thức TCP / IP, sử dụng cho giao tiếp qua internet, được tạo thành từ hai giao thức là TCP và UDP. Cả hai giao thức đều có từ 0 đến 65535 cổng. Vì chúng tôi luôn khuyến khích đóng các cổng không cần thiết trong hệ thống của chúng tôi, do đó về cơ bản, có hơn 65000 cửa (cổng) cần khóa. 65535 cổng này có thể được chia thành ba phạm vi sau:

  • Hệ thống hoặc các cổng nổi tiếng: từ 0 đến 1023

  • Cổng người dùng hoặc đã đăng ký: từ 1024 đến 49151

  • Cổng động hoặc cổng riêng: tất cả> 49151

Máy quét cổng sử dụng Socket

Trong chương trước, chúng ta đã thảo luận về socket là gì. Bây giờ, chúng ta sẽ xây dựng một máy quét cổng đơn giản sử dụng socket. Sau đây là một tập lệnh Python cho máy quét cổng sử dụng socket:

from socket import *
import time
startTime = time.time()

if __name__ == '__main__':
   target = input('Enter the host to be scanned: ')
   t_IP = gethostbyname(target)
   print ('Starting scan on host: ', t_IP)
   
   for i in range(50, 500):
      s = socket(AF_INET, SOCK_STREAM)
      
      conn = s.connect_ex((t_IP, i))
      if(conn == 0) :
         print ('Port %d: OPEN' % (i,))
      s.close()
print('Time taken:', time.time() - startTime)

Khi chúng tôi chạy đoạn mã trên, nó sẽ nhắc tên máy chủ, bạn có thể cung cấp bất kỳ tên máy chủ nào như tên của bất kỳ trang web nào nhưng hãy cẩn thận vì việc quét cổng có thể được coi là, hoặc được hiểu là một tội ác. Chúng tôi không bao giờ nên thực hiện quét cổng đối với bất kỳ trang web hoặc địa chỉ IP nào mà không có sự cho phép rõ ràng bằng văn bản từ chủ sở hữu máy chủ hoặc máy tính mà bạn đang nhắm mục tiêu. Quét cổng cũng giống như việc đi đến nhà của ai đó và kiểm tra cửa ra vào và cửa sổ của họ. Đó là lý do tại sao bạn nên sử dụng máy quét cổng trên localhost hoặc trang web của riêng bạn (nếu có).

Đầu ra

Tập lệnh trên tạo ra kết quả sau:

Enter the host to be scanned: localhost
Starting scan on host: 127.0.0.1
Port 135: OPEN
Port 445: OPEN
Time taken: 452.3990001678467

Kết quả cho thấy trong phạm vi từ 50 đến 500 (như được cung cấp trong tập lệnh), máy quét cổng này tìm thấy hai cổng - cổng 135 và 445, đang mở. Chúng tôi có thể thay đổi phạm vi này và có thể kiểm tra các cổng khác.

Máy quét cổng sử dụng ICMP (Máy chủ trực tiếp trong mạng)

ICMP không phải là quét cổng nhưng nó được sử dụng để ping máy chủ từ xa để kiểm tra xem máy chủ có hoạt động hay không. Quá trình quét này rất hữu ích khi chúng ta phải kiểm tra một số máy chủ trực tiếp trong mạng. Nó liên quan đến việc gửi Yêu cầu ICMP ECHO tới máy chủ lưu trữ và nếu máy chủ đó hoạt động, nó sẽ trả về ICMP ECHO Reply.

Quá trình gửi yêu cầu ICMP ở trên còn được gọi là quét ping, được cung cấp bởi lệnh ping của hệ điều hành.

Khái niệm về Ping Sweep

Trên thực tế, theo một nghĩa nào đó, quét ping còn được gọi là quét ping. Sự khác biệt duy nhất là quét ping là quy trình để tìm nhiều hơn một máy tính khả dụng trong phạm vi mạng cụ thể. Ví dụ, giả sử chúng ta muốn kiểm tra danh sách đầy đủ các địa chỉ IP bằng cách sử dụng tính năng quét ping, tức là lệnh ping của hệ điều hành sẽ rất tốn thời gian để quét từng địa chỉ IP. Đó là lý do tại sao chúng ta cần sử dụng tập lệnh quét ping. Sau đây là một tập lệnh Python để tìm máy chủ trực tiếp bằng cách sử dụng quét ping:

import os
import platform

from datetime import datetime
net = input("Enter the Network Address: ")
net1= net.split('.')
a = '.'

net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
oper = platform.system()

if (oper == "Windows"):
   ping1 = "ping -n 1 "
elif (oper == "Linux"):
   ping1 = "ping -c 1 "
else :
   ping1 = "ping -c 1 "
t1 = datetime.now()
print ("Scanning in Progress:")

for ip in range(st1,en1):
   addr = net2 + str(ip)
   comm = ping1 + addr
   response = os.popen(comm)
   
   for line in response.readlines():
      if(line.count("TTL")):
         break
      if (line.count("TTL")):
         print (addr, "--> Live")
         
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: ",total)

Kịch bản trên hoạt động trong ba phần. Đầu tiên, nó chọn dải địa chỉ IP để quét ping bằng cách chia nó thành nhiều phần. Tiếp theo là sử dụng chức năng, chức năng này sẽ chọn lệnh để quét ping theo hệ điều hành và cuối cùng là đưa ra phản hồi về máy chủ và thời gian cần thiết để hoàn tất quá trình quét.

Đầu ra

Tập lệnh trên tạo ra kết quả sau:

Enter the Network Address: 127.0.0.1
Enter the Starting Number: 1
Enter the Last Number: 100

Scanning in Progress:
Scanning completed in: 0:00:02.711155

Đầu ra ở trên không hiển thị cổng trực tiếp vì tường lửa đang bật và cài đặt gửi đến ICMP cũng bị tắt. Sau khi thay đổi các cài đặt này, chúng ta có thể nhận được danh sách các cổng trực tiếp trong phạm vi từ 1 đến 100 được cung cấp trong đầu ra.

Máy quét cổng sử dụng quét TCP

Để thiết lập kết nối TCP, máy chủ lưu trữ phải thực hiện bắt tay ba bước. Làm theo các bước sau để thực hiện hành động -

Step 1 − Packet with SYN flag set

Trong bước này, hệ thống đang cố gắng bắt đầu kết nối sẽ bắt đầu với một gói có cờ SYN.

Step 2 − Packet with SYN-ACK flag set

Trong bước này, hệ thống đích trả về một gói tin với các bộ cờ SYN và ACK.

Step 3 − Packet with ACK flag set

Cuối cùng, hệ thống khởi tạo sẽ trả về một gói tin cho hệ thống đích ban đầu với cờ ACK được đặt.

Tuy nhiên, câu hỏi đặt ra ở đây là nếu chúng ta có thể thực hiện quét cổng bằng cách sử dụng phương pháp trả lời và yêu cầu tiếng vang ICMP (máy quét quét ping) thì tại sao chúng ta cần quét TCP? Lý do chính đằng sau đó là giả sử nếu chúng ta tắt tính năng trả lời ICMP ECHO hoặc sử dụng tường lửa cho các gói ICMP thì máy quét quét ping sẽ không hoạt động và chúng ta cần quét TCP.

import socket
from datetime import datetime
net = input("Enter the IP address: ")
net1 = net.split('.')
a = '.'

net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
t1 = datetime.now()

def scan(addr):
   s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   socket.setdefaulttimeout(1)
   result = s.connect_ex((addr,135))
   if result == 0:
      return 1
   else :
      return 0

def run1():
   for ip in range(st1,en1):
      addr = net2 + str(ip)
      if (scan(addr)):
         print (addr , "is live")
         
run1()
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: " , total)

Kịch bản trên hoạt động trong ba phần. Nó chọn dải địa chỉ IP để quét quét ping bằng cách chia nó thành nhiều phần. Tiếp theo là sử dụng một chức năng để quét địa chỉ, chức năng này tiếp tục sử dụng ổ cắm. Sau đó, nó đưa ra phản hồi về máy chủ và thời gian cần thiết để hoàn tất quá trình quét. Kết quả = s. Câu lệnh connect_ex ((addr, 135)) trả về một chỉ báo lỗi. Chỉ báo lỗi là 0 nếu thao tác thành công, ngược lại, nó là giá trị của biến errno. Ở đây, chúng tôi đã sử dụng cổng 135; máy quét này hoạt động cho hệ thống Windows. Một cổng khác sẽ hoạt động ở đây là 445 (Microsoft-DSActive Directory) và thường mở.

Đầu ra

Tập lệnh trên tạo ra kết quả sau:

Enter the IP address: 127.0.0.1
Enter the Starting Number: 1
Enter the Last Number: 10

127.0.0.1 is live
127.0.0.2 is live
127.0.0.3 is live
127.0.0.4 is live
127.0.0.5 is live
127.0.0.6 is live
127.0.0.7 is live
127.0.0.8 is live
127.0.0.9 is live
127.0.0.10 is live
Scanning completed in: 0:00:00.230025

Máy quét cổng ren để tăng hiệu quả

Như chúng ta đã thấy trong các trường hợp trên, quá trình quét cổng có thể rất chậm. Ví dụ: bạn có thể thấy thời gian quét các cổng từ 50 đến 500, trong khi sử dụng máy quét cổng socket là 452.3990001678467. Để cải thiện tốc độ, chúng ta có thể sử dụng phân luồng. Sau đây là một ví dụ về máy quét cổng sử dụng phân luồng:

import socket
import time
import threading

from queue import Queue
socket.setdefaulttimeout(0.25)
print_lock = threading.Lock()

target = input('Enter the host to be scanned: ')
t_IP = socket.gethostbyname(target)
print ('Starting scan on host: ', t_IP)

def portscan(port):
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   try:
      con = s.connect((t_IP, port))
      with print_lock:
         print(port, 'is open')
      con.close()
   except:
      pass

def threader():
   while True:
      worker = q.get()
      portscan(worker)
      q.task_done()
      
q = Queue()
   startTime = time.time()
   
for x in range(100):
   t = threading.Thread(target = threader)
   t.daemon = True
   t.start()
   
for worker in range(1, 500):
   q.put(worker)
   
q.join()
print('Time taken:', time.time() - startTime)

Trong tập lệnh trên, chúng ta cần nhập mô-đun luồng, mô-đun này được tạo sẵn trong gói Python. Chúng tôi đang sử dụng khái niệm khóa luồng,thread_lock = threading.Lock()để tránh sửa đổi nhiều lần cùng một lúc. Về cơ bản, threading.Lock () sẽ cho phép một luồng truy cập vào biến tại một thời điểm. Do đó, không có sửa đổi kép nào xảy ra.

Sau đó, chúng ta xác định một hàm threader () sẽ lấy công việc (cổng) từ vòng lặp worker for. Sau đó, phương thức portcan () được gọi để kết nối với cổng và in kết quả. Số cổng được chuyển dưới dạng tham số. Khi nhiệm vụ được hoàn thành, phương thức q.task_done () được gọi.

Bây giờ sau khi chạy tập lệnh trên, chúng ta có thể thấy sự khác biệt về tốc độ quét từ 50 đến 500 cổng. Nó chỉ mất 1.3589999675750732 giây, ít hơn rất nhiều so với 452.3990001678467, thời gian được thực hiện bởi máy quét cổng socket để quét cùng một số cổng của localhost.

Đầu ra

Tập lệnh trên tạo ra kết quả sau:

Enter the host to be scanned: localhost
Starting scan on host: 127.0.0.1
135 is open
445 is open
Time taken: 1.3589999675750732