Skip to content

Commit

Permalink
Add new feature: reset MAC address to permanent device address
Browse files Browse the repository at this point in the history
Add new parameter -p, --permanent.
Minor fixes, code improvements and code optimization.
  • Loading branch information
Lopkop committed Jan 17, 2022
1 parent 87bf156 commit b8338dc
Showing 1 changed file with 47 additions and 33 deletions.
80 changes: 47 additions & 33 deletions macchanger.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
Command line: python macchanger.py --help
"""

import subprocess
import argparse
import random
import re
import sys
import subprocess

import colorama
import sys
import re

art = r"""
\\ //
Expand All @@ -20,7 +20,7 @@
/ >> \\\`__/_
/,)-^>> _\` \\\
(/ \\ //\\ [Author]: Lopkop
// _//\\\\ [Version]: 1.3
// _//\\\\ [Version]: 1.4
((` ((
"""

Expand Down Expand Up @@ -53,73 +53,87 @@ def _validate_interface(parser: argparse.ArgumentParser, interface: str) -> None
parser.error(colorama.Fore.LIGHTRED_EX + f'[-] interface "{interface}" does not exist.')


def _validate_all_requirements(parser: argparse.ArgumentParser, interface: str, mac_address: str) -> None:
"""Validates all requirements that must be checked"""
_validate_os(parser)
_validate_interface(parser, interface)
_validate_mac_address(parser, mac_address)


def _set_arguments_and_get_parameters(parser: argparse.ArgumentParser) -> argparse.Namespace:
"""Sets arguments and return user specify values"""
group = parser.add_mutually_exclusive_group()

parser.add_argument('-i', '--interface', dest='interface', help='Interface to change its MAC address')
group.add_argument('-m', '--mac', dest='new_mac', help='New MAC address')
group.add_argument('-r', '--random', dest='random_mac', help='Generates random MAC address', required=False,
action='store_true')
group.add_argument('-m', '--mac', dest='custom_mac', help='Set a custom MAC address')
group.add_argument('-r', '--random', dest='random_mac', help='Generate random MAC address',
action='store_true', required=False)
group.add_argument('-gcm', '--get-current-mac', dest='current_mac', help='Get current MAC address',
action='store_true', required=False)
group.add_argument('-p', '--permanent', dest='permanent_mac', help='Reset the MAC address to the permanent',
action='store_true', required=False)
parameters = parser.parse_args()

if not (parameters.current_mac or parameters.random_mac):
_validate_all_requirements(parser, parameters.interface, parameters.new_mac)
return parameters


def get_random_mac() -> str:
"""Generates random MAC address"""
return ':'.join(f'{random.randint(0, 255):02x}' for _ in range(6))
def get_permanent_mac(interface: str) -> str:
if sys.platform.startswith('darwin'):
mac = subprocess.run(f'networksetup -getmacaddress {interface}', shell=True, capture_output=True)
elif sys.platform.startswith('linux'):
mac = subprocess.run(f'ethtool -P {interface}', shell=True, capture_output=True)
return re.search(r'\w\w:\w\w:\w\w:\w\w:\w\w:\w\w', str(mac)).group(0)


def get_current_mac(parser: argparse.ArgumentParser, parameters: argparse.Namespace) -> str:
def get_current_mac(interface: str) -> str:
"""Returns current MAC address from interface that user specify"""
_validate_interface(parser, parameters.interface)
ifconfig_result = subprocess.check_output(['ifconfig', parameters.interface])
ifconfig_result = subprocess.check_output(['ifconfig', interface])
mac_address = re.search(r'\w\w:\w\w:\w\w:\w\w:\w\w:\w\w', str(ifconfig_result))

if mac_address:
return mac_address.group(0)
else:
parser.error(colorama.Fore.LIGHTRED_EX + f'[-] Could not read MAC address.')
print(colorama.Fore.LIGHTRED_EX + f'[-] Could not read MAC address.')
exit()


def get_random_mac() -> str:
"""Generates random MAC address"""
return ':'.join(f'{random.randint(0, 255):02x}' for _ in range(6))


def change_mac(interface: str, mac_address: str) -> None:
"""Changes the mac address"""
if sys.platform.startswith('darwin'):
subprocess.call(f'sudo ifconfig {interface} ether {mac_address}', shell=True)
if sys.platform.startswith('linux'):
elif sys.platform.startswith('linux'):
subprocess.call(f'ifconfig {interface} down', shell=True)
subprocess.call(f'ifconfig {interface} hw ether {mac_address}', shell=True)
subprocess.call(f'ifconfig {interface} up', shell=True)


def verify_mac_change_and_print_result(interface: str, mac: str) -> str:
return (colorama.Fore.LIGHTGREEN_EX + f'[+] MAC address has been changed to {mac}' if
get_current_mac(interface) == mac else
colorama.Fore.LIGHTRED_EX + f'[-] MAC address has not been changed to {mac}')


if __name__ == '__main__':
main_parser = argparse.ArgumentParser(description='Simple mac address changer for Linux and OS X.')
arguments = _set_arguments_and_get_parameters(main_parser)

_validate_os(main_parser)
_validate_interface(main_parser, arguments.interface)
if not (arguments.current_mac or arguments.random_mac or arguments.permanent_mac):
_validate_mac_address(main_parser, arguments.custom_mac)

print(art)
if arguments.current_mac:
print(f'current MAC = {get_current_mac(main_parser, arguments)}')
print(colorama.Style.BRIGHT + f'current MAC = {get_current_mac(arguments.interface)}')
exit()
print(f'current MAC = {get_current_mac(main_parser, arguments)}')
print(colorama.Style.BRIGHT + f'current MAC = {get_current_mac(arguments.interface)}')

random_mac = get_random_mac()
permanent_mac = get_permanent_mac(arguments.interface)
if arguments.random_mac:
random_mac = get_random_mac()
change_mac(arguments.interface, random_mac)
print(verify_mac_change_and_print_result(arguments.interface, random_mac))
elif custom_mac := arguments.custom_mac:
change_mac(arguments.interface, custom_mac)
print(verify_mac_change_and_print_result(arguments.interface, custom_mac))
else:
change_mac(arguments.interface, arguments.new_mac)

if get_current_mac(main_parser, arguments) == (new_mac := arguments.new_mac or random_mac):
print(colorama.Fore.LIGHTGREEN_EX + f'[+] MAC address has been changed to {new_mac}')
else:
print(colorama.Fore.LIGHTRED_EX + f'[-] MAC address has not been changed to {new_mac}')
change_mac(arguments.interface, permanent_mac)
print(verify_mac_change_and_print_result(arguments.interface, permanent_mac))

0 comments on commit b8338dc

Please sign in to comment.