Skip to content

Commit 77f383c

Browse files
authored
Merge branch 'amidaware:main' into main
2 parents caf39a9 + d446b64 commit 77f383c

File tree

1 file changed

+62
-17
lines changed

1 file changed

+62
-17
lines changed

scripts_staging/Win_NetworkScanner.py

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,57 @@
33
"""
44
This script performs a network scan on a given target or subnet.
55
It checks if the target hosts are alive, and if ports 80 (HTTP) and 443 (HTTPS) are open, and optionally performs reverse DNS lookups if specified.
6+
7+
Params
8+
--hostname
9+
610
v1.1 2/2024 silversword411
711
v1.4 added open port checker
812
v1.5 5/2/2024 integrated reverse DNS lookup into the ping function with 1-second timeout
13+
v1.6 5/31/2024 align output to columns and ports low to high
14+
v1.7 2/18/2025 fix columns with long host names and added response time
915
10-
TODO: Make subnet get automatically detected instead of assuming /24
11-
TODO: Compatible with Linux as well
16+
TODO: Make subnet get automatically detected
17+
TODO: run on linux as well
1218
"""
1319

1420
import socket
1521
import threading
1622
import subprocess
1723
import ipaddress
24+
import re
1825
from collections import defaultdict
1926
import argparse
2027

28+
2129
# Function to get the IP address of the primary network interface
2230
def get_host_ip():
2331
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
2432
try:
25-
s.connect(('10.255.255.255', 1))
33+
s.connect(("10.255.255.255", 1))
2634
IP = s.getsockname()[0]
2735
except Exception:
28-
IP = '127.0.0.1'
36+
IP = "127.0.0.1"
2937
finally:
3038
s.close()
3139
return IP
3240

33-
# Function to ping an IP address, check if it is alive, and optionally perform a reverse DNS lookup
41+
42+
# Function to ping an IP address, check if it is alive, measure response time, and optionally perform a reverse DNS lookup
3443
def ping_ip(ip, alive_hosts, do_reverse_dns):
3544
try:
36-
output = subprocess.check_output(["ping", "-n", "1", "-w", "1000", ip], stderr=subprocess.STDOUT, universal_newlines=True)
45+
output = subprocess.check_output(
46+
["ping", "-n", "1", "-w", "1000", ip],
47+
stderr=subprocess.STDOUT,
48+
universal_newlines=True,
49+
)
3750
if "Reply from" in output:
3851
alive_ip = ipaddress.ip_address(ip)
52+
response_time = re.search(r"time[=<]\s*(\d+)ms", output)
53+
response_time = (
54+
int(response_time.group(1)) if response_time else -1
55+
) # If no time found, use -1
56+
3957
hostname = "NA"
4058
if do_reverse_dns:
4159
try:
@@ -46,10 +64,12 @@ def ping_ip(ip, alive_hosts, do_reverse_dns):
4664
hostname = "unknown"
4765
finally:
4866
s.close()
49-
alive_hosts.append((alive_ip, hostname))
67+
68+
alive_hosts.append((alive_ip, hostname, response_time))
5069
except Exception:
5170
pass
5271

72+
5373
# Function to check for open ports
5474
def check_ports(ip, port, open_ports):
5575
try:
@@ -60,19 +80,25 @@ def check_ports(ip, port, open_ports):
6080
except Exception:
6181
pass
6282

83+
6384
# Parse command-line arguments
6485
def parse_arguments():
65-
parser = argparse.ArgumentParser(description="Scan network subnet for alive hosts, open ports, and optionally perform reverse DNS lookup.")
66-
parser.add_argument("--hostname", help="Perform reverse DNS lookup", action="store_true")
86+
parser = argparse.ArgumentParser(
87+
description="Scan network subnet for alive hosts, open ports, and optionally perform reverse DNS lookup."
88+
)
89+
parser.add_argument(
90+
"--hostname", help="Perform reverse DNS lookup", action="store_true"
91+
)
6792
return parser.parse_args()
6893

94+
6995
# Main function to detect the subnet and scan it
7096
def main():
7197
args = parse_arguments()
7298
host_ip = get_host_ip()
7399
print(f"Detected Host IP: {host_ip}")
74100

75-
subnet = ipaddress.ip_network(f'{host_ip}/24', strict=False)
101+
subnet = ipaddress.ip_network(f"{host_ip}/24", strict=False)
76102
alive_hosts = []
77103
open_ports = defaultdict(list)
78104

@@ -90,21 +116,40 @@ def main():
90116

91117
# Launch port checks
92118
port_check_threads = []
93-
for host, _ in alive_hosts:
119+
for host, _, _ in alive_hosts:
94120
for port in [22, 23, 25, 80, 443, 2525, 8443, 10443, 10000, 20000]:
95121
t = threading.Thread(target=check_ports, args=(str(host), port, open_ports))
96122
t.start()
97123
port_check_threads.append(t)
98-
124+
99125
for t in port_check_threads:
100126
t.join()
101127

102-
print(f"Alive hosts in the subnet {subnet}:")
103-
for host, hostname in alive_hosts:
104-
ports = ', '.join(str(port) for port in open_ports[str(host)])
105-
print(f"IP: {host}, {hostname}, Open Ports: {ports}")
128+
# Determine column widths dynamically
129+
max_hostname_length = max(
130+
(len(hostname) for _, hostname, _ in alive_hosts), default=8
131+
)
132+
ip_column_width = 16
133+
hostname_column_width = max(max_hostname_length, 12) + 2 # Minimum width of 12
134+
response_time_column_width = 8
135+
ports_column_width = 50 # Static width for ports
136+
137+
# Print header
138+
header = f"{'IP':<{ip_column_width}}{'(ms)':<{response_time_column_width}}{'Hostname':<{hostname_column_width}}{'Open Ports':<{ports_column_width}}"
139+
print(header)
140+
print("-" * len(header))
141+
142+
# Print results
143+
for host, hostname, response_time in alive_hosts:
144+
ports = sorted(open_ports[str(host)])
145+
ports_str = ", ".join(map(str, ports))
146+
response_time_str = f"{response_time} ms" if response_time >= 0 else "N/A"
147+
print(
148+
f"{str(host):<{ip_column_width}}{response_time_str:<{response_time_column_width}}{hostname:<{hostname_column_width}}{ports_str:<{ports_column_width}}"
149+
)
106150

107151
print(f"\nTotal count of alive hosts: {len(alive_hosts)}")
108152

153+
109154
if __name__ == "__main__":
110-
main()
155+
main()

0 commit comments

Comments
 (0)