blog.kanbach.org

IT-Security and stuff

How to permanently change a MAC address using ethtool

Changing the MAC address of a network interface can be a common task if you either change addresses for privacy reasons or if you're performing security assessments.

If you're using a Linux-based operating system, this can be done using one of the following commands:

ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx

macchanger-ng --mac xx:xx:xx:xx:xx:xx eth0

ip link set eth0 address xx:xx:xx:xx:xx:xx

While these changes are only temporary, it's also possible to instruct the operating system to set the MAC address straight after booting, for example by modifying files like /etc/network/interfaces.

But still, these changes would only apply to the current operating system and is not bound to the hardware itself. In this post I will demonstrate a method how to set the MAC address of an ethernet device permanently, so that even if you connect the device to another computer, it still uses the modifies MAC address. This will be achieved using ethtool. But let's have a look at some basic ethtool commands first:

Brief explanation of ethtool

Ethtool comes in handy when you want to debug your network interfaces. It can help to determine whether you are connected to a network or not, what the speed of the link is and if auto-negotiation is enabled.

For some basic information about a network interface, just call ethtool without command line arguments:

$ sudo ethtool eth0
Settings for eth0:
    Supported ports: [ TP ]
    Supported link modes:   10baseT/Half 10baseT/Full 
                            100baseT/Half 100baseT/Full 
                            1000baseT/Full 
    Supported pause frame use: No
    Supports auto-negotiation: Yes
    Supported FEC modes: Not reported
    Advertised link modes:  1000baseT/Full 
    Advertised pause frame use: No
    Advertised auto-negotiation: Yes
    Advertised FEC modes: Not reported
    Speed: 1000Mb/s
    Duplex: Full
    Port: Twisted Pair
    PHYAD: 2
    Transceiver: internal
    Auto-negotiation: on
    MDI-X: on (auto)
    Supports Wake-on: pumbg
    Wake-on: g
    Current message level: 0x00000007 (7)
                   drv probe link
    Link detected: yes

As you can see, the link is detected, the speed is set to 1000Mb/s and Auto-negotiation is enabled.

If you want to find out more details about the driver your interface is using, just add the -i argument:

$ sudo ethtool -i eth0
driver: asix
version: 22-Dec-2011
firmware-version: ASIX AX88772B USB 2.0 Ethernet
expansion-rom-version: 
bus-info: usb-0000:00:14.0-2
supports-statistics: no
supports-test: no
supports-eeprom-access: yes
supports-register-dump: no
supports-priv-flags: no

In this case, my interface is using the asix driver. By the way, for this example I used a USB-to-Ethernet adapter.

Obtaining the current MAC address and changing it permanently

First, let's have a look at the current MAC address:

$ ip a show dev eth0
9: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 00:50:b6:33:c5:e5 brd ff:ff:ff:ff:ff:ff

So, how could the MAC address 00:50:b6:33:c5:e5 be permanently changed to 00:11:22:33:44:55?

Retrieving an EEPROM dump from the network interface

By writing directly to the EEPROM of the network device, it is possible to change the MAC address.

!! CAUTION !! Writing to the EEPROM of the network device could brick the device. Before you actually write to the EEPROM, you should backup the original EEPROM

To retrieve the current EEPROM content, you can use ethtool again:

