#!/bin/zsh # Advanced Wi-Fi MAC spoofing script for macOS # Automatically detects phone hotspot MAC or allows manual input # Usage: # spoof-wifi-mac.sh # auto-detect connected hotspot MAC # spoof-wifi-mac.sh --phone-mac # detect phone MAC from hotspot # spoof-wifi-mac.sh AA:BB:CC:DD:EE:FF # set specific MAC # spoof-wifi-mac.sh --revert # restore original MAC set -euo pipefail # Get absolute path to script if [ -n "${ZSH_VERSION:-}" ]; then SCRIPT_PATH="${0:A}" else SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" fi # Fallback if still empty if [ -z "$SCRIPT_PATH" ] || [ ! -f "$SCRIPT_PATH" ]; then SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" fi STATE_FILE="/tmp/wifi_mac_spoof_state" ORIGINAL_MAC_FILE="/tmp/wifi_mac_original" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color require_root() { if [ "$EUID" -ne 0 ] && [ "$(id -u)" -ne 0 ]; then echo -e "${YELLOW}Re-running with sudo...${NC}" exec sudo -E "$0" "${@}" fi } detect_wifi_if() { local iface iface=$(networksetup -listallhardwareports | awk '/Wi-Fi/{getline; print $2; exit}') if [ -z "$iface" ]; then echo -e "${RED}Error: Could not detect Wi-Fi interface${NC}" exit 1 fi echo "$iface" } get_current_mac() { local iface="$1" ifconfig "$iface" 2>/dev/null | awk '/ether/{print $2; exit}' || echo "" } get_connected_network() { local iface="$1" /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I 2>/dev/null | awk '/ SSID:/ {print substr($0, index($0,$2))}' || echo "" } get_connected_bssid() { local iface="$1" /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I 2>/dev/null | awk '/ BSSID:/ {print $2}' || echo "" } detect_phone_hotspot_mac() { local iface="$1" local bssid echo -e "${BLUE}Detecting connected hotspot MAC...${NC}" bssid=$(get_connected_bssid "$iface") if [ -z "$bssid" ] || [ "$bssid" = "none" ]; then echo -e "${YELLOW}Warning: Not connected to Wi-Fi or cannot detect BSSID${NC}" return 1 fi echo -e "${GREEN}Found hotspot BSSID: $bssid${NC}" echo "$bssid" return 0 } validate_mac() { local mac="$1" if ! [[ "$mac" =~ ^([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}$ ]]; then echo -e "${RED}Invalid MAC format: $mac (expected AA:BB:CC:DD:EE:FF)${NC}" exit 1 fi } power_wifi() { local iface="$1" local state="$2" # on|off networksetup -setairportpower "$iface" "$state" 2>/dev/null || true sleep 1 } save_original_mac() { local iface="$1" local mac="$2" if [ ! -f "$ORIGINAL_MAC_FILE" ]; then echo "$iface|$mac" > "$ORIGINAL_MAC_FILE" echo -e "${GREEN}Saved original MAC for permanent restore: $mac${NC}" fi } check_sip_status() { local sip_status sip_status=$(csrutil status 2>/dev/null | grep -i "enabled" || echo "unknown") if [[ "$sip_status" == *"enabled"* ]]; then return 0 # SIP enabled else return 1 # SIP disabled or unknown fi } set_mac() { local iface="$1" local mac="$2" local current_mac current_mac=$(get_current_mac "$iface") if [ -z "$current_mac" ]; then echo -e "${RED}Error: Cannot read current MAC address${NC}" exit 1 fi echo -e "${BLUE}Current MAC: $current_mac${NC}" echo -e "${BLUE}Target MAC: $mac${NC}" if [ "$current_mac" = "$mac" ]; then echo -e "${YELLOW}MAC already set to target value${NC}" return 0 fi # Check SIP status if check_sip_status; then echo -e "${YELLOW}⚠ System Integrity Protection (SIP) is enabled${NC}" echo -e "${YELLOW}MAC spoofing may be blocked on Apple Silicon with SIP enabled${NC}" fi # Save original MAC if not saved save_original_mac "$iface" "$current_mac" # Save for revert echo "$iface $current_mac" > "$STATE_FILE" echo -e "${YELLOW}Turning Wi-Fi off...${NC}" power_wifi "$iface" off echo -e "${YELLOW}Setting MAC to $mac...${NC}" # Try ifconfig method local success=false if ifconfig "$iface" ether "$mac" 2>/dev/null; then success=true fi if [ "$success" = false ]; then echo -e "${RED}✗ Error: Failed to set MAC address${NC}" echo "" echo -e "${BLUE}=== РЕШЕНИЕ ПРОБЛЕМЫ ===${NC}" echo "" if check_sip_status; then echo -e "${YELLOW}На Apple Silicon (M1/M2/M3) с включенным SIP подмена MAC заблокирована${NC}" echo "" echo -e "${YELLOW}Варианты решения:${NC}" echo "1. Отключить SIP (НЕ рекомендуется - снижает безопасность)" echo " - Перезагрузите в Recovery Mode (Cmd+R)" echo " - Утилиты → Терминал → csrutil disable" echo " - Перезагрузите Mac" echo "" echo "2. Использовать альтернативные методы:" echo " • VPN на телефоне (рекомендуется)" echo " • USB Tethering вместо Wi-Fi hotspot" echo " • Bluetooth Tethering" echo "" echo -e "${BLUE}Важно:${NC}" echo "Оператор сотовой связи видит IMEI телефона, а не MAC MacBook." echo "MAC клиента виден только на уровне локальной Wi-Fi сети." echo "Подмена MAC не меняет идентификацию на уровне оператора." else echo -e "${YELLOW}Интерфейс может не поддерживать подмену MAC${NC}" echo -e "${YELLOW}Или требуется дополнительная настройка${NC}" fi power_wifi "$iface" on exit 1 fi echo -e "${YELLOW}Turning Wi-Fi on...${NC}" power_wifi "$iface" on sleep 2 local new_mac new_mac=$(get_current_mac "$iface") if [ "$new_mac" = "$mac" ]; then echo -e "${GREEN}✓ Success! MAC changed to: $new_mac${NC}" else echo -e "${RED}⚠ Warning: MAC may not have changed${NC}" echo -e "${YELLOW}Current MAC: $new_mac${NC}" echo -e "${YELLOW}Target MAC: $mac${NC}" echo -e "${YELLOW}This may require disabling SIP or using a different method${NC}" fi } revert_mac() { local iface local original_mac if [ -f "$STATE_FILE" ]; then read iface original_mac < "$STATE_FILE" elif [ -f "$ORIGINAL_MAC_FILE" ]; then local saved saved=$(cat "$ORIGINAL_MAC_FILE") iface=$(echo "$saved" | cut -d'|' -f1) original_mac=$(echo "$saved" | cut -d'|' -f2) else echo -e "${RED}No saved MAC found. Cannot revert.${NC}" exit 1 fi if [ -z "${iface:-}" ] || [ -z "${original_mac:-}" ]; then echo -e "${RED}State file is corrupted. Delete $STATE_FILE and $ORIGINAL_MAC_FILE${NC}" exit 1 fi echo -e "${BLUE}Restoring MAC for $iface to $original_mac...${NC}" power_wifi "$iface" off ifconfig "$iface" ether "$original_mac" 2>/dev/null || { echo -e "${RED}Failed to restore MAC${NC}" power_wifi "$iface" on exit 1 } power_wifi "$iface" on sleep 2 rm -f "$STATE_FILE" local current current=$(get_current_mac "$iface") echo -e "${GREEN}✓ Reverted. Current MAC: $current${NC}" } show_instructions() { echo -e "${BLUE}=== ИНСТРУКЦИИ ПО ПОЛУЧЕНИЮ MAC ТЕЛЕФОНА ===${NC}" echo "" echo -e "${YELLOW}iPhone:${NC}" echo "1. Настройки → Wi-Fi" echo "2. Нажмите (i) рядом с сетью" echo "3. Отключите 'Частный Wi-Fi адрес' (Private Wi-Fi Address)" echo "4. MAC-адрес будет показан как 'Адрес Wi-Fi'" echo "" echo -e "${YELLOW}Android:${NC}" echo "1. Настройки → О телефоне → Статус" echo "2. Найдите 'MAC-адрес Wi-Fi'" echo "" echo -e "${YELLOW}Альтернативный способ (если подключены к hotspot):${NC}" echo "Скрипт может автоматически определить MAC точки доступа" echo "Используйте: $0 --phone-mac" echo "" } main() { # Check if we need root and restart with sudo if needed # Skip check for help/instructions commands that don't need root local arg="${1:-}" local needs_root=false if [ "$arg" != "--help" ] && [ "$arg" != "-h" ] && [ "$arg" != "--instructions" ]; then needs_root=true fi if [ "$needs_root" = true ] && [ "$(id -u)" -ne 0 ]; then echo -e "${YELLOW}Re-running with sudo...${NC}" exec sudo -E "$SCRIPT_PATH" "${@}" exit 0 fi if [ "$arg" = "--help" ] || [ "$arg" = "-h" ]; then echo "Usage: $0 [OPTIONS] [MAC_ADDRESS]" echo "" echo "Options:" echo " --phone-mac Auto-detect phone hotspot MAC" echo " --revert Restore original MAC" echo " --instructions Show instructions for finding phone MAC" echo " --help Show this help" echo "" echo "Examples:" echo " $0 # Interactive mode" echo " $0 --phone-mac # Auto-detect hotspot MAC" echo " $0 AA:BB:CC:DD:EE:FF # Set specific MAC" echo " $0 --revert # Restore original" exit 0 fi if [ "$arg" = "--instructions" ]; then show_instructions exit 0 fi if [ "$arg" = "--revert" ]; then revert_mac exit 0 fi local iface iface=$(detect_wifi_if) echo -e "${GREEN}Wi-Fi interface: $iface${NC}" local target_mac="" if [ "$arg" = "--phone-mac" ]; then target_mac=$(detect_phone_hotspot_mac "$iface") if [ -z "$target_mac" ]; then echo -e "${RED}Could not detect phone hotspot MAC${NC}" echo -e "${YELLOW}Make sure you're connected to phone hotspot and try manual input${NC}" show_instructions exit 1 fi elif [ -n "$arg" ]; then target_mac="$arg" else # Try auto-detect first local detected detected=$(detect_phone_hotspot_mac "$iface" 2>/dev/null || echo "") if [ -n "$detected" ]; then echo -e "${GREEN}Detected hotspot MAC: $detected${NC}" read "confirm?Use this MAC? (y/n): " if [[ "$confirm" =~ ^[Yy] ]]; then target_mac="$detected" else read "target_mac?Enter phone Wi-Fi MAC (AA:BB:CC:DD:EE:FF): " fi else show_instructions read "target_mac?Enter phone Wi-Fi MAC (AA:BB:CC:DD:EE:FF): " fi fi if [ -z "$target_mac" ]; then echo -e "${RED}No MAC address provided${NC}" exit 1 fi validate_mac "$target_mac" set_mac "$iface" "$target_mac" echo "" echo -e "${BLUE}=== ВАЖНО ===${NC}" echo -e "${YELLOW}• MAC сбросится после перезагрузки или переподключения Wi-Fi${NC}" echo -e "${YELLOW}• Используйте '$0 --revert' для восстановления${NC}" echo -e "${YELLOW}• Для постоянной подмены может потребоваться отключение SIP${NC}" echo -e "${YELLOW}• Оператор видит трафик через точку доступа, MAC клиента виден только на уровне Wi-Fi${NC}" } main "$@"