Created
December 13, 2016 21:26
-
-
Save pbadeer/3297e6bc5e8a77a2f84307c66410aa06 to your computer and use it in GitHub Desktop.
Mac Address Spoofer from Tails OS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Taken from https://git-tails.immerda.ch/tails/plain/config/chroot_local-includes/usr/local/lib/tails-spoof-mac | |
set -e | |
set -u | |
# This script spoofs or resets the MAC address of all NICs given as | |
# arguments according to the setting in Tails Greeter. The default (i.e | |
# before Tails Greeter has been run) is to enable MAC spoofing. | |
. /usr/local/lib/tails-shell-library/hardware.sh | |
. /usr/local/lib/tails-shell-library/log.sh | |
. /usr/local/lib/tails-shell-library/tails-greeter.sh | |
# Get LIVE_USERNAME | |
. /etc/live/config.d/username.conf | |
. /usr/bin/gettext.sh | |
TEXTDOMAIN="tails" | |
export TEXTDOMAIN | |
stop_and_disable_NM() { | |
for s in NetworkManager-dispatcher.service \ | |
NetworkManager-wait-online.service \ | |
NetworkManager.service; do | |
systemctl stop "${s}" | |
systemctl disable "${s}" | |
systemctl mask "${s}" | |
done | |
log "Networking disabled" | |
} | |
show_notification() { | |
# We must wait until all the facilities necessary for showing the | |
# notification to the Live user is available to prevent it from | |
# getting lost. | |
until pgrep -u "${LIVE_USERNAME}" '^ibus-daemon' >/dev/null ; do | |
sleep 1 | |
done | |
# The above doesn't seem to be enough. The best we can do seems to | |
# be to statically wait a bit longer. The amount chosen is just | |
# arbitrarily picked, and may not work on slow hardware or even | |
# DVD boot, but should at least work in our automated test suite. | |
sleep 10 | |
/usr/local/sbin/tails-notify-user "${1}" "${2}" 0 | |
} | |
notify_panic_success() { | |
local nic | |
local nic_name | |
nic="${1}" | |
nic_name="${2}" | |
show_notification "`gettext \"Network card \\\${nic} disabled\"`" \ | |
"`eval_gettext \"MAC spoofing failed for network card \\\${nic_name} (\\\${nic}) so it is temporarily disabled. | |
You might prefer to restart Tails and disable MAC spoofing.\"`" | |
} | |
notify_panic_failure() { | |
local nic | |
local nic_name | |
nic="${1}" | |
nic_name="${2}" | |
show_notification "`gettext \"All networking disabled\"`" \ | |
"`eval_gettext \"MAC spoofing failed for network card \\\${nic_name} (\\\${nic}). The error recovery also failed so all networking is disabled. | |
You might prefer to restart Tails and disable MAC spoofing.\"`" | |
} | |
mac_spoof_panic() { | |
local nic | |
local module | |
local nic_name | |
local unload_success | |
nic=${1} | |
if ! /sbin/ip link set dev "${nic}" down; then | |
log "Failed to down NIC ${nic} in panic mode." | |
fi | |
module=$(get_module_used_by_nic "${nic}") | |
nic_name="$(get_name_of_nic ${nic})" | |
echo "blacklist ${module}" >> /etc/modprobe.d/"${module}"-blacklist.conf | |
unload_module_and_rev_deps "${module}" || : | |
if nic_exists "${nic}"; then | |
log "Failed to unload module ${module} of NIC ${nic}." | |
stop_and_disable_NM | |
notify_panic_failure "${nic}" "${nic_name}" & | |
else | |
log "Successfully unloaded module ${module} of NIC ${nic}." | |
notify_panic_success "${nic}" "${nic_name}" & | |
fi | |
} | |
spoof_mac() { | |
local msg | |
set +e | |
msg="$(macchanger -e "${1}" 2>&1)" | |
ret="${?}" | |
set -e | |
if [ "${ret}" != 0 ]; then | |
log "macchanger failed for NIC ${1}, returned ${ret} and said: ${msg}" | |
return 1 | |
fi | |
} | |
set_log_tag spoof-mac | |
NIC="${1}" | |
if ! mac_spoof_is_enabled; then | |
exit 0 | |
fi | |
log "Trying to spoof MAC address of NIC ${NIC}..." | |
if ! nic_exists "${NIC}"; then | |
log "NIC ${NIC} doesn't exist, skipping" | |
exit 1 | |
fi | |
OLD_MAC="$(get_current_mac_of_nic "${NIC}")" | |
# There is a 1/2^24 chance macchanger will randomly pick the real MAC | |
# address. We try to making it really unlikely repeating it up to | |
# three times. Theoretically speaking this leaks information about the | |
# real MAC address at each occasion but actually leaking the real MAC | |
# address will be more serious in practice. | |
for i in 1 2 3; do | |
if ! spoof_mac "${NIC}"; then | |
# If our MAC spoofing primitive fails, we fail safe by forcing | |
# us to enter into panic mode. | |
unset NEW_MAC | |
break | |
fi | |
NEW_MAC="$(get_current_mac_of_nic "${NIC}")" | |
if [ "${OLD_MAC}" != "${NEW_MAC}" ]; then | |
break | |
fi | |
done | |
# MAC spoofing fail-safe: if $NIC's MAC address isn't spoofed at this | |
# point we have to take some drastic measures in order to prevent | |
# potential leaks. | |
if [ -z "${OLD_MAC:-}" ] || [ -z "${NEW_MAC:-}" ] || \ | |
[ "${OLD_MAC:-}" = "${NEW_MAC:-}" ] | |
then | |
log "Failed to spoof MAC address of NIC ${NIC}. Going into panic mode." | |
if ! mac_spoof_panic "${NIC}"; then | |
# If mac_spoof_panic() fails we're quite screwed, so we kill | |
# NetworkManager without notification to do our best to | |
# prevent a MAC address leak. | |
log "Panic mode failed for NIC ${NIC}." | |
stop_and_disable_NM | |
fi | |
exit 1 | |
fi | |
log "Successfully spoofed MAC address of NIC ${NIC}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment