93 lines
2.5 KiB
Python
Executable file
93 lines
2.5 KiB
Python
Executable file
#!/usr/bin/python3
|
|
|
|
import socket
|
|
import common_ports
|
|
import os
|
|
import sys
|
|
import re
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
|
|
|
|
def scan_port(ip_addr, port):
|
|
try:
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
s.settimeout(1)
|
|
result = s.connect_ex((ip_addr, port))
|
|
s.close()
|
|
if result == 0:
|
|
return port
|
|
except:
|
|
return None
|
|
return None
|
|
|
|
|
|
def get_open_ports(target, port_range, verbose=False):
|
|
open_ports = []
|
|
|
|
# Try resolving the target
|
|
try:
|
|
ip_addr = socket.gethostbyname(target)
|
|
except socket.gaierror:
|
|
if re.match(r'^\d{1,3}(\.\d{1,3}){3}$', target):
|
|
return "Error: Invalid IP address"
|
|
else:
|
|
return "Error: Invalid hostname"
|
|
|
|
# Build the list of ports from range
|
|
ports_list = list(range(port_range[0], port_range[1] + 1))
|
|
|
|
with ThreadPoolExecutor(max_workers=100) as executor:
|
|
futures = [executor.submit(scan_port, ip_addr, port) for port in ports_list]
|
|
for future in futures:
|
|
result = future.result()
|
|
if result:
|
|
open_ports.append(result)
|
|
|
|
# Output
|
|
if verbose:
|
|
try:
|
|
hostname = socket.gethostbyaddr(ip_addr)[0]
|
|
except socket.herror:
|
|
hostname = target
|
|
|
|
output = f"Open ports for {hostname} ({ip_addr})\nPORT SERVICE\n"
|
|
try:
|
|
import common_ports
|
|
for port in open_ports:
|
|
service = common_ports.ports_and_services.get(port, 'unknown')
|
|
output += f"{port:<9}{service}\n"
|
|
except ImportError:
|
|
for port in open_ports:
|
|
output += f"{port:<9}unknown\n"
|
|
return output.strip()
|
|
|
|
return open_ports
|
|
|
|
|
|
# print(get_open_ports("scanme.nmap.org", [20, 80], verbose=True))
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python3 portscan.py <ip_or_file> [start_port] [end_port] [--verbose]")
|
|
return
|
|
|
|
input_arg = sys.argv[1]
|
|
start_port = int(sys.argv[2]) if len(sys.argv) > 2 else 20
|
|
end_port = int(sys.argv[3]) if len(sys.argv) > 3 else 1024
|
|
verbose = "--verbose" in sys.argv
|
|
|
|
targets = []
|
|
|
|
if os.path.isfile(input_arg):
|
|
with open(input_arg) as f:
|
|
targets = [line.strip() for line in f if line.strip()]
|
|
else:
|
|
targets = [input_arg]
|
|
|
|
for target in targets:
|
|
print(get_open_ports(target, [start_port, end_port], verbose))
|
|
print("-" * 40)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|