|
#!/bin/bash
|
|
|
|
# Easily set up a spoofed MAC address to a network interface on systemd-based Linux systems.
|
|
# Based on: https://wiki.archlinux.org/index.php/MAC_address_spoofing#Method_1:_systemd-networkd
|
|
|
|
# Copyright: Pekka Helenius (~Fincer), 2018
|
|
|
|
# Randomizing/Modifying MAC address may disturb malicious ARP scans (device idenfitication) and may help circumventing MAC-based restrictions which may be present on the local network.
|
|
# Use only at your own risk. Spoofing MAC address may not be accepted in all situations, may be illegal and may cause legal troubles. You have been warned.
|
|
|
|
#genmac() {
|
|
|
|
trap ctrl_c INT
|
|
|
|
function ctrl_c() {
|
|
echo -e "\nAborting.\n"
|
|
exit
|
|
#return
|
|
}
|
|
|
|
random_mac() {
|
|
# Author: Aaron Toponce
|
|
# https://serverfault.com/questions/299556/how-to-generate-a-random-mac-address-from-the-linux-command-line/631119#631119
|
|
MAC=$(printf '%02x' $((0x$(od /dev/urandom -N1 -t x1 -An | cut -c 2-) & 0xFE | 0x02)); od /dev/urandom -N5 -t x1 -An | sed 's/ /:/g')
|
|
}
|
|
|
|
insert_mac() {
|
|
echo -e "\nChanging MAC address information (root permission required).\n"
|
|
|
|
sudo sed -i "/\[Link\]/!b;n;cMACAddress=$MAC" /etc/systemd/network/00-default.link
|
|
echo -e "MAC address changed from '$MAC_OLD' to '$MAC' for interface '$MAC_DEVICE'.\n\nPlease restart this interface to apply the changes.\n\nTo restore original MAC address, either delete configuration file '/etc/systemd/network/$linkname' or set real MAC address manually into it.\n"
|
|
exit 0
|
|
#return 0
|
|
}
|
|
|
|
geninsert_mac() {
|
|
|
|
gennew_mac() {
|
|
|
|
while true; do
|
|
unset response
|
|
read -r -p "Generate a new MAC address? [Y/n] " response
|
|
|
|
if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
|
random_mac
|
|
newname_mac
|
|
else
|
|
echo -e "\nKeeping old MAC address configuration.\n"
|
|
exit
|
|
#return
|
|
fi
|
|
done
|
|
}
|
|
|
|
newname_mac() {
|
|
unset response
|
|
read -r -p "New MAC address for '$MAC_DEVICE' will be '$MAC'. Accept? [Y/n] " response
|
|
|
|
if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
|
insert_mac
|
|
else
|
|
gennew_mac
|
|
fi
|
|
}
|
|
newname_mac
|
|
}
|
|
|
|
gen_mac() {
|
|
|
|
real_mac() {
|
|
|
|
AVAILABLE_MACS=$(ip -br link show | sed '/LOOPBACK/d' | awk '{print NR"\t"$1"\t"$3"\t"$2}')
|
|
|
|
IFS=$'\n'
|
|
|
|
echo -e "\nAvailable network interfaces with their MAC addresses are:\n\n${AVAILABLE_MACS[*]}"
|
|
|
|
echo -e "\nPlease select the interface which MAC address you want to spoof of\n"
|
|
read -r -p "Selection [number]: " number
|
|
|
|
if [[ ! $number =~ ^[0-9]+$ ]]; then
|
|
echo -e "\nInvalid input value. Aborting.\n"
|
|
exit 1
|
|
#return 1
|
|
fi
|
|
|
|
for INTERFACE in $(echo -e "${AVAILABLE_MACS[*]}"); do
|
|
|
|
intf_num=$(echo $INTERFACE | awk '{print $1}')
|
|
|
|
if [[ $number -eq $intf_num ]]; then
|
|
MAC_REAL=$(echo $INTERFACE | awk '{print $3}')
|
|
MAC_DEVICE=$(echo $INTERFACE | awk '{print $2}')
|
|
break
|
|
fi
|
|
done
|
|
unset IFS
|
|
|
|
if [[ $MAC_REAL == "" ]]; then
|
|
echo -e "\nNot a valid MAC address found for interface number $number. Aborting.\n"
|
|
exit 1
|
|
#return 1
|
|
fi
|
|
|
|
}
|
|
|
|
real_mac
|
|
|
|
PREV_CONF=$(grep -Ril "$MAC_REAL" /etc/systemd/network/ | grep -E "[0-9]{,2}\-default\.link$")
|
|
|
|
if [[ ! $(echo $PREV_CONF | wc -w) -eq 0 ]]; then
|
|
echo -e "\nUsing existing configuration file for interface '$MAC_DEVICE':\n$PREV_CONF\n"
|
|
linkname=$(basename $PREV_CONF)
|
|
MAC_OLD=$(awk -F= '/\[Link\]/{getline; print $2}' $PREV_CONF)
|
|
else
|
|
MAC_OLD=$MAC_REAL
|
|
echo -e "\nPrevious configuration file not found. Creating it (root permission required).\n"
|
|
read -r -p "Configuration file name? (must follow syntax: 00-default.link, 41-default.link, 98-default.link etc.): " linkname
|
|
|
|
if [[ "$linkname" =~ ^[0-9]{,2}\-default\.link$ ]]; then
|
|
|
|
if [[ ! $(sudo -n true) ]]; then
|
|
sudo echo ""
|
|
fi
|
|
|
|
echo -e "[Match]\nMACAddress=$MAC_REAL\n\n[Link]\nMACAddress=$MAC_REAL\nNamePolicy=kernel database onboard slot path" \
|
|
| sudo tee /etc/systemd/network/$linkname > /dev/null
|
|
|
|
echo -e "Created new configuration file: /etc/systemd/network/$linkname\n"
|
|
else
|
|
echo -e "\nInvalid file name given. Aborting.\n"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
unset response
|
|
echo -e "Either randomly generated or manually specified MAC address can be used.\n"
|
|
read -r -p "Do you want to use randomly generated MAC address? [Y/n] " response
|
|
|
|
if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
|
random_mac
|
|
geninsert_mac
|
|
else
|
|
|
|
if [[ $(echo $response | sed 's/ //g') =~ ^([nN][oO]|[nN])$ ]]; then
|
|
read -r -p "Please type a new MAC address (Syntax is e.g. aa:bb:33:zz:f0:4a): " MAC
|
|
maxtries=5
|
|
while [[ $maxtries -gt 0 ]]; do
|
|
|
|
case "$MAC" in
|
|
[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]])
|
|
insert_mac
|
|
;;
|
|
esac
|
|
unset MAC
|
|
read -r -p "Invalid MAC address given. Please type again ($maxtries tries left): " MAC
|
|
let maxtries--
|
|
done
|
|
else
|
|
echo -e "\nInvalid answer. Aborting.\n"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
echo -e "\nWARNING: Changing MAC address WILL DISRUPT connections to any network device using MAC-based authentication methods. These devices may include configured routers, WiFi hotspots etc. Remember to write down the new MAC address, and make sure you are authorized to configure the MAC address to all affected network devices if needed.\n"
|
|
read -r -p "You are going to spoof a MAC address of this computer. Are you sure? [Y/n] " response
|
|
|
|
if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
|
gen_mac
|
|
else
|
|
echo -e "\nKeeping old MAC address configuration.\n"
|
|
fi
|
|
|
|
#}
|