$ ethtool -e eth0
Offset		Values
------		------
0x0000:		15 5a ec 75 20 12 29 27 00 50 b6 33 c5 e5 09 04 
0x0010:		60 22 71 12 19 0e 3d 04 3d 04 3d 04 3d 04 80 05 
0x0020:		00 06 10 e0 42 24 40 12 49 27 ff ff 00 00 ff ff 
0x0030:		c0 09 0e 03 31 00 31 00 43 00 34 00 45 00 34 00 
0x0040:		12 01 00 02 ff ff 00 40 95 0b 2b 77 01 00 01 02 
0x0050:		03 01 09 02 27 00 01 01 04 a0 64 09 04 00 00 03 
0x0060:		ff ff 00 07 07 05 81 03 08 00 0b 07 05 82 02 00 
0x0070:		02 00 07 05 03 02 00 02 00 ff 04 03 30 00 ff ff 
0x0080:		12 01 00 02 ff ff 00 08 95 0b 2b 77 01 00 01 02 
0x0090:		03 01 09 02 27 00 01 01 04 a0 64 09 04 00 00 03 
0x00a0:		ff ff 00 07 07 05 81 03 08 00 a0 07 05 82 02 40 
0x00b0:		00 00 07 05 03 02 40 00 00 dd ff ff aa aa bb bb 
0x00c0:		22 03 41 00 53 00 49 00 58 00 20 00 45 00 6c 00 
0x00d0:		65 00 63 00 2e 00 20 00 43 00 6f 00 72 00 70 00 
0x00e0:		2e 00 12 03 41 00 58 00 38 00 38 00 37 00 37 00 
0x00f0:		32 00 42 00 ff ff ff ff ff ff ff ff ff ff ff ff 
0x0100:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x0110:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x0120:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x0130:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x0140:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x0150:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x0160:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x0170:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x0180:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x0190:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x01a0:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x01b0:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x01c0:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x01d0:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x01e0:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
0x01f0:		ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

As you can see, ethtool returns some hex-encoded binary data, which represents the EEPROM content of the ASIX USB-to-Ethernet device. The 9th byte in the first row (offset 0x08) is the first byte of the MAC address. Before you proceed, this is the dump that you should store somewhere in order to have a backup in case the modification will cause issues. If you want to store an unencoded plain dump, just add the raw on argument:

$ ethtool -e eth0 raw on > eeprom-backup.bin

Modifying the MAC address

Before the new MAC address is set, you should make sure that the offsets are correct. As shown above -e will print the EEPROM content to the screen. If you use -E instead, it's possible to write values to the EEPROM.

Let's check the offsets first:

$ ethtool -e eth0 offset 0x08 length 6
Offset		Values
------		------
0x0008:		00 50 b6 33 c5 e5

Offset 0x08 seems to be correct, the output above shows exactly the current MAC address of the device.

In order to write to the EEPROM, ethtool can be called as follows:

$ ethtool -E eth0 magic <N> offset <N> value <N>

As you can see, there is an additional command line argument, beginning with magic. This magic value is a vendor specific value that needs to be added to the command in order to write to the EEPROM. This value should prevent accidental writes to the EEPROM. For Asix devices the value can be obtained from the Linux kernel source code (see asix.h):

...
#define AX_EEPROM_MAGIC	0xdeadbeef
...

Now we know the magic value and can fire off some commands:

$ ethtool -E eth0 magic 0xdeadbeef offset 0x08 value 0x00
$ ethtool -E eth0 magic 0xdeadbeef offset 0x09 value 0x11
$ ethtool -E eth0 magic 0xdeadbeef offset 0x0a value 0x22
$ ethtool -E eth0 magic 0xdeadbeef offset 0x0b value 0x33
$ ethtool -E eth0 magic 0xdeadbeef offset 0x0c value 0x44
$ ethtool -E eth0 magic 0xdeadbeef offset 0x0d value 0x55

Afterwards ethtool is invoked again to see whether all values were written correctly:

$ ethtool -e eth0 offset 0x08 length 6
Offset		Values
------		------
0x0008:		00 11 22 33 44 55

It seems that all values are written correctly. Now let's check the output of ip after unplugging the USB-to-Ethernet adapter and plugging it back in:

$ ip a show dev eth0
10: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ff

Excellent! The MAC address has permanently changed; check this on another computer as well and you will see that the MAC address is now stored within the device's EEPROM and not just within the memory of the operating system.

Sometimes the EEPROM of Ethernet devices could contain a checksum that needs to be adjusted after changing the MAC address. If you want to change your hardware address, check the according manual before and take care that you have a proper backup available if something goes wrong.

Have fun