5

I've recently bought a Nexus 7 to use as a demo client for a system I am currently developing. For the time being, the system requires the client to have a particular MAC address in order to work. I've rooted the Nexus (still with the Android 4.4 stock ROM), and am using ip link to change the hardware address of wlan0. I am aware that this will be reset on reboot, but as I'd rather not recompile my Android kernel right now, that's okay.

The issue I am seeing is that I am unable to get an IP address from my (open) WiFi network with a modified MAC address. If I set a static IP, I can connect successfully with the modified address, but no packets are getting through.

Hopefully the below transcript will shed some light on exactly what isn't working and what I've tried.

First, I "forget" my WiFi connection and reboot my device just to start from scratch. Then:

$ adb shell
shell@flo:/ $ su
root@flo:/ # ip link | grep -A1 wlan0
22: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT qlen 100
    link/ether ac:22:0b:9f:37:f7 brd ff:ff:ff:ff:ff:ff
root@flo:/ # ip link set dev wlan0 addr ac:22:0b:9f:37:f0

Here, I connect to the wireless network. If DHCP is selected, I am simply shown "Obtaining IP address" until the connection fails. If I set a static IP, the network is shown as connected, but:

root@flo:/ # ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
From 192.168.1.113: icmp_seq=1 Destination Host Unreachable
From 192.168.1.113: icmp_seq=2 Destination Host Unreachable
^C
--- 192.168.1.1 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1004ms
pipe 2
1|root@flo:/ # ip route
default via 192.168.1.1 dev wlan0 
192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.113 
192.168.1.1 dev wlan0  scope link 
1|root@flo:/ # ip n
192.168.1.1 dev wlan0  INCOMPLETE
255|root@flo:/ # ip n change 192.168.1.1 lladdr 10:0D:7F:4D:1C:D0 dev wlan0
root@flo:/ # ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
^C
--- 192.168.1.1 ping statistics ---
7 packets transmitted, 0 received, 100% packet loss, time 6006ms

So, still no connection. Let's see what happens if I change my MAC address back to the real one without even disconnecting from the wireless network:

root@flo:/ # ip link set dev wlan0 addr ac:22:0b:9f:37:f7
root@flo:/ # ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=13.0 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=9.82 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=9.49 ms
^C
--- 192.168.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 9.491/10.793/13.061/1.609 ms

Does anyone have any idea what might be going on here?

For what it's worth, I am running DD-WRT on my router, no MAC filtering is enabled, and there should be no other "weird" rules set.

UPDATE: After some further investigation, I have noticed that it seems like the Nexus 7 isn't using the spoofed address at all when talking to my AP. I have enabled MAC filtering and only allowed the spoofed address, and then adb logcat shows a CTRL-EVENT-ASSOC-REJECT message. I'm wondering whether this might somehow be related to this wpa_supplicant question, but there weren't any answers to be had there either...

  • Do you have a possibility to check that from the routers side (logs or the like)? Have you tried whether adb logcat sheds some light? That's the only two things coming to my mind immediately (though there might be more, as e.g. using some analytic apps). – Izzy Nov 28 '13 at 20:35
  • adb logcat only says DHCP timeout with The spoofed MAC. The router gives very limited information unfortunately, – Jon Gjengset Nov 29 '13 at 0:01
  • Do you see the spoofed MAC in the ARP table? – Mr. Buster Nov 29 '13 at 4:36
  • No, the router's ARP table is not showing the spoofed MAC. In the "wireless clients" list, the device is also listed with its stock MAC when I force a connection with static IP. This seems to imply that the MAC isn't actually changing, but if that were the case, why is it not connecting? – Jon Gjengset Nov 29 '13 at 10:21
  • Is the static lease assigned to the stock MAC or spoof MAC? Does the arp table look the same if you clear the static lease, spoof the MAC on your device again, then reconnect? I don't think your device is building frames correctly after trying to spoof the MAC - if your router receives frames from your device with an incorrect or missing source MAC then it won't know how to talk back. That could explain why you see your device "connect" to the router (when it tries to claim the IP address) but you can't actually pass traffic. – Mr. Buster Nov 29 '13 at 21:51
2

After much searching, I came across this thread on the xda-developers forum where people seem to be having much of the same issue with a Nexus 4. After trying several of the proposed solutions in that thread, I came across one that worked!

It turns out that Android keeps a permanent record of the MAC in /persist/wifi/.macaddr. For some reason, it insists on using the MAC in that file whenever connecting to a wireless network. If you're on a rooted device, however, you can overwrite it with whatever MAC you want. Interestingly, this change will also persist across reboots!

So, without further ado, here's how you change the MAC permanently on an Android device (substitute 112233445566 with the MAC you want):

computer $ adb shell
android $ su
android # cd /persist/wifi
android # echo -n "112233445566" > .macaddr
android # ^D
android $ ^D
computer $ adb reboot
  • 1
    The .macaddr file does not contain characters. It contains 6 bytes that represent the MAC address. For example, if you want to change the MAC address you need to write the bytes 0x00 0x11 0x22 0x33 0x44 0x55 to the .macaddr file. You can do this in bash using: echo -e "\x00\x11\x22\x33\x44\x55" > /persist/wifi/.macaddr – Xample Nov 4 '14 at 22:53
  • That's interesting... On my device, it was necessary to use the ascii representation, not the hex... – Jon Gjengset Nov 5 '14 at 6:15
  • don't know why this answer is down voted, but it works actually, my phone is nexus 4 which is rooted. – wynemo Jul 10 '17 at 10:21
0

I don't think your device is actually changing the MAC. Static coding an IP on your router won't do you much good if you don't have L2 connectivity.

I had worked out a way to change the MAC on my 2012 N7 by using busybox and the ifconfig command. Try installing busybox, disconnecting from the WLAN, then running the following as root (substituting your MAC, of course).

busybox ifconfig wlan0 hw ether 00:00:00:00:00:00

busybox iplink show wlan0

Does that work for you?

  • Using ip link is effectively the same as using ifconfig, so I don't think that's what's doing it... – Jon Gjengset Nov 29 '13 at 0:00
  • Still, worth a shot. Worked for me. – Mr. Buster Nov 29 '13 at 3:27
  • Tried it now. Setting the MAC with ifconfig wlan0 hw ether produces the exact same behaviour unfortunately. – Jon Gjengset Nov 29 '13 at 10:23
0

Jon's answer about the hidden .macaddr gave me enough hint to temporarily change the mac address on my rooted LG VS450PP (it has Software version of VS450PP1).

The mac address for wlan is hardcoded in a file (make a note of the file's ownership and permission info)

/data/misc/wifi/WCNSS_qcom_wlan_nv.bin 

It will be obvious once you do a hexdump. I scp the file to a regular linux machine and used xxd to generate the hex dump in text, changed the mac address, and generated the new bin file. You just need to scp it back to the phone and make sure you have the right ownership/permission, disable/re-enable WiFi, and you should be good to go.

If you restart the phone, the change will be reverted. I haven't figured out how to permanently change the mac.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.