From 8cac05c13df417c9b30b14768d43894780c9384b Mon Sep 17 00:00:00 2001 From: silversword411 Date: Thu, 5 Jun 2025 02:26:58 -0400 Subject: [PATCH 1/2] Add script to trigger remote wipe via MDM --- .../Win_ResetviaMDM.ps1 | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) rename {scripts_wip => scripts_staging}/Win_ResetviaMDM.ps1 (74%) diff --git a/scripts_wip/Win_ResetviaMDM.ps1 b/scripts_staging/Win_ResetviaMDM.ps1 similarity index 74% rename from scripts_wip/Win_ResetviaMDM.ps1 rename to scripts_staging/Win_ResetviaMDM.ps1 index 33c09909..21314fc4 100644 --- a/scripts_wip/Win_ResetviaMDM.ps1 +++ b/scripts_staging/Win_ResetviaMDM.ps1 @@ -1,4 +1,13 @@ -# Uses MDM features of windows to perform a Windows Reset clearing all data +<# +.SYNOPSIS + Trigger a remote wipe via MDM. + +.DESCRIPTION + Invokes the 'doWipeMethod' in Windows equivalent to the Reset function in the Settings app. + +.NOTES + v1.0 7/2024 bbrendon Initial version +#> $namespaceName = "root\cimv2\mdm\dmmap" $className = "MDM_RemoteWipe" @@ -16,4 +25,4 @@ try { } catch [Exception] { write-host $_ | out-string -} \ No newline at end of file +} From 217db5909f4e80beff3d0a1e8da7ac5df9dbb58f Mon Sep 17 00:00:00 2001 From: silversword411 Date: Thu, 5 Jun 2025 02:33:34 -0400 Subject: [PATCH 2/2] Enhance Win_NetworkScanner to include MAC address lookup and update parameter descriptions --- scripts_staging/Win_NetworkScanner.py | 73 ++++++++++++++++----------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/scripts_staging/Win_NetworkScanner.py b/scripts_staging/Win_NetworkScanner.py index bc3d9634..8413e867 100644 --- a/scripts_staging/Win_NetworkScanner.py +++ b/scripts_staging/Win_NetworkScanner.py @@ -4,14 +4,16 @@ This script performs a network scan on a given target or subnet. 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. -Params ---hostname +Params: +--hostname Perform reverse DNS lookup +--mac Include MAC address in output v1.1 2/2024 silversword411 v1.4 added open port checker -v1.5 5/2/2024 integrated reverse DNS lookup into the ping function with 1-second timeout -v1.6 5/31/2024 align output to columns and ports low to high -v1.7 2/18/2025 fix columns with long host names and added response time +v1.5 5/2/2024 silversword411 integrated reverse DNS lookup into the ping function with 1-second timeout +v1.6 5/31/2024 silversword411 align output to columns and ports low to high +v1.7 2/18/2025 silversword411 fix columns with long host names and added response time +v1.8 5/21/2025 silversword411 added MAC address lookup with --mac option TODO: Make subnet get automatically detected TODO: run on linux as well @@ -26,7 +28,6 @@ import argparse -# Function to get the IP address of the primary network interface def get_host_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: @@ -39,7 +40,6 @@ def get_host_ip(): return IP -# Function to ping an IP address, check if it is alive, measure response time, and optionally perform a reverse DNS lookup def ping_ip(ip, alive_hosts, do_reverse_dns): try: output = subprocess.check_output( @@ -50,9 +50,7 @@ def ping_ip(ip, alive_hosts, do_reverse_dns): if "Reply from" in output: alive_ip = ipaddress.ip_address(ip) response_time = re.search(r"time[=<]\s*(\d+)ms", output) - response_time = ( - int(response_time.group(1)) if response_time else -1 - ) # If no time found, use -1 + response_time = int(response_time.group(1)) if response_time else -1 hostname = "NA" if do_reverse_dns: @@ -65,12 +63,22 @@ def ping_ip(ip, alive_hosts, do_reverse_dns): finally: s.close() - alive_hosts.append((alive_ip, hostname, response_time)) + alive_hosts.append( + (alive_ip, hostname, response_time, "") + ) # Placeholder for MAC except Exception: pass -# Function to check for open ports +def get_mac_address(ip): + try: + output = subprocess.check_output(["arp", "-a", ip], universal_newlines=True) + match = re.search(r"(\w{2}-\w{2}-\w{2}-\w{2}-\w{2}-\w{2})", output) + return match.group(1) if match else "N/A" + except Exception: + return "N/A" + + def check_ports(ip, port, open_ports): try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: @@ -81,18 +89,19 @@ def check_ports(ip, port, open_ports): pass -# Parse command-line arguments def parse_arguments(): parser = argparse.ArgumentParser( - description="Scan network subnet for alive hosts, open ports, and optionally perform reverse DNS lookup." + description="Scan network subnet for alive hosts, open ports, and optionally perform reverse DNS or get MAC address." ) parser.add_argument( "--hostname", help="Perform reverse DNS lookup", action="store_true" ) + parser.add_argument( + "--mac", help="Include MAC address in output", action="store_true" + ) return parser.parse_args() -# Main function to detect the subnet and scan it def main(): args = parse_arguments() host_ip = get_host_ip() @@ -111,12 +120,15 @@ def main(): for t in threads: t.join() - # Sort the alive hosts numerically + if args.mac: + for i, (ip, hostname, response_time, _) in enumerate(alive_hosts): + mac = get_mac_address(str(ip)) + alive_hosts[i] = (ip, hostname, response_time, mac) + alive_hosts.sort(key=lambda x: x[0]) - # Launch port checks port_check_threads = [] - for host, _, _ in alive_hosts: + for host, _, _, _ in alive_hosts: for port in [22, 23, 25, 80, 443, 2525, 8443, 10443, 10000, 20000]: t = threading.Thread(target=check_ports, args=(str(host), port, open_ports)) t.start() @@ -125,28 +137,31 @@ def main(): for t in port_check_threads: t.join() - # Determine column widths dynamically max_hostname_length = max( - (len(hostname) for _, hostname, _ in alive_hosts), default=8 + (len(hostname) for _, hostname, _, _ in alive_hosts), default=8 ) ip_column_width = 16 - hostname_column_width = max(max_hostname_length, 12) + 2 # Minimum width of 12 + hostname_column_width = max(max_hostname_length, 12) + 2 response_time_column_width = 8 - ports_column_width = 50 # Static width for ports + mac_column_width = 20 if args.mac else 0 + ports_column_width = 50 - # Print header - header = f"{'IP':<{ip_column_width}}{'(ms)':<{response_time_column_width}}{'Hostname':<{hostname_column_width}}{'Open Ports':<{ports_column_width}}" + header = f"{'IP':<{ip_column_width}}{'(ms)':<{response_time_column_width}}{'Hostname':<{hostname_column_width}}" + if args.mac: + header += f"{'MAC Address':<{mac_column_width}}" + header += f"{'Open Ports':<{ports_column_width}}" print(header) print("-" * len(header)) - # Print results - for host, hostname, response_time in alive_hosts: + for host, hostname, response_time, mac in alive_hosts: ports = sorted(open_ports[str(host)]) ports_str = ", ".join(map(str, ports)) response_time_str = f"{response_time} ms" if response_time >= 0 else "N/A" - print( - f"{str(host):<{ip_column_width}}{response_time_str:<{response_time_column_width}}{hostname:<{hostname_column_width}}{ports_str:<{ports_column_width}}" - ) + line = f"{str(host):<{ip_column_width}}{response_time_str:<{response_time_column_width}}{hostname:<{hostname_column_width}}" + if args.mac: + line += f"{mac:<{mac_column_width}}" + line += f"{ports_str:<{ports_column_width}}" + print(line) print(f"\nTotal count of alive hosts: {len(alive_hosts)}")