macchanger icon indicating copy to clipboard operation
macchanger copied to clipboard

macOS Sonoma 14.4 broke macchanger, and ifconfig!? wtfh

Open artkiver opened this issue 1 year ago • 50 comments

I already submitted Feedback to Apple, but figured I would report things here too in case someone may discover a workaround.

macchanger worked without issues on macOS 14.3.1.

After updating to 14.4:

% sudo macchanger -r en0                         
Password:
INFO:    Type of interface is Wi-Fi. Will disassociate from any network.
WARNING: The airport command line tool is deprecated and will be removed in a future release.
For diagnosing Wi-Fi related issues, use the Wireless Diagnostics app or wdutil command line tool.
ERROR:   This device / interface has no MAC address to set.

Worse, this doesn't seem to be unique to macchanger; ifconfig seems broken on macOS 14.4 Sonoma as well:

sudo ifconfig en0 ether 10:93:e8:37:38:39
ifconfig: ioctl (SIOCAIFADDR): Can't assign requested address
adomino@MBAm2starhikari ~ % sudo ifconfig en0 ether de:ad:be:ef:de:ad
ifconfig: ioctl (SIOCAIFADDR): Can't assign requested address

Tested as broken on two Apple Silicon devices which previously functioned OK with macchanger on 14.3.1.

artkiver avatar Mar 12 '24 21:03 artkiver

Thanks for reporting this issue! I just upgraded to Sonoma 14.4.1 and can confirm the issue.
This appears to be a problem with the airport command line tool as it doesn't disassociate from the network. You can manually disconnect from the Wi-Fi network and then run macchanger which works.

shilch avatar Mar 26 '24 16:03 shilch

I tried to find an alternative to the airport command and came up with the following snippet that imitates IO80211.framework. Some information can also be found here.

It would be great if you could test if this code correctly performs disassociation from Wi-Fi. If you have access to older versions of macOS it would also be great to have a positive sign that they are working there.

The below code can be compiled using clang -o disassoc ./disassoc.c.

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

int main(int argc, char** argv) {
    int fd = socket(AF_INET, SOCK_DGRAM, 0);

    struct io80211_ioctl {
        char     ifname[16];
        uint64_t type;
        uint32_t length;
        void*    data;
    } ioc;
    strcpy(ioc.ifname, "en0");
    ioc.type = 22;
    ioc.length = 0;
    ioc.data = NULL;

    int res = ioctl(fd, 0x802869c8, &ioc);
    if(res == -1) {
        perror("ioctl");
        return res;
    }
    return 0;
}

shilch avatar Mar 26 '24 20:03 shilch

Genius, how did you even pull this? Works now !

DarkNero69 avatar Apr 03 '24 04:04 DarkNero69

Genius, how did you even pull this? Works now !

Great to hear that, @DarkNero69. Do you have the possibility to test the code on an older system?

shilch avatar Apr 04 '24 18:04 shilch

Genius, how did you even pull this? Works now !

Great to hear that, @DarkNero69. Do you have the possibility to test the code on an older system?

Hey, sorry for the delayed reply. Unfortunately i don't have another computer or any other system. I only got macbook air m1 :/ but this can easily be tested in public computers, though i don't have the time to hit up library at the moment haha

DarkNero69 avatar Apr 07 '24 10:04 DarkNero69

@shilch The fix is tested to be working on my MBP 13-inch, 2020 running i5. Be sure to run it with sudo though.

axyklee avatar Apr 08 '24 03:04 axyklee

Thanks @aaronleetw, @DarkNero69!

I developed a new version that supports macOS Sonoma 14.4+ on branch v0.2-draft.

Please let me know if the new version does the job:

git clone -b v0.2-draft https://github.com/shilch/macchanger
cd macchanger
make
./macchanger

shilch avatar Apr 09 '24 11:04 shilch

@shilch Works on my end! Thank you for your work.

axyklee avatar Apr 10 '24 03:04 axyklee

@shilch It works for me too! I'm not very experienced with the terminal, but I managed to get it working hehe. Amazing work, thank you! It's much simpler and faster to use now =)

DarkNero69 avatar Apr 10 '24 04:04 DarkNero69

Thanks @aaronleetw, @DarkNero69!

I developed a new version that supports macOS Sonoma 14.4+ on branch v0.2-draft.

Please let me know if the new version does the job:

git clone -b v0.2-draft https://github.com/shilch/macchanger
cd macchanger
make
./macchanger

Thank you!

I've tested the new v0.2-draft branch on 14.3.1, 14.4 and 14.4.1 and it is functioning OK.

Attempting to build on OS X El Capitan 10.11.6 yields the following errors:

