Cambiar dirección MAC con Python

Muchas redes tienen filtrado por MAC para impedir la conexión de dispositivos desconocidos a dicha red.

En esta entrada veremos cómo podemos cambiar la dirección MAC de nuestro equipo por una que nosotros elijamos con un sencillo script en Python.

Lo primero es conocer la interfaz de red a la que queremos cambiar la dirección MAC, para ello, desde la terminal ejecutamos:

$ ifconfig

y veremos algo como esto:

Salida de ifconfig

Vemos que la interfaz de red en este caso es eth0 y que la dirección MAC actual es 08:00:27:90:18:59

Analizando el código

Vamos a ver el código del script función por función.

Primero las librerías necesarias. No debería hacer falta instalarlas porque suele traerlas el sistema por defecto, son las siguientes:

  • subprocess: para ejecutar comando sobre el sistema
  • optparse: para las opciones del script
  • re: para testear con expresiones regulares que la nueva MAC cumpla con el formato válido
  • os: para saber si el usuario es root

Primero las importamos:

import subprocess
import optparse
import re
import os

Comprueba con una expresión regular, que la dirección MAC que hemos elegido tiene el formato correcto:

def get_current_mac(interface):
    ifconfig = subprocess.check_output(['ifconfig', interface])
    mac_address = re.search(r'\w\w:\w\w:\w\w:\w\w:\w\w:\w\w', str(ifconfig))

    if mac_address:
        return mac_address.group(0)

    raise Exception('Sorry, MAC address not found')

Crea el menú de consola de nuestra aplicación:

def get_arguments():
    parser = optparse.OptionParser()

    parser.add_option('-i', '--interface', dest='interface', help='Interface to change its MAC addr')
    parser.add_option('-m', '--mac', dest='new_mac', help='New MAC addr')

    (options, arguments) = parser.parse_args()

    if not options.interface:
        parser.error('[!] Please specify an interface, use --help for more info.')
    elif not options.new_mac:
        parser.error('[!] Please specify a MAC, use --help for more info.')

    return options

Cambia la MAC por la que hemos establecido:

def change_mac(interface, new_mac):
    print('Changing MAC address form {} to {}'.format(interface, new_mac))
    subprocess.call(['ifconfig', interface, 'hw', 'ether', new_mac])

Para la interfaz de red seleccionada para poder cambiar la MAC:

def down_interface(interface):
    print('Turning off network interface: {}'.format(interface))
    subprocess.call(['ifconfig', interface, 'down'])

Levanta la unidad de red seleccionada:

def up_interface(interface):
    print('Turning on network interface: {}'.format(interface))
    subprocess.call(['ifconfig', interface, 'up'])

Función principal, lo primero que hace (línea 2) es comprobar que seamos root, después inicia el procedimiento de cambio de MAC usando las funciones que hemos descrito anteriormente:

if __name__ == "__main__":
    if os.geteuid() == 0:  # Check super user
        options = get_arguments()
        current_mac = get_current_mac(options.interface)

        down_interface(options.interface)

        print('Current MAC: {}'.format(current_mac))
        change_mac(options.interface, options.new_mac)

        up_interface(options.interface)

        if current_mac != options.new_mac:
            print('MAC address was succesfully changed to {}'.format(options.new_mac))
        else:
            raise Exception('It was not possible to change the MAC address')
    else:
        raise Exception('Pemission denied')

Y este sería el código completo:

import subprocess
import optparse
import re
import os


def get_current_mac(interface):
    ifconfig = subprocess.check_output(['ifconfig', interface])
    mac_address = re.search(r'\w\w:\w\w:\w\w:\w\w:\w\w:\w\w', str(ifconfig))

    if mac_address:
        return mac_address.group(0)

    raise Exception('Sorry, MAC address not found')


def get_arguments():
    parser = optparse.OptionParser()

    parser.add_option('-i', '--interface', dest='interface', help='Interface to change its MAC addr')
    parser.add_option('-m', '--mac', dest='new_mac', help='New MAC addr')

    (options, arguments) = parser.parse_args()

    if not options.interface:
        parser.error('[!] Please specify an interface, use --help for more info.')
    elif not options.new_mac:
        parser.error('[!] Please specify a MAC, use --help for more info.')

    return options


def change_mac(interface, new_mac):
    print('Changing MAC address form {} to {}'.format(interface, new_mac))
    subprocess.call(['ifconfig', interface, 'hw', 'ether', new_mac])


def down_interface(interface):
    print('Turning off network interface: {}'.format(interface))
    subprocess.call(['ifconfig', interface, 'down'])


def up_interface(interface):
    print('Turning on network interface: {}'.format(interface))
    subprocess.call(['ifconfig', interface, 'up'])


if __name__ == "__main__":
    if os.geteuid() == 0:  # Check super user
        options = get_arguments()
        current_mac = get_current_mac(options.interface)

        down_interface(options.interface)

        print('Current MAC: {}'.format(current_mac))
        change_mac(options.interface, options.new_mac)

        up_interface(options.interface)

        if current_mac != options.new_mac:
            print('MAC address was succesfully changed to {}'.format(options.new_mac))
        else:
            raise Exception('It was not possible to change the MAC address')
    else:
        raise Exception('Pemission denied')

¿Cómo lo ejecutamos?

Primero tenemos que cambiar al usuario root para no tener problemas de permisos. Basta con ejecutar el comando:

$ sudo su

Si queremos ver la ayuda:

$ python3 main.py -h

Nos saldrá lo siguiente:

Mostrando la ayuda del script

Para cambiar la dirección MAC por la que nosotros queramos:

$ python3 main.py -i eth0 -m 08:00:27:90:18:79

eth0 es la interfaz que hemos visto al principio, a esta interfaz le cambiaremos la MAC por la que especificamos en el comando -m (08:00:27:90:18:79).

El resultado sería el siguiente:

Como vemos, estos son los pasos que ha seguido el programa:

  1. Apaga la interfaz de red etch0
  2. Dice cuál es nuestra MAC actual
  3. Cambia la dirección MAC
  4. Vuelve a levantar la unidad de red
  5. Nos avisa de que el cambio está hecho

En este repositorio de GitHub está el proyecto completo.

Publicado por Fj Asensi

BigData & MachineLearning Developer | Senior Microsoft Dynamics 365 Business Central Developer

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

A %d blogueros les gusta esto: