Skip to content

Commit 4211d4a

Browse files
Merge pull request #290 from silversword411/main
Fix MDM comment header and update Network scanner to 1.8
2 parents 4f67dbc + 217db59 commit 4211d4a

File tree

2 files changed

+55
-31
lines changed

2 files changed

+55
-31
lines changed

scripts_staging/Win_NetworkScanner.py

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
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.
66
7-
Params
8-
--hostname
7+
Params:
8+
--hostname Perform reverse DNS lookup
9+
--mac Include MAC address in output
910
1011
v1.1 2/2024 silversword411
1112
v1.4 added open port checker
12-
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
13+
v1.5 5/2/2024 silversword411 integrated reverse DNS lookup into the ping function with 1-second timeout
14+
v1.6 5/31/2024 silversword411 align output to columns and ports low to high
15+
v1.7 2/18/2025 silversword411 fix columns with long host names and added response time
16+
v1.8 5/21/2025 silversword411 added MAC address lookup with --mac option
1517
1618
TODO: Make subnet get automatically detected
1719
TODO: run on linux as well
@@ -26,7 +28,6 @@
2628
import argparse
2729

2830

29-
# Function to get the IP address of the primary network interface
3031
def get_host_ip():
3132
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
3233
try:
@@ -39,7 +40,6 @@ def get_host_ip():
3940
return IP
4041

4142

42-
# Function to ping an IP address, check if it is alive, measure response time, and optionally perform a reverse DNS lookup
4343
def ping_ip(ip, alive_hosts, do_reverse_dns):
4444
try:
4545
output = subprocess.check_output(
@@ -50,9 +50,7 @@ def ping_ip(ip, alive_hosts, do_reverse_dns):
5050
if "Reply from" in output:
5151
alive_ip = ipaddress.ip_address(ip)
5252
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
53+
response_time = int(response_time.group(1)) if response_time else -1
5654

5755
hostname = "NA"
5856
if do_reverse_dns:
@@ -65,12 +63,22 @@ def ping_ip(ip, alive_hosts, do_reverse_dns):
6563
finally:
6664
s.close()
6765

68-
alive_hosts.append((alive_ip, hostname, response_time))
66+
alive_hosts.append(
67+
(alive_ip, hostname, response_time, "")
68+
) # Placeholder for MAC
6969
except Exception:
7070
pass
7171

7272

73-
# Function to check for open ports
73+
def get_mac_address(ip):
74+
try:
75+
output = subprocess.check_output(["arp", "-a", ip], universal_newlines=True)
76+
match = re.search(r"(\w{2}-\w{2}-\w{2}-\w{2}-\w{2}-\w{2})", output)
77+
return match.group(1) if match else "N/A"
78+
except Exception:
79+
return "N/A"
80+
81+
7482
def check_ports(ip, port, open_ports):
7583
try:
7684
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
@@ -81,18 +89,19 @@ def check_ports(ip, port, open_ports):
8189
pass
8290

8391

84-
# Parse command-line arguments
8592
def parse_arguments():
8693
parser = argparse.ArgumentParser(
87-
description="Scan network subnet for alive hosts, open ports, and optionally perform reverse DNS lookup."
94+
description="Scan network subnet for alive hosts, open ports, and optionally perform reverse DNS or get MAC address."
8895
)
8996
parser.add_argument(
9097
"--hostname", help="Perform reverse DNS lookup", action="store_true"
9198
)
99+
parser.add_argument(
100+
"--mac", help="Include MAC address in output", action="store_true"
101+
)
92102
return parser.parse_args()
93103

94104

95-
# Main function to detect the subnet and scan it
96105
def main():
97106
args = parse_arguments()
98107
host_ip = get_host_ip()
@@ -111,12 +120,15 @@ def main():
111120
for t in threads:
112121
t.join()
113122

114-
# Sort the alive hosts numerically
123+
if args.mac:
124+
for i, (ip, hostname, response_time, _) in enumerate(alive_hosts):
125+
mac = get_mac_address(str(ip))
126+
alive_hosts[i] = (ip, hostname, response_time, mac)
127+
115128
alive_hosts.sort(key=lambda x: x[0])
116129

117-
# Launch port checks
118130
port_check_threads = []
119-
for host, _, _ in alive_hosts:
131+
for host, _, _, _ in alive_hosts:
120132
for port in [22, 23, 25, 80, 443, 2525, 8443, 10443, 10000, 20000]:
121133
t = threading.Thread(target=check_ports, args=(str(host), port, open_ports))
122134
t.start()
@@ -125,28 +137,31 @@ def main():
125137
for t in port_check_threads:
126138
t.join()
127139

128-
# Determine column widths dynamically
129140
max_hostname_length = max(
130-
(len(hostname) for _, hostname, _ in alive_hosts), default=8
141+
(len(hostname) for _, hostname, _, _ in alive_hosts), default=8
131142
)
132143
ip_column_width = 16
133-
hostname_column_width = max(max_hostname_length, 12) + 2 # Minimum width of 12
144+
hostname_column_width = max(max_hostname_length, 12) + 2
134145
response_time_column_width = 8
135-
ports_column_width = 50 # Static width for ports
146+
mac_column_width = 20 if args.mac else 0
147+
ports_column_width = 50
136148

137-
# Print header
138-
header = f"{'IP':<{ip_column_width}}{'(ms)':<{response_time_column_width}}{'Hostname':<{hostname_column_width}}{'Open Ports':<{ports_column_width}}"
149+
header = f"{'IP':<{ip_column_width}}{'(ms)':<{response_time_column_width}}{'Hostname':<{hostname_column_width}}"
150+
if args.mac:
151+
header += f"{'MAC Address':<{mac_column_width}}"
152+
header += f"{'Open Ports':<{ports_column_width}}"
139153
print(header)
140154
print("-" * len(header))
141155

142-
# Print results
143-
for host, hostname, response_time in alive_hosts:
156+
for host, hostname, response_time, mac in alive_hosts:
144157
ports = sorted(open_ports[str(host)])
145158
ports_str = ", ".join(map(str, ports))
146159
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-
)
160+
line = f"{str(host):<{ip_column_width}}{response_time_str:<{response_time_column_width}}{hostname:<{hostname_column_width}}"
161+
if args.mac:
162+
line += f"{mac:<{mac_column_width}}"
163+
line += f"{ports_str:<{ports_column_width}}"
164+
print(line)
150165

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

scripts_wip/Win_ResetviaMDM.ps1 renamed to scripts_staging/Win_ResetviaMDM.ps1

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
# Uses MDM features of windows to perform a Windows Reset clearing all data
1+
<#
2+
.SYNOPSIS
3+
Trigger a remote wipe via MDM.
4+
5+
.DESCRIPTION
6+
Invokes the 'doWipeMethod' in Windows equivalent to the Reset function in the Settings app.
7+
8+
.NOTES
9+
v1.0 7/2024 bbrendon Initial version
10+
#>
211

312
$namespaceName = "root\cimv2\mdm\dmmap"
413
$className = "MDM_RemoteWipe"
@@ -16,4 +25,4 @@ try {
1625
}
1726
catch [Exception] {
1827
write-host $_ | out-string
19-
}
28+
}

0 commit comments

Comments
 (0)