-
Notifications
You must be signed in to change notification settings - Fork 0
/
fast_port_scanner.py
130 lines (105 loc) · 4.53 KB
/
fast_port_scanner.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# ADVANCE PORT SCANNER WITH CONCURRENCY AND MULTITHREADING
import socket, sys
import time, queue
import argparse
from colorama import init, Fore
import threading
import signal
import requests
# Function to handle Ctrl+C signal
def signal_handler(sig, frame):
print(f'\n{red}[!] Ctrl+C pressed. Exiting...{reset}')
sys.exit(0)
# Set up signal handler for Ctrl+C
signal.signal(signal.SIGINT, signal_handler)
# Initialize colorama for colored output
init()
red = Fore.RED
green = Fore.GREEN
blue = Fore.BLUE
reset = Fore.RESET
# Get target network from command line arguments
argparse = argparse.ArgumentParser(description="This is simple port scanner tool",
usage=" python3 simple_port_scanner.py -t TARGET -s START_PORT -e END_PORT --threads NUMBER_OF_THREADS")
print(f"{red}*{reset}{reset}" * 50)
print(f"{red}Python simple port scanner{reset}{reset}")
print(f"{red}*{reset}{reset}" * 50)
argparse.add_argument("-t", "--target", help="Enter the target ip to scan", required=True)
argparse.add_argument("-s", "--start_port", help="Enter the starting port no. from which you want to scan",
required=True, type=int)
argparse.add_argument("-e", "--end_port", help="Enter the ending port no. till which you want to scan", required=True,
type=int)
argparse.add_argument("--threads", help="Enter the number of threads you want to run", type=int)
argparse.add_argument("-o", "--output", help="Enter the name and path file to write output to")
args = argparse.parse_args()
target = args.target
start_port = args.start_port
end_port = args.end_port
thread_no = args.threads
output = args.output
result = "[+] Result:\nPORT\tSTATE\tSERVICE\n"
# Host name resolution
try:
target = socket.gethostbyname(target)
except:
print("[-] Host resolution failed.")
exit()
print(f"{red} [+]Scanning target: {target}{reset}")
"""this is written for receiving connection which has argument the number of bits that has to be obtained generally
the first bits obtained are banner as exception for port 80, port 80 does not returns any data so we have to handle
it separately"""
# function to get banner (Receiving Raw Data from an Open Port)
def get_banner(port, s):
if port == 80:
response = requests.get('http://' + target)
return response.headers["Server"]
try:
return s.recv(1024).decode()
except:
return 'NOT FOUND'
# Method which will run using threads provided below and taking ports from queue
def scan_port(t_no):
global result
while not q.empty():
port = q.get()
print(f" {blue}Scanning for port {port}...{reset}")
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(3)
conn = s.connect_ex((target, port))
if conn == 0: # not conn => not 0 which is true so can be written as if not conn also
banner = get_banner(port, s) # storing the banner data obtained by get_banner function
banner = "".join(banner.splitlines()) # to avoid extra \n in output
result += f"{red}{port}\tOPEN\t{banner}\n{reset}"
s.close()
except Exception as e:
print(f"An error occurred: {e}")
q.task_done()
# creation of queue
q = queue.Queue() # This line reassigns q to a new empty queue
# calculating starting_time
start_time: float = time.time()
# adding ports to queue
for j in range(start_port, end_port + 1):
q.put(j)
# creation of thread and starting of thread
for i in range(thread_no):
t = threading.Thread(target=scan_port, args=(i,))
t.start()
"""
Every program runs main thread first the main thread consists of material that is on zero indent to avoid main thread to run first
so here our time taken is on 0th indent that means it is on main thread and above method is on another thread so if the main thread
runs first then it will print time taken first and then move to function so to avoid this we use
"""
q.join()
# q.join here specifies that if all the ports are scanned then only you move to lines given below to calculate time
# taken calculating end_time
end_time = time.time()
print(result)
# calculating total time taken
print(f"{green}Time taken: {end_time - start_time}{reset}")
if output:
with open(output, 'w') as file:
file.write(f"Port scan result for target {target}\n")
file.write(result)
print("[+] Written to file ")