Il existe plusieurs façons de changer son adresse MAC sous GNU/Linux (macchanger étant la méthode la plus connue) mais l’avantage de ce qui va suivre c’est que cela se passera directement au niveau du noyau Linux ce qui a pour avantage d’être particulièrement efficace et sûr. Alors certes il faut compiler son petit noyau mais bon nous sommes tous des geeks barbus, non?
Brad nous a sorti un petit patch (hack) sympathique pour changer aléatoirement l’adresse MAC d’une interface réseau dès que celle-ci est activée 🙂
Ainsi à chaque démarrage de l’ordinateur, les adresses MAC changent de manière aléatoire tout comme elles changeront également à chaque redémarrage du service réseau.
Pour information, le patch ci-dessous n’est pas intégré dans grsec car ce n’est pas le but visé par le projet.
Voici le code qui va bien du path « random_mac.diff » :
diff --git a/net/core/dev.c b/net/core/dev.c
index 19d9b66..9a16733 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4823,6 +4823,24 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
rtmsg_ifinfo(RTM_NEWLINK, dev, changes);
__dev_notify_flags(dev, old_flags);
+
+ if ((changes & IFF_UP) && !(old_flags & IFF_UP)) {
+ /* randomize MAC whenever interface is brought up */
+ struct sockaddr sa;
+ unsigned int mac4;
+ unsigned short mac2;
+
+ mac4 = prandom_u32();
+ mac2 = prandom_u32();
+ memcpy(sa.sa_data, &mac4, sizeof(mac4));
+ memcpy((char *)sa.sa_data + sizeof(mac4), &mac2, sizeof(mac2));
+ if (!is_valid_ether_addr(sa.sa_data))
+ sa.sa_data[5] = 1;
+ sa.sa_data[0] &= 0xFC;
+ sa.sa_family = dev->type;
+ dev_set_mac_address(dev, &sa);
+ }
+
return ret;
}
EXPORT_SYMBOL(dev_change_flags);
@@ -4991,7 +5009,8 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
return dev_set_mtu(dev, ifr->ifr_mtu);
case SIOCSIFHWADDR:
– return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
+ /* ignore userland MAC changes */
+ return 0;
case SIOCSIFHWBROADCAST:
if (ifr->ifr_hwaddr.sa_family != dev->type)
Pour les noyaux égals ou supérieurs à la version 3.15, j’ai dû modifier le précédant patch pour qu’il fonctionne toujours avec les versions plus récentes:
diff --git a/net/core/dev.c b/net/core/dev.c
index a30bef1..7eb6778 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5476,6 +5476,24 @@ int dev_change_flags(struct net_device *dev, unsigned int flags)
changes = (old_flags ^ dev->flags) | (old_gflags ^ dev->gflags);
__dev_notify_flags(dev, old_flags, changes);
+
+ if ((changes & IFF_UP) && !(old_flags & IFF_UP)) {
+ /* randomize MAC whenever interface is brought up */
+ struct sockaddr sa;
+ unsigned int mac4;
+ unsigned short mac2;
+
+ mac4 = prandom_u32();
+ mac2 = prandom_u32();
+ memcpy(sa.sa_data, &mac4, sizeof(mac4));
+ memcpy((char *)sa.sa_data + sizeof(mac4), &mac2, sizeof(mac2));
+ if (!is_valid_ether_addr(sa.sa_data))
+ sa.sa_data[5] = 1;
+ sa.sa_data[0] &= 0xFC;
+ sa.sa_family = dev->type;
+ dev_set_mac_address(dev, &sa);
+ }
+
return ret;
}
EXPORT_SYMBOL(dev_change_flags);
diff –git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index cf999e0..265c2b3 100644
— a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -260,6 +260,8 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
case SIOCSIFHWADDR:
return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
+ /* ignore userland MAC changes */
+ return 0;
case SIOCSIFHWBROADCAST:
if (ifr->ifr_hwaddr.sa_family != dev->type)
Bonne compilation 😉
Cool. Moi qui cherchais un moyen super compliqué au lieu de faire simple….
Il l’a dit au début « ce qui a pour avantage d’être particulièrement efficace et sûr ». Ça peut-être utile pour Tails et les autres distributions conçu pour l’anonymat ou la vie privée.
Merci
Yep ! On peut également modifier l’adresse MAC de sa carte réseau à l’aide du script ci-dessus :
———————- Début du script ———————-
#!/bin/sh
# Définition de l’interface :
IFACE=$1
# On éteint l’interface :
ip link set dev $IFACE down
# On génère une fausse adresse MAC,
# puis on tente de l’attribuer à l’interface réseau.
# Cela peut échouer ; on génère alors une nouvelle adresse MAC.
# Et lorsqu’une adresse MAC a été attribuée avec succès
# à l’interface réseau, le processus s’arrête.
VARIABLE=1
while [ $VARIABLE != 0 ]
do FAUSSE_MAC=$(hexdump -n 6 -e ‘3/1 « :%x »‘ /dev/urandom | cut -b 2-20)
ip link set $IFACE address $FAUSSE_MAC 2>/dev/null
VARIABLE=$?;
done;
echo -n « L’adresse MAC de l’interface »
echo -n $IFACE
echo -n » est maintenant »
echo $FAUSSE_MAC
exit 0
———————- Fin du script ———————-
On utilise ce script en lui donnant l’interface réseau en argument :
$ script eth0
$ script wlan0
merci pour cet article c’est très intéressant