-
Notifications
You must be signed in to change notification settings - Fork 0
/
portScanner.py
112 lines (102 loc) · 4.53 KB
/
portScanner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import sys
import socket
import argparse
import concurrent.futures
import requests
def probe_port(ip, port, timeout, protocol):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM if protocol == 'tcp' else socket.SOCK_DGRAM)
sock.settimeout(timeout)
if protocol == 'tcp':
result = sock.connect_ex((ip, port))
else:
result = sock.sendto(b'', (ip, port))
sock.close()
return result
except socket.error as e:
print(f"Socket error: {e}")
return None
def parse_port_range(port_range):
try:
if "-" in port_range:
start_port, end_port = map(int, port_range.split("-"))
if start_port < 1 or end_port > 65535:
raise ValueError("Invalid port range. Port numbers must be between 1 and 65535.")
return start_port, end_port
else:
port = int(port_range)
if port < 1 or port > 65535:
raise ValueError("Invalid port number. Port number must be between 1 and 65535.")
return port, port
except ValueError as e:
print(f"Invalid port range: {e}")
sys.exit(1)
def scan_ports(ip, port_range, num_threads, timeout, protocols):
open_ports = []
start_port, end_port = parse_port_range(port_range)
with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor:
futures = []
for port in range(start_port, end_port + 1):
for protocol in protocols:
futures.append(executor.submit(probe_port, ip, port, timeout, protocol))
for future in concurrent.futures.as_completed(futures):
response = future.result()
if response == 0:
open_ports.append(future._kwargs['port'])
return open_ports
def get_service_name(port, protocol):
try:
if protocol == 'tcp':
response = requests.get(f"https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search={port}")
response.raise_for_status()
service_name = response.text.split(f"<td>{port}</td>")[1].split("</a>")[0].split(">")[-1]
elif protocol == 'udp':
response = requests.get(f"https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers-udp.xhtml?search={port}")
response.raise_for_status()
service_name = response.text.split(f"<td>{port}</td>")[1].split("</a>")[0].split(">")[-1]
else:
service_name = None
return service_name
except requests.exceptions.RequestException as e:
print(f"Request error: {e}")
return None
def main():
# Parse the command-line arguments
parser = argparse.ArgumentParser(description="Python Port Scanner")
parser.add_argument("ip", help="IP address to scan")
parser.add_argument("-p", "--port-range", default="1-65535", help="Port range (e.g., 1-100, 80, 443) (default: 1-65535)")
parser.add_argument("-t", "--threads", type=int, default=100, help="Number of threads (default: 100)")
parser.add_argument("-T", "--timeout", type=float, default=1.0, help="Timeout in seconds (default: 1.0)")
parser.add_argument("-sS", "--syn-scan", action="store_true", help="Perform SYN scan")
parser.add_argument("-sT", "--tcp-scan", action="store_true", help="Perform TCP scan")
parser.add_argument("-sU", "--udp-scan", action="store_true", help="Perform UDP scan")
parser.add_argument("-sY", "--sctp-scan", action="store_true", help="Perform SCTP scan")
parser.add_argument("-sV", "--service-scan", action="store_true", help="Perform service scan")
args = parser.parse_args()
ip = args.ip
port_range = args.port_range
num_threads = args.threads
timeout = args.timeout
protocols = []
if args.syn_scan:
protocols.append('tcp')
if args.tcp_scan:
protocols.append('tcp')
if args.udp_scan:
protocols.append('udp')
if args.sctp_scan:
protocols.append('sctp')
open_ports = scan_ports(ip, port_range, num_threads, timeout, protocols)
if open_ports:
print("Open Ports:")
for port in open_ports:
for protocol in protocols:
service_name = get_service_name(port, protocol)
if service_name:
print(f"Port {port}/{protocol.upper()}: {service_name}")
else:
print(f"Port {port}/{protocol.upper()}: Unknown Service")
else:
print("No open ports found.")
if __name__ == "__main__":
main()