1+ import  subprocess 
2+ import  regex  as  re 
3+ import  string 
4+ import  random 
5+ 
6+ # the registry path of network interfaces 
7+ network_interface_reg_path  =  r"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e972-e325-11ce-bfc1-08002be10318}" 
8+ # the transport name regular expression, looks like {AF1B45DB-B5D4-46D0-B4EA-3E18FA49BF5F} 
9+ transport_name_regex  =  re .compile ("{.+}" )
10+ # the MAC address regular expression 
11+ mac_address_regex  =  re .compile (r"([A-Z0-9]{2}[:-]){5}([A-Z0-9]{2})" )
12+ 
13+ def  get_random_mac_address ():
14+     """Generate and return a MAC address in the format of WINDOWS""" 
15+     # get the hexdigits uppercased 
16+     uppercased_hexdigits  =  '' .join (set (string .hexdigits .upper ()))
17+     # 2nd character must be 2, 4, A, or E 
18+     return  random .choice (uppercased_hexdigits ) +  random .choice ("24AE" ) +  "" .join (random .sample (uppercased_hexdigits , k = 10 ))
19+     
20+ 
21+ def  clean_mac (mac ):
22+     """Simple function to clean non hexadecimal characters from a MAC address 
23+     mostly used to remove '-' and ':' from MAC addresses and also uppercase it""" 
24+     return  "" .join (c  for  c  in  mac  if  c  in  string .hexdigits ).upper ()    
25+ 
26+ 
27+ def  get_connected_adapters_mac_address ():
28+     # make a list to collect connected adapter's MAC addresses along with the transport name 
29+     connected_adapters_mac  =  []
30+     # use the getmac command to extract  
31+     for  potential_mac  in  subprocess .check_output ("getmac" ).decode ().splitlines ():
32+         # parse the MAC address from the line 
33+         mac_address  =  mac_address_regex .search (potential_mac )
34+         # parse the transport name from the line 
35+         transport_name  =  transport_name_regex .search (potential_mac )
36+         if  mac_address  and  transport_name :
37+             # if a MAC and transport name are found, add them to our list 
38+             connected_adapters_mac .append ((mac_address .group (), transport_name .group ()))
39+     return  connected_adapters_mac 
40+ 
41+ 
42+ def  get_user_adapter_choice (connected_adapters_mac ):
43+     # print the available adapters 
44+     for  i , option  in  enumerate (connected_adapters_mac ):
45+         print (f"#{ i }  : { option [0 ]}  , { option [1 ]}  " )
46+     if  len (connected_adapters_mac ) <=  1 :
47+         # when there is only one adapter, choose it immediately 
48+         return  connected_adapters_mac [0 ]
49+     # prompt the user to choose a network adapter index 
50+     try :
51+         choice  =  int (input ("Please choose the interface you want to change the MAC address:" ))
52+         # return the target chosen adapter's MAC and transport name that we'll use later to search for our adapter 
53+         # using the reg QUERY command 
54+         return  connected_adapters_mac [choice ]
55+     except :
56+         # if -for whatever reason- an error is raised, just quit the script 
57+         print ("Not a valid choice, quitting..." )
58+         exit ()
59+     
60+ 
61+ def  change_mac_address (adapter_transport_name , new_mac_address ):
62+     # use reg QUERY command to get available adapters from the registry 
63+     output  =  subprocess .check_output (f"reg QUERY "  +   network_interface_reg_path .replace ("\\ \\ " , "\\ " )).decode ()
64+     for  interface  in  re .findall (rf"{ network_interface_reg_path }  \\\d+" , output ):
65+         # get the adapter index 
66+         adapter_index  =  int (interface .split ("\\ " )[- 1 ])
67+         interface_content  =  subprocess .check_output (f"reg QUERY { interface .strip ()}  " ).decode ()
68+         if  adapter_transport_name  in  interface_content :
69+             # if the transport name of the adapter is found on the output of the reg QUERY command 
70+             # then this is the adapter we're looking for 
71+             # change the MAC address using reg ADD command 
72+             changing_mac_output  =  subprocess .check_output (f"reg add { interface }   /v NetworkAddress /d { new_mac_address }   /f" ).decode ()
73+             # print the command output 
74+             print (changing_mac_output )
75+             # break out of the loop as we're done 
76+             break 
77+     # return the index of the changed adapter's MAC address 
78+     return  adapter_index 
79+       
80+ 
81+ def  disable_adapter (adapter_index ):
82+     # use wmic command to disable our adapter so the MAC address change is reflected 
83+     disable_output  =  subprocess .check_output (f"wmic path win32_networkadapter where index={ adapter_index }   call disable" ).decode ()
84+     return  disable_output 
85+ 
86+ 
87+ def  enable_adapter (adapter_index ):
88+     # use wmic command to enable our adapter so the MAC address change is reflected 
89+     enable_output  =  subprocess .check_output (f"wmic path win32_networkadapter where index={ adapter_index }   call enable" ).decode ()
90+     return  enable_output 
91+         
92+ 
93+ if  __name__  ==  "__main__" :
94+     import  argparse 
95+     parser  =  argparse .ArgumentParser (description = "Python Windows MAC changer" )
96+     parser .add_argument ("-r" , "--random" , action = "store_true" , help = "Whether to generate a random MAC address" )
97+     parser .add_argument ("-m" , "--mac" , help = "The new MAC you want to change to" )
98+     args  =  parser .parse_args ()
99+     if  args .random :
100+         # if random parameter is set, generate a random MAC 
101+         new_mac_address  =  get_random_mac_address ()
102+     elif  args .mac :
103+         # if mac is set, use it after cleaning 
104+         new_mac_address  =  clean_mac (args .mac )
105+     
106+     connected_adapters_mac  =  get_connected_adapters_mac_address ()
107+     old_mac_address , target_transport_name  =  get_user_adapter_choice (connected_adapters_mac )
108+     print ("[*] Old MAC address:" , old_mac_address )
109+     adapter_index  =  change_mac_address (target_transport_name , new_mac_address )
110+     print ("[+] Changed to:" , new_mac_address )
111+     disable_adapter (adapter_index )
112+     print ("[+] Adapter is disabled" )
113+     enable_adapter (adapter_index )
114+     print ("[+] Adapter is enabled again" )
0 commit comments