>백엔드 개발 >파이썬 튜토리얼 >Python을 사용하는 기본 포트 스캐너

Python을 사용하는 기본 포트 스캐너

Linda Hamilton
Linda Hamilton원래의
2024-10-23 13:31:30255검색

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)에 액세스합니다.

Import 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()


이 코드 블록은 주어진 IP 주소의 특정 포트가 소켓을 사용하여 열려 있는지 확인하는 함수 scan_port(ip, port)를 정의합니다.

소켓 생성: 소켓.socket(socket.AF_INET, 소켓.SOCK_STREAM) TCP를 사용하여 IPv4용 새 소켓을 생성합니다.

시간 초과: s.settimeout(1) 소켓 시간을 1초로 설정합니다. 해당 시간 내에 연결이 성공하지 못하면 시도가 중지됩니다.

연결 테스트:s.connect_ex((ip, port))특정 IP와 포트에 연결을 시도합니다. 성공하면 결과는 0이 됩니다. 그렇지 않으면 다른 값이 됩니다.

서비스 감지: 소켓.getservbyport(int(port))는 포트 80의 HTTP와 같이 지정된 포트에서 실행 중인 서비스를 감지합니다.

오류 처리: 오류가 발생한 경우(예: 포트에 서비스 없음) 제외 블록은 서비스를 "없음"으로 설정합니다.

출력: 포트가 열려 있으면(결과 == 0) 포트 번호, 상태("Open") 및 서비스 이름을 인쇄합니다.

연결 폐쇄: 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)

이 코드 블록은 소켓.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

이 함수는 os.system() 핑 메소드를 사용하여 특정 대상 IP의 특정 포트가 작동 중인지 작동 중지되었는지 확인하는 check_host_up(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 주소가 있으면 호스트에 연결할 수 있는지 확인해야 합니다. 호스트(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으로 문의하세요.