首頁  >  文章  >  後端開發  >  使用 Python 的基本連接埠掃描器

使用 Python 的基本連接埠掃描器

Linda Hamilton
Linda Hamilton原創
2024-10-23 13:31:30157瀏覽

Basic Port Scanner using Python

原始碼請點這裡

這是基本的連接埠掃描工具,允許使用者掃描主機以查找開放連接埠以及在該連接埠上運行的服務...

首先讓我們看一下程式碼,然後將其分解為幾個部分來分析......

import socket
from datetime import datetime
import sys
import os 

def usage():
    """Prints the usage information for this script."""
    usage_info = """
    Tool Name: SimplePortScanner 

    Developed by : Bharath Kumar

    Usage:
        python3 port_scanner.py [options]

    Options:
        -h, --help           Show this help message and exit.
        -t, --target <ip>    Specify the target hostname or IP address (required).
        -p, --port <port>    Specify a port (or) range of ports to scan (e.g. -p 80 (or) -p 1-1024).

    Description:
        This script performs a port scan on a specified hostname or IP address
        for a specific port or a range of ports, checking which ports are open. 

    Examples:
        python3 port_scanner.py -t example.com (or) 192.0.0.1 
        python3 port_scanner.py -t example.com (or) 192.168.1.1 -p 80
        python3 port_scanner.py -t example.com (or) 192.168.1.1 --ports 1-1024
    """
    print(usage_info)

start_time = datetime.now()

def scan_port(ip, port):

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(1)
    try:
        result = s.connect_ex((ip, port))
        service = socket.getservbyport(int(port))
    except:
        service = "None"
    if result == 0:
        print(" Port: {}\t State: Open\t Service: {}".format(port, service))

    else:
        pass

    s.close()


def host(target):
    try:
        ip = socket.gethostbyname(target)
        print('_'*51)
        print("[#] Resolved {} to {}".format(target,ip))
        return ip
    except:
        print('_'*51)
        print("[#] Error: Unable to resolve hostname {}".format(target))
        sys.exit(1)

def check_host_up(ip):

    ping = os.system("ping {} -c 1 > /dev/null".format(ip))

    if ping == 0:
       print("[#] {} host is up and running".format(ip))
       return True
    else:
        print("[#] {} host is down".format(ip))
        print("Exiting...")
        exit()
        return False





if __name__ == "__main__":

    target_ip = None
    start_port = 1
    end_port = 65535

    try:
        for i, arg in enumerate(sys.argv):
            if arg in ("-t", "--target"):
                target_ip = sys.argv[i + 1]
            elif arg in ("-p", "--ports"):
                port_range = sys.argv[i + 1]
                if "-" in port_range:
                    start_port, end_port = map(int, port_range.split('-'))
                else:
                    start_port = end_port = int(port_range)

        if target_ip is None:
            print("[#] Error: Target hostname or IP address is required.")
            usage()
            sys.exit(1)

        if start_port is None or end_port is None:
            print("[#] Error: Port range is required.")
            usage()
            sys.exit(1)

        target_ip = host(target_ip)

        if not check_host_up(target_ip):
            sys.exit(1)

        print(f"[#] Scanning {target_ip} from port {start_port} to {end_port}...")
        print("[#] Scanning started at: {}".format(start_time))
        print('_'*51)

        for port in range(start_port, end_port + 1):
            scan_port(target_ip, port)

    except (IndexError, ValueError):
        print("[#] Error: Invalid arguments provided.")
        usage()
        sys.exit(1)

start_time = start_time.now() - start_time
print('_'*51)
print("Scanning is completed in ",start_time)

導入套接字:兩個節點(伺服器、客戶端)相互通訊的方式。

from datetime import datetime: 用於掃描所使用的計算時間。

Import sys: 是對系統特定參數(argv)的存取。

導入os:用來執行ping指令。

def_usage(): 列印此腳本的使用資訊。

start_time = datetime.now(): 用於取得目前時間和日期,以計算掃描所花費的時間。

def scan_port(ip, port):

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(1)
    try:
        result = s.connect_ex((ip, port))
        service = socket.getservbyport(int(port))
    except:
        service = "None"
    if result == 0:
        print(" Port: {}\t State: Open\t Service: {}".format(port, service))

    else:
        pass

    s.close()


此程式碼區塊定義函數 scan_port(ip, port),用於檢查給定 ip 位址上的特定連接埠是否使用套接字開啟。

套接字建立: socket.socket(socket.AF_INET, socket.SOCK_STREAM) 使用 TCP 為 IPv4 建立新套接字。

逾時: s.settimeout(1) 將套接字時間設定為 1 秒,如果在該時間內連線未成功,它將停止嘗試。

連線測試:s.connect_ex((ip, port))它嘗試連接特定的ip和連接埠。如果成功,結果將為0;否則,它將是不同的值。

服務偵測: socket.getservbyport(int(port))嘗試偵測指定連接埠上執行的服務。例如連接埠 80 的 HTTP。

錯誤處理:如果發生錯誤(例如,連接埠上沒有服務), except 區塊將服務設定為「None」。

輸出:如果連接埠開啟(結果== 0),則列印連接埠號碼、狀態(「開啟」)和服務名稱。

連線關閉: s.close() 關閉套接字以釋放資源。

def host(target):
    try:
        ip = socket.gethostbyname(target)
        print('_'*51)
        print("[#] Resolved {} to {}".format(target,ip))
        return ip
    except:
        print('_'*51)
        print("[#] Error: Unable to resolve hostname {}".format(target))
        sys.exit(1)

此程式碼區塊定義了函數 host(target),它使用 socket.gethostname() 將給定的目標(主機名稱)解析為其對應的 IP 位址