make macchanger.c:39:51: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void interface_get_ether(const interface_t iface, ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:40:51: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void interface_set_ether(interface_t iface, const ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:41:61: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void interface_get_permanent_ether(const interface_t iface, ether_addr_t* eth... ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:48:42: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void change_mac(interface_t iface, const ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:50:19: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void random_ether(ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:51:34: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? int ether_parse(const char* str, ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:52:35: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? const char* ether_to_string(const ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:65:5: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? ether_addr_t ether; ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:155:5: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? ether_addr_t ether, permanent_ether; ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:164:48: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void change_mac(const interface_t iface, const ether_addr_t* new_ether) { ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:165:5: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? ether_addr_t permanent_ether, old_ether, current_ether; ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:167:18: error: member reference base type 'const user_addr_t' (aka 'const unsigned long long') is not a structure or union if (new_ether->octet[0] & 1) { ~~~~~~~~~^ ~~~~~ macchanger.c:194:19: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void random_ether(ether_addr_t* ether) { ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:204:35: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union ssize_t n = read(fd, ether->octet + (ETHER_ADDR_LEN - to_read), ... ~~~~~^ ~~~~~ macchanger.c:213:10: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union ether->octet[0] &= 0xFE; ~~~~~^ ~~~~~ macchanger.c:219:34: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? int ether_parse(const char* str, ether_addr_t* ether) { ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:226:14: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union ether->octet[i] = 0; ~~~~~^ ~~~~~ macchanger.c:228:18: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union ether->octet[i] <<= 4; ~~~~~^ ~~~~~ macchanger.c:230:45: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union if(ch >= '0' && ch <= '9') ether->octet[i] |= (ch - '0'); ~~~~~^ ~~~~~ fatal error: too many errors emitted, stopping now [-ferror-limit=] 20 errors generated. make: *** [macchanger] Error 1

However, the previous macchanger.sh functions OK on El Capitan 10.11.6.

artkiver avatar Apr 15 '24 23:04 artkiver

I also noticed that on macOS versions with the v0.2-draft branch, when invoked without root privileges, it will fail to change the MAC address (expected behavior) but it will still disassociate from WiFi (I am not sure if this is desirable?).

artkiver avatar Apr 15 '24 23:04 artkiver

@shilch Hi there, the branch v0.2-draft didn't work on my macOS(Sonoma 14.4.1).

sudo ./macchanger -r en0
INFO:    Type of interface is Wi-Fi. Will disassociate from any network.
interface_set_ether: Can't assign requested address

geek4what avatar May 15 '24 01:05 geek4what

Thank you for this. It works with the wifi adapter on my M2 Macbook Air, Sonoma 14.5. But, it does not work with my Belkin USB-C ethernet adapter, i get the error message "interface_set_ether: Can't assign requested address". Any leads?

nilssonalex avatar May 27 '24 10:05 nilssonalex

Hello. Sorry i haven't been replied to anything yet. First of all, thank you so much for developing such an amazing thing!

I haven't changed my mac address lately, but i just tested it by typing "sudo macchanger" to terminal. It seems like it works, managed to change to some random mac address. Thanks!

DarkNero69 avatar May 28 '24 17:05 DarkNero69

Sorry for not responding in a while.

@artkiver The compilation error occurs because the ether_addr_t did not exist in El Capitan. That should be an easy fix which I will add.

@geek4what Which device are you using? Is the en0 an Airport device?

@nilssonalex The tool uses the interface APIs provided by the operating system. If the network driver for this 3rd party device does not implement the possibility to change the mac address, there's nothing that macchanger can do. You would need a driver which has this feature.

shilch avatar May 28 '24 19:05 shilch

The v0.2-draft is also working for me, thanks!

fharper avatar May 28 '24 19:05 fharper

Sorry for not responding in a while.

@geek4what Which device are you using? Is the en0 an Airport device?

wifi en0. By the way, after upgrade to 14.5, it's work like a charm.

geek4what avatar May 29 '24 02:05 geek4what

For wifi this works great. However, if I try to change the mac address of a wired network, I still get the following error: sh-3.2# ./macchanger -m [mac] en17 interface_set_ether: Can't assign requested address

I use 14.5. The interface is listed as a USB 10/100/1000 device.

johndekroon avatar Jun 05 '24 13:06 johndekroon

@shilch Hi there, the branch v0.2-draft didn't work on my macOS(Sonoma 14.4.1).

sudo ./macchanger -r en0
INFO:    Type of interface is Wi-Fi. Will disassociate from any network.
interface_set_ether: Can't assign requested address

It's because macchanger can't disassociate from the wifi network. Disconnect from wifi yourself, then run macchanger and it will work. Tested on M1 Max MBP running macOS 15 Sequoia beta

dennis777 avatar Jun 12 '24 04:06 dennis777

I tried to find an alternative to the airport command and came up with the following snippet that imitates IO80211.framework. Some information can also be found here.

It would be great if you could test if this code correctly performs disassociation from Wi-Fi. If you have access to older versions of macOS it would also be great to have a positive sign that they are working there.

The below code can be compiled using clang -o disassoc ./disassoc.c.

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

int main(int argc, char** argv) {
    int fd = socket(AF_INET, SOCK_DGRAM, 0);

    struct io80211_ioctl {
        char     ifname[16];
        uint64_t type;
        uint32_t length;
        void*    data;
    } ioc;
    strcpy(ioc.ifname, "en0");
    ioc.type = 22;
    ioc.length = 0;
    ioc.data = NULL;

    int res = ioctl(fd, 0x802869c8, &ioc);
    if(res == -1) {
        perror("ioctl");
        return res;
    }
    return 0;
}

Sadly this didn't work for me in macOS 15 beta (I never tried on macOS 14)

dennis777 avatar Jun 12 '24 04:06 dennis777

v0.2-draft, Macbook Pro 16 2021 M1 Pro

works fine for wifi en0, but for en4

sudo ./macchanger -r en4
interface_set_ether: Can't assign requested address

USB 10/100/1000 LAN:

Bus: USB Vendor Name: Realtek Product Name: USB 10/100/1000 LAN Vendor ID: 0x0bda Product ID: 0x8153 USB Link Speed: Up to 5 Gb/s Driver: com.apple.DriverKit.AppleUserECM BSD Device Name: en4 MAC Address: 00:e0:4c:cc:3f:7d AVB Support: No

ASolod82 avatar Jun 12 '24 20:06 ASolod82

Just so I can understand correctly, with nothing plugged into your Mac (no hardwire internet connections, or network adapters), you can run sudo./macchanger -r en0 while the MacBook is connected to a wireless network? Meaning it disassociates, changes the MAC address, and then reconnects?

Thanks

dennis777 avatar Jun 12 '24 21:06 dennis777

Just so I can understand correctly, with nothing plugged into your Mac (no hardwire internet connections, or network adapters), you can run sudo./macchanger -r en0 while the MacBook is connected to a wireless network? Meaning it disassociates, changes the MAC address, and then reconnects?

Thanks

image

Meaning, I just reconnected my wifi using new mac address. But it doesn't work for my type-c ethernet adapter :( image

ASolod82 avatar Jun 12 '24 21:06 ASolod82

Were you connected to wifi on en0 before you ran the command? And what does it show you when you run en4?

dennis777 avatar Jun 13 '24 00:06 dennis777

@johndekroon @dennis777 @ASolod82 Thanks for your tests!

Can you please check if it works / there are errors for the following cases:

  • Using the v0.2-draft version
  • Using the master version but disassociating using this snippet
  • Using the master version but disassociating using the macOS UI

shilch avatar Jul 05 '24 15:07 shilch

Certainly! Here are the results tested on my 21 MacBook Pro M1 Max macOS 15.0 beta (shouldn't be any different for 14 as airport is deprecated there as well)

Using the v0.2-draft version

Result: Does not disassociate from wifi, thus not changing the Mac address Screenshot 2024-07-08 at 10 12 14 Manually disassociating, works just fine image

Using the master version but disassociating using this snippet

Result: does not disassociate but prints a message

ioctl: Operation not supported on socket

So then as expected, the macchanger doesn't work because it doesn't disassociate using that snippet image

seems like ioctl() call isn't working in disassoc.c

Using the master version but disassociating using the macOS UI

Result: Works perfectly fine image

Hope this helps! Let me know if theres anything else I can test @shilch

dennis777 avatar Jul 08 '24 17:07 dennis777

Thanks @dennis777, I guess that Apple changed the interface to disassociate WiFi in one of the recent versions ("Operation not supported on socket" hints at an API change). I am currently using 14.4.1 on M1 Pro and v0.2-draft works for me. User @geek4what had issues on 14.4.1 but upgrading to 14.5 fixed it, apparently. I assume that issue affects macOS 15.0+.
The solution could be to implement the disassociation using IOKit instead of ioctl. The headers have been leaked here. Once I'm less busy with university, I'll have a look at it.

shilch avatar Jul 08 '24 18:07 shilch

Ah okay I didn't know about this tool until after I updated to the beta.

I will play around with those dumped headers and see if I can come up with anything in the meantime. But my experience with C is extremely limited. I wish I understood it better 😅 Thank you

dennis777 avatar Jul 08 '24 18:07 dennis777

The v0.2-draft version worked fine. I am on 14.5 (Macbook Air)

Is it possible to make it installable by brew?

Also the git clone https://github.com/shilch/macchanger command in the readme does not clone the v0.2-draft.. You should adjust it to git clone -b v0.2-draft https://github.com/shilch/macchanger

ldoench avatar Aug 11 '24 13:08 ldoench

The v0.2-draft version worked fine.

Which model of Mac do you use and what version of macOS?

dennis777 avatar Aug 11 '24 17:08 dennis777