def check_host_up(ip):

    ping = os.system("ping {} -c 1 > /dev/null".format(ip))

    if ping == 0:
       print("[#] {} host is up and running".format(ip))
       return True
    else:
        print("[#] {} host is down".format(ip))
        print("Exiting...")
        exit()
        return False

此函數 check_host_up(ip) 使用 os.system() ping 方法檢查給定目標 ip 上的特定連接埠是開啟還是關閉。

if __name__ == "__main__":

    target_ip = None
    start_port = 1
    end_port = 65535

    try:
        for i, arg in enumerate(sys.argv):
            if arg in ("-t", "--target"):
                target_ip = sys.argv[i + 1]
            elif arg in ("-p", "--ports"):
                port_range = sys.argv[i + 1]
                if "-" in port_range:
                    start_port, end_port = map(int, port_range.split('-'))
                else:
                    start_port = end_port = int(port_range)


命令列參數解析

sys.argv 陣列包含傳遞給腳本的參數清單。我們循環遍歷這些參數來檢查目標 IP(-t 或 --target)和連接埠範圍(-p 或 --ports)。

目標IP/主機名稱儲存在target_ip中。
連接埠範圍被解析​​並分為 start_port 和 end_port。如果不指定範圍,則預設掃描1到65535之間的所有連接埠。

import socket
from datetime import datetime
import sys
import os 

def usage():
    """Prints the usage information for this script."""
    usage_info = """
    Tool Name: SimplePortScanner 

    Developed by : Bharath Kumar

    Usage:
        python3 port_scanner.py [options]

    Options:
        -h, --help           Show this help message and exit.
        -t, --target <ip>    Specify the target hostname or IP address (required).
        -p, --port <port>    Specify a port (or) range of ports to scan (e.g. -p 80 (or) -p 1-1024).

    Description:
        This script performs a port scan on a specified hostname or IP address
        for a specific port or a range of ports, checking which ports are open. 

    Examples:
        python3 port_scanner.py -t example.com (or) 192.0.0.1 
        python3 port_scanner.py -t example.com (or) 192.168.1.1 -p 80
        python3 port_scanner.py -t example.com (or) 192.168.1.1 --ports 1-1024
    """
    print(usage_info)

start_time = datetime.now()

def scan_port(ip, port):

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(1)
    try:
        result = s.connect_ex((ip, port))
        service = socket.getservbyport(int(port))
    except:
        service = "None"
    if result == 0:
        print(" Port: {}\t State: Open\t Service: {}".format(port, service))

    else:
        pass

    s.close()


def host(target):
    try:
        ip = socket.gethostbyname(target)
        print('_'*51)
        print("[#] Resolved {} to {}".format(target,ip))
        return ip
    except:
        print('_'*51)
        print("[#] Error: Unable to resolve hostname {}".format(target))
        sys.exit(1)

def check_host_up(ip):

    ping = os.system("ping {} -c 1 > /dev/null".format(ip))

    if ping == 0:
       print("[#] {} host is up and running".format(ip))
       return True
    else:
        print("[#] {} host is down".format(ip))
        print("Exiting...")
        exit()
        return False





if __name__ == "__main__":

    target_ip = None
    start_port = 1
    end_port = 65535

    try:
        for i, arg in enumerate(sys.argv):
            if arg in ("-t", "--target"):
                target_ip = sys.argv[i + 1]
            elif arg in ("-p", "--ports"):
                port_range = sys.argv[i + 1]
                if "-" in port_range:
                    start_port, end_port = map(int, port_range.split('-'))
                else:
                    start_port = end_port = int(port_range)

        if target_ip is None:
            print("[#] Error: Target hostname or IP address is required.")
            usage()
            sys.exit(1)

        if start_port is None or end_port is None:
            print("[#] Error: Port range is required.")
            usage()
            sys.exit(1)

        target_ip = host(target_ip)

        if not check_host_up(target_ip):
            sys.exit(1)

        print(f"[#] Scanning {target_ip} from port {start_port} to {end_port}...")
        print("[#] Scanning started at: {}".format(start_time))
        print('_'*51)

        for port in range(start_port, end_port + 1):
            scan_port(target_ip, port)

    except (IndexError, ValueError):
        print("[#] Error: Invalid arguments provided.")
        usage()
        sys.exit(1)

start_time = start_time.now() - start_time
print('_'*51)
print("Scanning is completed in ",start_time)

主機解析度和可及性

一旦我們有了有效的IP位址,我們就需要檢查主機是否可以存取。函數host(target_ip)將主機名稱解析為其IP位址,check_host_up(target_ip)驗證主機是否在線。

def scan_port(ip, port):

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(1)
    try:
        result = s.connect_ex((ip, port))
        service = socket.getservbyport(int(port))
    except:
        service = "None"
    if result == 0:
        print(" Port: {}\t State: Open\t Service: {}".format(port, service))

    else:
        pass

    s.close()


連接埠掃描

連接埠掃描功能的核心發生在循環內:

此循環迭代指定的端口範圍,對於每個端口,函數 scan_port(target_ip, port) 探測端口以檢查它是打開還是關閉。

結論

透過遵循本指南,您已經學習瞭如何建立一個簡單的 Python 連接埠掃描器,該掃描器接受命令列參數、驗證輸入以及掃描給定目標上的一系列連接埠。雖然這是一個基本實現,但它為線程或服務檢測等更高級的功能奠定了基礎。

請隨意調整和擴展此腳本以滿足您的特定需求。祝掃描愉快!

以上是使用 Python 的基本連接埠掃描器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn